As suggested by Anders: back out 37112.
[obnox/wireshark/wip.git] / epan / strutil.c
1 /* strutil.c
2  * String utility routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <glib.h>
33 #include "strutil.h"
34 #include "emem.h"
35 #include <../isprint.h>
36
37
38 #ifdef _WIN32
39 #include <windows.h>
40 #include <tchar.h>
41 #include <wchar.h>
42 #endif
43
44 static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
45                               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
46
47 /*
48  * Given a pointer into a data buffer, and to the end of the buffer,
49  * find the end of the (putative) line at that position in the data
50  * buffer.
51  * Return a pointer to the EOL character(s) in "*eol".
52  */
53 const guchar *
54 find_line_end(const guchar *data, const guchar *dataend, const guchar **eol)
55 {
56   const guchar *lineend;
57
58   lineend = memchr(data, '\n', dataend - data);
59   if (lineend == NULL) {
60     /*
61      * No LF - line is probably continued in next TCP segment.
62      */
63     lineend = dataend;
64     *eol = dataend;
65   } else {
66     /*
67      * Is the LF at the beginning of the line?
68      */
69     if (lineend > data) {
70       /*
71        * No - is it preceded by a carriage return?
72        * (Perhaps it's supposed to be, but that's not guaranteed....)
73        */
74       if (*(lineend - 1) == '\r') {
75         /*
76          * Yes.  The EOL starts with the CR.
77          */
78         *eol = lineend - 1;
79       } else {
80         /*
81          * No.  The EOL starts with the LF.
82          */
83         *eol = lineend;
84
85         /*
86          * I seem to remember that we once saw lines ending with LF-CR
87          * in an HTTP request or response, so check if it's *followed*
88          * by a carriage return.
89          */
90         if (lineend < (dataend - 1) && *(lineend + 1) == '\r') {
91           /*
92            * It's <non-LF><LF><CR>; say it ends with the CR.
93            */
94           lineend++;
95         }
96       }
97     } else {
98       /*
99        * Yes - the EOL starts with the LF.
100        */
101       *eol = lineend;
102     }
103
104     /*
105      * Point to the character after the last character.
106      */
107     lineend++;
108   }
109   return lineend;
110 }
111
112 /*
113  * Get the length of the next token in a line, and the beginning of the
114  * next token after that (if any).
115  * Return 0 if there is no next token.
116  */
117 int
118 get_token_len(const guchar *linep, const guchar *lineend,
119               const guchar **next_token)
120 {
121   const guchar *tokenp;
122   int token_len;
123
124   tokenp = linep;
125
126   /*
127    * Search for a blank, a CR or an LF, or the end of the buffer.
128    */
129   while (linep < lineend && *linep != ' ' && *linep != '\r' && *linep != '\n')
130       linep++;
131   token_len = (int) (linep - tokenp);
132
133   /*
134    * Skip trailing blanks.
135    */
136   while (linep < lineend && *linep == ' ')
137     linep++;
138
139   *next_token = linep;
140
141   return token_len;
142 }
143
144
145 #define INITIAL_FMTBUF_SIZE     128
146
147 /*
148  * Given a string, generate a string from it that shows non-printable
149  * characters as C-style escapes, and return a pointer to it.
150  */
151 gchar *
152 format_text(const guchar *string, size_t len)
153 {
154   static gchar *fmtbuf[3];
155   static int fmtbuf_len[3];
156   static int idx;
157   int column;
158   const guchar *stringend = string + len;
159   guchar c;
160   int i;
161
162   idx = (idx + 1) % 3;
163
164   /*
165    * Allocate the buffer if it's not already allocated.
166    */
167   if (fmtbuf[idx] == NULL) {
168     fmtbuf[idx] = g_malloc(INITIAL_FMTBUF_SIZE);
169     fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
170   }
171   column = 0;
172   while (string < stringend) {
173     /*
174      * Is there enough room for this character, if it expands to
175      * a backslash plus 3 octal digits (which is the most it can
176      * expand to), and also enough room for a terminating '\0'?
177      */
178     if (column+3+1 >= fmtbuf_len[idx]) {
179       /*
180        * Double the buffer's size if it's not big enough.
181        * The size of the buffer starts at 128, so doubling its size
182        * adds at least another 128 bytes, which is more than enough
183        * for one more character plus a terminating '\0'.
184        */
185       fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
186       fmtbuf[idx] = g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
187     }
188     c = *string++;
189
190     if (g_unichar_isprint(c)) {
191       fmtbuf[idx][column] = c;
192       column++;
193     } else {
194       fmtbuf[idx][column] =  '\\';
195       column++;
196       switch (c) {
197
198       case '\a':
199         fmtbuf[idx][column] = 'a';
200         column++;
201         break;
202
203       case '\b':
204         fmtbuf[idx][column] = 'b'; /* BS */
205         column++;
206         break;
207
208       case '\f':
209         fmtbuf[idx][column] = 'f'; /* FF */
210         column++;
211         break;
212
213       case '\n':
214         fmtbuf[idx][column] = 'n'; /* NL */
215         column++;
216         break;
217
218       case '\r':
219         fmtbuf[idx][column] = 'r'; /* CR */
220         column++;
221         break;
222
223       case '\t':
224         fmtbuf[idx][column] = 't'; /* tab */
225         column++;
226         break;
227
228       case '\v':
229         fmtbuf[idx][column] = 'v';
230         column++;
231         break;
232
233       default:
234         i = (c>>6)&03;
235         fmtbuf[idx][column] = i + '0';
236         column++;
237         i = (c>>3)&07;
238         fmtbuf[idx][column] = i + '0';
239         column++;
240         i = (c>>0)&07;
241         fmtbuf[idx][column] = i + '0';
242         column++;
243         break;
244       }
245     }
246   }
247   fmtbuf[idx][column] = '\0';
248   return fmtbuf[idx];
249 }
250
251 /*
252  * Given a string, generate a string from it that shows non-printable
253  * characters as C-style escapes except a whitespace character
254  * (space, tab, carriage return, new line, vertical tab, or formfeed)
255  * which will be replaced by a space, and return a pointer to it.
256  */
257 gchar *
258 format_text_wsp(const guchar *string, size_t len)
259 {
260   static gchar *fmtbuf[3];
261   static int fmtbuf_len[3];
262   static int idx;
263   int column;
264   const guchar *stringend = string + len;
265   guchar c;
266   int i;
267
268   idx = (idx + 1) % 3;
269
270   /*
271    * Allocate the buffer if it's not already allocated.
272    */
273   if (fmtbuf[idx] == NULL) {
274     fmtbuf[idx] = g_malloc(INITIAL_FMTBUF_SIZE);
275     fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
276   }
277   column = 0;
278   while (string < stringend) {
279     /*
280      * Is there enough room for this character, if it expands to
281      * a backslash plus 3 octal digits (which is the most it can
282      * expand to), and also enough room for a terminating '\0'?
283      */
284     if (column+3+1 >= fmtbuf_len[idx]) {
285       /*
286        * Double the buffer's size if it's not big enough.
287        * The size of the buffer starts at 128, so doubling its size
288        * adds at least another 128 bytes, which is more than enough
289        * for one more character plus a terminating '\0'.
290        */
291       fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
292       fmtbuf[idx] = g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
293     }
294     c = *string++;
295
296     if (g_unichar_isprint(c)) {
297       fmtbuf[idx][column] = c;
298       column++;
299     } else if  (isspace(c)) {
300       fmtbuf[idx][column] = ' ';
301       column++;
302     } else {
303       fmtbuf[idx][column] =  '\\';
304       column++;
305       switch (c) {
306
307       case '\a':
308         fmtbuf[idx][column] = 'a';
309         column++;
310         break;
311
312       case '\b':
313         fmtbuf[idx][column] = 'b'; /* BS */
314         column++;
315         break;
316
317       case '\f':
318         fmtbuf[idx][column] = 'f'; /* FF */
319         column++;
320         break;
321
322       case '\n':
323         fmtbuf[idx][column] = 'n'; /* NL */
324         column++;
325         break;
326
327       case '\r':
328         fmtbuf[idx][column] = 'r'; /* CR */
329         column++;
330         break;
331
332       case '\t':
333         fmtbuf[idx][column] = 't'; /* tab */
334         column++;
335         break;
336
337       case '\v':
338         fmtbuf[idx][column] = 'v';
339         column++;
340         break;
341
342       default:
343         i = (c>>6)&03;
344         fmtbuf[idx][column] = i + '0';
345         column++;
346         i = (c>>3)&07;
347         fmtbuf[idx][column] = i + '0';
348         column++;
349         i = (c>>0)&07;
350         fmtbuf[idx][column] = i + '0';
351         column++;
352         break;
353       }
354     }
355   }
356   fmtbuf[idx][column] = '\0';
357   return fmtbuf[idx];
358 }
359
360 static gboolean
361 is_byte_sep(guint8 c)
362 {
363         return (c == '-' || c == ':' || c == '.');
364 }
365
366 /* Turn a string of hex digits with optional separators (defined by
367  * is_byte_sep() into a byte array.
368  */
369 gboolean
370 hex_str_to_bytes(const char *hex_str, GByteArray *bytes, gboolean force_separators) {
371         guint8          val;
372         const guchar    *p, *q, *r, *s, *punct;
373         char            four_digits_first_half[3];
374         char            four_digits_second_half[3];
375         char            two_digits[3];
376         char            one_digit[2];
377
378         if (! hex_str || ! bytes) {
379                 return FALSE;
380         }
381         g_byte_array_set_size(bytes, 0);
382         p = (const guchar *)hex_str;
383         while (*p) {
384                 q = p+1;
385                 r = p+2;
386                 s = p+3;
387
388                 if (*q && *r && *s
389                     && isxdigit(*p) && isxdigit(*q) &&
390                     isxdigit(*r) && isxdigit(*s)) {
391                         four_digits_first_half[0] = *p;
392                         four_digits_first_half[1] = *q;
393                         four_digits_first_half[2] = '\0';
394                         four_digits_second_half[0] = *r;
395                         four_digits_second_half[1] = *s;
396                         four_digits_second_half[2] = '\0';
397
398                         /*
399                          * Four or more hex digits in a row.
400                          */
401                         val = (guint8) strtoul(four_digits_first_half, NULL, 16);
402                         g_byte_array_append(bytes, &val, 1);
403                         val = (guint8) strtoul(four_digits_second_half, NULL, 16);
404                         g_byte_array_append(bytes, &val, 1);
405
406                         punct = s + 1;
407                         if (*punct) {
408                                 /*
409                                  * Make sure the character after
410                                  * the forth hex digit is a byte
411                                  * separator, i.e. that we don't have
412                                  * more than four hex digits, or a
413                                  * bogus character.
414                                  */
415                                 if (is_byte_sep(*punct)) {
416                                         p = punct + 1;
417                                         continue;
418                                 }
419                                 else if (force_separators) {
420                                         return FALSE;
421                                         break;
422                                 }
423                         }
424                         p = punct;
425                         continue;
426                 }
427
428                 else if (*q && isxdigit(*p) && isxdigit(*q)) {
429                         two_digits[0] = *p;
430                         two_digits[1] = *q;
431                         two_digits[2] = '\0';
432
433                         /*
434                          * Two hex digits in a row.
435                          */
436                         val = (guint8) strtoul(two_digits, NULL, 16);
437                         g_byte_array_append(bytes, &val, 1);
438                         punct = q + 1;
439                         if (*punct) {
440                                 /*
441                                  * Make sure the character after
442                                  * the second hex digit is a byte
443                                  * separator, i.e. that we don't have
444                                  * more than two hex digits, or a
445                                  * bogus character.
446                                  */
447                                 if (is_byte_sep(*punct)) {
448                                         p = punct + 1;
449                                         continue;
450                                 }
451                                 else if (force_separators) {
452                                         return FALSE;
453                                         break;
454                                 }
455                         }
456                         p = punct;
457                         continue;
458                 }
459                 else if (*q && isxdigit(*p) && is_byte_sep(*q)) {
460                         one_digit[0] = *p;
461                         one_digit[1] = '\0';
462
463                         /*
464                          * Only one hex digit (not at the end of the string)
465                          */
466                         val = (guint8) strtoul(one_digit, NULL, 16);
467                         g_byte_array_append(bytes, &val, 1);
468                         p = q + 1;
469                         continue;
470                 }
471                 else if (!*q && isxdigit(*p)) {
472                         one_digit[0] = *p;
473                         one_digit[1] = '\0';
474
475                         /*
476                          * Only one hex digit (at the end of the string)
477                          */
478                         val = (guint8) strtoul(one_digit, NULL, 16);
479                         g_byte_array_append(bytes, &val, 1);
480                         p = q;
481                         continue;
482                 }
483                 else {
484                         return FALSE;
485                 }
486         }
487         return TRUE;
488 }
489
490 /*
491  * Turn an RFC 3986 percent-encoded string into a byte array.
492  * XXX - We don't check for reserved characters.
493  */
494 #define HEX_DIGIT_BUF_LEN 3
495 gboolean
496 uri_str_to_bytes(const char *uri_str, GByteArray *bytes) {
497         guint8          val;
498         const guchar    *p;
499         guchar          hex_digit[HEX_DIGIT_BUF_LEN];
500
501         g_byte_array_set_size(bytes, 0);
502         if (! uri_str) {
503                 return FALSE;
504         }
505
506         p = (const guchar *)uri_str;
507
508         while (*p) {
509                 if (! isascii(*p) || ! isprint(*p))
510                         return FALSE;
511                 if (*p == '%') {
512                         p++;
513                         if (*p == '\0') return FALSE;
514                         hex_digit[0] = *p;
515                         p++;
516                         if (*p == '\0') return FALSE;
517                         hex_digit[1] = *p;
518                         hex_digit[2] = '\0';
519                         if (! isxdigit(hex_digit[0]) || ! isxdigit(hex_digit[1]))
520                                 return FALSE;
521                         val = (guint8) strtoul((char *)hex_digit, NULL, 16);
522                         g_byte_array_append(bytes, &val, 1);
523                 } else {
524                         g_byte_array_append(bytes, (guint8 *) p, 1);
525                 }
526                 p++;
527
528         }
529         return TRUE;
530 }
531
532 /*
533  * Given a GByteArray, generate a string from it that shows non-printable
534  * characters as percent-style escapes, and return a pointer to it.
535  */
536 gchar *
537 format_uri(const GByteArray *bytes, const gchar *reserved_chars)
538 {
539   static gchar *fmtbuf[3];
540   static guint fmtbuf_len[3];
541   static guint idx;
542   const guchar *reserved_def = ":/?#[]@!$&'()*+,;= ";
543   const guchar *reserved = reserved_def;
544   guint8 c;
545   guint column, i;
546   gboolean is_reserved = FALSE;
547
548   if (! bytes)
549     return "";
550
551   idx = (idx + 1) % 3;
552   if (reserved_chars)
553     reserved = reserved_chars;
554
555   /*
556    * Allocate the buffer if it's not already allocated.
557    */
558   if (fmtbuf[idx] == NULL) {
559     fmtbuf[idx] = g_malloc(INITIAL_FMTBUF_SIZE);
560     fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
561   }
562   for (column = 0; column < bytes->len; column++) {
563     /*
564      * Is there enough room for this character, if it expands to
565      * a percent plus 2 hex digits (which is the most it can
566      * expand to), and also enough room for a terminating '\0'?
567      */
568     if (column+2+1 >= fmtbuf_len[idx]) {
569       /*
570        * Double the buffer's size if it's not big enough.
571        * The size of the buffer starts at 128, so doubling its size
572        * adds at least another 128 bytes, which is more than enough
573        * for one more character plus a terminating '\0'.
574        */
575       fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
576       fmtbuf[idx] = g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
577     }
578     c = bytes->data[column];
579
580     if (!isascii(c) || !isprint(c) || c == '%') {
581       is_reserved = TRUE;
582     }
583
584     for (i = 0; i < strlen(reserved); i++) {
585       if (c == reserved[i])
586         is_reserved = TRUE;
587     }
588
589     if (!is_reserved) {
590       fmtbuf[idx][column] = c;
591     } else {
592       fmtbuf[idx][column] = '%';
593       column++;
594       fmtbuf[idx][column] = hex[c >> 4];
595       column++;
596       fmtbuf[idx][column] = hex[c & 0xF];
597     }
598   }
599   fmtbuf[idx][column] = '\0';
600   return fmtbuf[idx];
601 }
602
603 /**
604  * Create a copy of a GByteArray
605  *
606  * @param ba The byte array to be copied.
607  * @return If ba exists, a freshly allocated copy.  NULL otherwise.
608  *
609  */
610 GByteArray *
611 byte_array_dup(GByteArray *ba) {
612     GByteArray *new_ba;
613
614     if (!ba)
615         return NULL;
616
617     new_ba = g_byte_array_new();
618     g_byte_array_append(new_ba, ba->data, ba->len);
619     return new_ba;
620 }
621
622 #define SUBID_BUF_LEN 5
623 gboolean
624 oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
625   guint32 subid0, subid, sicnt, i;
626   const char *p, *dot;
627   guint8 buf[SUBID_BUF_LEN];
628
629   g_byte_array_set_size(bytes, 0);
630
631   /* check syntax */
632   p = oid_str;
633   dot = NULL;
634   while (*p) {
635     if (!isdigit((guchar)*p) && (*p != '.')) return FALSE;
636     if (*p == '.') {
637       if (p == oid_str) return FALSE;
638       if (!*(p+1)) return FALSE;
639       if ((p-1) == dot) return FALSE;
640       dot = p;
641     }
642     p++;
643   }
644   if (!dot) return FALSE;
645
646   p = oid_str;
647   sicnt = 0;
648   subid0 = 0;   /* squelch GCC complaints */
649   while (*p) {
650     subid = 0;
651     while (isdigit((guchar)*p)) {
652       subid *= 10;
653       subid += *p - '0';
654       p++;
655     }
656     if (sicnt == 0) {
657       subid0 = subid;
658       if (subid0 > 2) return FALSE;
659     } else if (sicnt == 1) {
660       if ((subid0 < 2) && (subid > 39)) return FALSE;
661       subid += 40 * subid0;
662     }
663     if (sicnt) {
664       i = SUBID_BUF_LEN;
665       do {
666         i--;
667         buf[i] = 0x80 | (subid % 0x80);
668         subid >>= 7;
669       } while (subid && i);
670       buf[SUBID_BUF_LEN-1] &= 0x7F;
671       g_byte_array_append(bytes, buf + i, SUBID_BUF_LEN - i);
672     }
673     sicnt++;
674     if (*p) p++;
675   }
676
677   return TRUE;
678 }
679
680 /**
681  * Compare the contents of two GByteArrays
682  *
683  * @param ba1 A byte array
684  * @param ba2 A byte array
685  * @return If both arrays are non-NULL and their lengths are equal and
686  *         their contents are equal, returns TRUE.  Otherwise, returns
687  *         FALSE.
688  *
689  * XXX - Should this be in strutil.c?
690  */
691 gboolean
692 byte_array_equal(GByteArray *ba1, GByteArray *ba2) {
693     if (!ba1 || !ba2)
694         return FALSE;
695
696     if (ba1->len != ba2->len)
697         return FALSE;
698
699     if (memcmp(ba1->data, ba2->data, ba1->len) != 0)
700         return FALSE;
701
702     return TRUE;
703 }
704
705
706 /* Return a XML escaped representation of the unescaped string.
707  * The returned string must be freed when no longer in use. */
708 gchar *
709 xml_escape(const gchar *unescaped)
710 {
711         GString *buffer = g_string_sized_new(128);
712         const gchar *p;
713         gchar c;
714
715         p = unescaped;
716         while ( (c = *p++) ) {
717                 switch (c) {
718                         case '<':
719                                 g_string_append(buffer, "&lt;");
720                                 break;
721                         case '>':
722                                 g_string_append(buffer, "&gt;");
723                                 break;
724                         case '&':
725                                 g_string_append(buffer, "&amp;");
726                                 break;
727                         case '\'':
728                                 g_string_append(buffer, "&apos;");
729                                 break;
730                         case '"':
731                                 g_string_append(buffer, "&quot;");
732                                 break;
733                         default:
734                                 g_string_append_c(buffer, c);
735                                 break;
736                 }
737         }
738         /* Return the string value contained within the GString
739          * after getting rid of the GString structure.
740          * This is the way to do this, see the GLib reference. */
741         return g_string_free(buffer, FALSE);
742 }
743
744
745 /* Return the first occurrence of needle in haystack.
746  * If not found, return NULL.
747  * If either haystack or needle has 0 length, return NULL.
748  * Algorithm copied from GNU's glibc 2.3.2 memcmp() */
749 const guint8 *
750 epan_memmem(const guint8 *haystack, guint haystack_len,
751                 const guint8 *needle, guint needle_len)
752 {
753         const guint8 *begin;
754         const guint8 *const last_possible
755                 = haystack + haystack_len - needle_len;
756
757         if (needle_len == 0) {
758                 return NULL;
759         }
760
761         if (needle_len > haystack_len) {
762                 return NULL;
763         }
764
765         for (begin = haystack ; begin <= last_possible; ++begin) {
766                 if (begin[0] == needle[0] &&
767                         !memcmp(&begin[1], needle + 1,
768                                 needle_len - 1)) {
769                         return begin;
770                 }
771         }
772
773         return NULL;
774 }
775
776 /*
777  * Scan the search string to make sure it's valid hex.  Return the
778  * number of bytes in nbytes.
779  */
780 guint8 *
781 convert_string_to_hex(const char *string, size_t *nbytes)
782 {
783   size_t n_bytes;
784   const char *p;
785   guchar c;
786   guint8 *bytes, *q, byte_val;
787
788   n_bytes = 0;
789   p = &string[0];
790   for (;;) {
791     c = *p++;
792     if (c == '\0')
793       break;
794     if (isspace(c))
795       continue; /* allow white space */
796     if (c==':' || c=='.' || c=='-')
797       continue; /* skip any ':', '.', or '-' between bytes */
798     if (!isxdigit(c)) {
799       /* Not a valid hex digit - fail */
800       return NULL;
801     }
802
803     /*
804      * We can only match bytes, not nibbles; we must have a valid
805      * hex digit immediately after that hex digit.
806      */
807     c = *p++;
808     if (!isxdigit(c))
809       return NULL;
810
811     /* 2 hex digits = 1 byte */
812     n_bytes++;
813   }
814
815   /*
816    * Were we given any hex digits?
817    */
818   if (n_bytes == 0) {
819       /* No. */
820       return NULL;
821   }
822
823   /*
824    * OK, it's valid, and it generates "n_bytes" bytes; generate the
825    * raw byte array.
826    */
827   bytes = g_malloc(n_bytes);
828   p = &string[0];
829   q = &bytes[0];
830   for (;;) {
831     c = *p++;
832     if (c == '\0')
833       break;
834     if (isspace(c))
835       continue; /* allow white space */
836     if (c==':' || c=='.' || c=='-')
837       continue; /* skip any ':', '.', or '-' between bytes */
838     /* From the loop above, we know this is a hex digit */
839     if (isdigit(c))
840       byte_val = c - '0';
841     else if (c >= 'a')
842       byte_val = (c - 'a') + 10;
843     else
844       byte_val = (c - 'A') + 10;
845     byte_val <<= 4;
846
847     /* We also know this is a hex digit */
848     c = *p++;
849     if (isdigit(c))
850       byte_val |= c - '0';
851     else if (c >= 'a')
852       byte_val |= (c - 'a') + 10;
853     else if (c >= 'A')
854       byte_val |= (c - 'A') + 10;
855
856     *q++ = byte_val;
857   }
858   *nbytes = n_bytes;
859   return bytes;
860 }
861
862 /*
863  * Copy if if it's a case-sensitive search; uppercase it if it's
864  * a case-insensitive search.
865  */
866 char *
867 convert_string_case(const char *string, gboolean case_insensitive)
868 {
869
870   if (case_insensitive) {
871     return g_utf8_strup(string, -1);
872   } else {
873     return g_strdup(string);
874   }
875 }
876
877 char *
878 epan_strcasestr(const char *haystack, const char *needle)
879 {
880         gsize hlen = strlen(haystack);
881         gsize nlen = strlen(needle);
882
883         while (hlen-- >= nlen) {
884                 if (!g_ascii_strncasecmp(haystack, needle, nlen))
885                         return (char*) haystack;
886                 haystack++;
887         }
888         return NULL;
889 }
890
891 const char *
892 string_or_null(const char *string)
893 {
894   if (string)
895     return string;
896   return "[NULL]";
897 }
898
899 int
900 escape_string_len(const char *string)
901 {
902         const char *p;
903         gchar c;
904         int repr_len;
905
906         repr_len = 0;
907         for (p = string; (c = *p) != '\0'; p++) {
908                 /* Backslashes and double-quotes must
909                  * be escaped */
910                 if (c == '\\' || c == '"') {
911                         repr_len += 2;
912                 }
913                 /* Values that can't nicely be represented
914                  * in ASCII need to be escaped. */
915                 else if (!isprint((unsigned char)c)) {
916                         /* c --> \xNN */
917                         repr_len += 4;
918                 }
919                 /* Other characters are just passed through. */
920                 else {
921                         repr_len++;
922                 }
923         }
924         return repr_len + 2;    /* string plus leading and trailing quotes */
925 }
926
927 char *
928 escape_string(char *buf, const char *string)
929 {
930   const gchar *p;
931   gchar c;
932   char *bufp;
933   char hexbuf[3];
934
935   bufp = buf;
936   *bufp++ = '"';
937   for (p = string; (c = *p) != '\0'; p++) {
938         /* Backslashes and double-quotes must
939          * be escaped. */
940         if (c == '\\' || c == '"') {
941                 *bufp++ = '\\';
942                 *bufp++ = c;
943         }
944         /* Values that can't nicely be represented
945          * in ASCII need to be escaped. */
946         else if (!isprint((unsigned char)c)) {
947                 /* c --> \xNN */
948                 g_snprintf(hexbuf,sizeof(hexbuf), "%02x", (unsigned char) c);
949                 *bufp++ = '\\';
950                 *bufp++ = 'x';
951                 *bufp++ = hexbuf[0];
952                 *bufp++ = hexbuf[1];
953         }
954         /* Other characters are just passed through. */
955         else {
956                 *bufp++ = c;
957         }
958   }
959   *bufp++ = '"';
960   *bufp = '\0';
961   return buf;
962 }
963
964 #define GN_CHAR_ALPHABET_SIZE 128
965
966 static gunichar IA5_default_alphabet[GN_CHAR_ALPHABET_SIZE] = {
967
968     /*ITU-T recommendation T.50 specifies International Reference Alphabet 5 (IA5) */
969
970     '?', '?', '?', '?', '?', '?', '?', '?',
971     '?', '?', '?', '?', '?', '?', '?', '?',
972     '?', '?', '?', '?', '?', '?', '?', '?',
973     '?', '?', '?', '?', '?', '?', '?', '?',
974     ' ', '!', '\"','#', '$', '%', '&', '\'',
975     '(', ')', '*', '+', ',', '-', '.', '/',
976     '0', '1', '2', '3', '4', '5', '6', '7',
977     '8', '9', ':', ';', '<', '=', '>', '?',
978     '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
979     'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
980     'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
981     'X',  'Y',  'Z',  '[',  '\\',  ']',  '^',  '_',
982     '`', 'a',  'b',  'c',  'd',  'e',  'f',  'g',
983     'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
984     'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
985     'x',  'y',  'z',  '{',  '|',  '}',  '~',  '?'
986 };
987
988 static gunichar
989 char_def_ia5_alphabet_decode(unsigned char value)
990 {
991     if (value < GN_CHAR_ALPHABET_SIZE)
992     {
993                 return IA5_default_alphabet[value];
994     }
995     else
996     {
997                 return '?';
998     }
999 }
1000
1001 void
1002 IA5_7BIT_decode(unsigned char * dest, const unsigned char* src, int len)
1003 {
1004     int i, j;
1005     gunichar buf;
1006
1007
1008     for (i = 0, j = 0; j < len;  j++)
1009     {
1010             buf = char_def_ia5_alphabet_decode(src[j]);
1011             i += g_unichar_to_utf8(buf,&(dest[i]));
1012     }
1013     dest[i]=0;
1014     return;
1015 }
1016
1017 /*
1018  * This function takes a string and copies it, inserting a 'chr' before
1019  * every 'chr' in it.
1020  */
1021 gchar*
1022 ws_strdup_escape_char (const gchar *str, const gchar chr)
1023 {
1024         gchar *p, *q, *new_str;
1025
1026         if(!str)
1027                 return NULL;
1028
1029         p = (gchar *)str;
1030         /* Worst case: A string that is full of 'chr' */
1031         q = new_str = g_malloc (strlen(str) * 2 + 1);
1032
1033         while(*p != 0)
1034         {
1035                 if(*p == chr)
1036                         *q++ = chr;
1037
1038                 *q++ = *p++;
1039         }
1040         *q = '\0';
1041
1042         return new_str;
1043 }
1044
1045 /*
1046  * This function takes a string and copies it, removing any occurences of double
1047  * 'chr' with a single 'chr'.
1048  */
1049 gchar*
1050 ws_strdup_unescape_char (const gchar *str, const char chr)
1051 {
1052         gchar *p, *q, *new_str;
1053
1054         if(!str)
1055                 return NULL;
1056
1057         p = (gchar *)str;
1058         /* Worst case: A string that contains no 'chr' */
1059         q = new_str = g_malloc (strlen(str) + 1);
1060
1061         while(*p != 0)
1062         {
1063                 *q++ = *p;
1064                 if ((*p == chr) && (*(p+1) == chr))
1065                         p += 2;
1066                 else
1067                         p++;
1068         }
1069         *q = '\0';
1070
1071         return new_str;
1072 }
1073
1074 /* Create a newly-allocated string with replacement values. */
1075 gchar *string_replace(const gchar* str, const gchar *old_val, const gchar *new_val) {
1076         gchar **str_parts;
1077         gchar *new_str;
1078
1079         if (!str || !old_val) {
1080                 return NULL;
1081         }
1082
1083         str_parts = g_strsplit(str, old_val, 0);
1084         new_str = g_strjoinv(new_val, str_parts);
1085         g_strfreev(str_parts);
1086
1087         return new_str;
1088 }