2 * String utility routines
4 * $Id: strutil.c,v 1.6 2000/11/13 07:19:32 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 * Given a pointer into a data buffer, and to the end of the buffer,
39 * find the end of the (putative) line at that position in the data
41 * Return a pointer to the EOL character(s) in "*eol".
44 find_line_end(const u_char *data, const u_char *dataend, const u_char **eol)
46 const u_char *lineend;
48 lineend = memchr(data, '\n', dataend - data);
49 if (lineend == NULL) {
51 * No LF - line is probably continued in next TCP segment.
57 * Is the LF at the beginning of the line?
61 * No - is it preceded by a carriage return?
62 * (Perhaps it's supposed to be, but that's not guaranteed....)
64 if (*(lineend - 1) == '\r') {
66 * Yes. The EOL starts with the CR.
71 * No. The EOL starts with the LF.
76 * I seem to remember that we once saw lines ending with LF-CR
77 * in an HTTP request or response, so check if it's *followed*
78 * by a carriage return.
80 if (lineend < (dataend - 1) && *(lineend + 1) == '\r') {
82 * It's <non-LF><LF><CR>; say it ends with the CR.
89 * Yes - the EOL starts with the LF.
95 * Point to the character after the last character.
103 * Get the length of the next token in a line, and the beginning of the
104 * next token after that (if any).
105 * Return 0 if there is no next token.
108 get_token_len(const u_char *linep, const u_char *lineend,
109 const u_char **next_token)
111 const u_char *tokenp;
117 * Search for a blank, a CR or an LF, or the end of the buffer.
119 while (linep < lineend && *linep != ' ' && *linep != '\r' && *linep != '\n')
121 token_len = linep - tokenp;
124 * Skip trailing blanks.
126 while (linep < lineend && *linep == ' ')
135 #define INITIAL_FMTBUF_SIZE 128
138 * Given a string, generate a string from it that shows non-printable
139 * characters as C-style escapes, and return a pointer to it.
142 format_text(const u_char *string, int len)
144 static gchar *fmtbuf;
145 static int fmtbuf_len;
147 const u_char *stringend = string + len;
152 * Allocate the buffer if it's not already allocated.
154 if (fmtbuf == NULL) {
155 fmtbuf = g_malloc(INITIAL_FMTBUF_SIZE);
156 fmtbuf_len = INITIAL_FMTBUF_SIZE;
159 while (string < stringend) {
161 * Is there enough room for this character, if it expands to
162 * a backslash plus 3 octal digits (which is the most it can
163 * expand to), and also enough room for a terminating '\0'?
165 if (column+3+1 >= fmtbuf_len) {
167 * Double the buffer's size if it's not big enough.
168 * The size of the buffer starts at 128, so doubling its size
169 * adds at least another 128 bytes, which is more than enough
170 * for one more character plus a terminating '\0'.
172 fmtbuf_len = fmtbuf_len * 2;
173 fmtbuf = g_realloc(fmtbuf, fmtbuf_len);
180 fmtbuf[column] = '\\';
185 fmtbuf[column] = '\\';
190 fmtbuf[column] = 'a';
195 fmtbuf[column] = 'b';
200 fmtbuf[column] = 'f';
205 fmtbuf[column] = 'n';
210 fmtbuf[column] = 'r';
215 fmtbuf[column] = 't';
220 fmtbuf[column] = 'v';
226 fmtbuf[column] = i + '0';
229 fmtbuf[column] = i + '0';
232 fmtbuf[column] = i + '0';
238 fmtbuf[column] = '\0';
242 /* Max string length for displaying byte string. */
243 #define MAX_BYTE_STR_LEN 32
245 /* Turn an array of bytes into a string showing the bytes in hex. */
246 #define N_BYTES_TO_STR_STRINGS 6
248 bytes_to_str(const guint8 *bd, int bd_len) {
249 static gchar str[N_BYTES_TO_STR_STRINGS][MAX_BYTE_STR_LEN+3+1];
254 static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
255 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
258 if (cur_idx >= N_BYTES_TO_STR_STRINGS)
260 cur = &str[cur_idx][0];
262 len = MAX_BYTE_STR_LEN;
263 while (bd_len > 0 && len > 0) {
264 *p++ = hex[(*bd) >> 4];
265 *p++ = hex[(*bd) & 0xF];
271 /* Note that we're not showing the full string. */