2 * String utility routines
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include <wsutil/str_util.h>
31 #include <epan/proto.h>
39 static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
40 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
43 * Given a pointer into a data buffer, and to the end of the buffer,
44 * find the end of the (putative) line at that position in the data
46 * Return a pointer to the EOL character(s) in "*eol".
49 find_line_end(const guchar *data, const guchar *dataend, const guchar **eol)
51 const guchar *lineend;
53 lineend = (guchar *)memchr(data, '\n', dataend - data);
54 if (lineend == NULL) {
56 * No LF - line is probably continued in next TCP segment.
62 * Is the LF at the beginning of the line?
66 * No - is it preceded by a carriage return?
67 * (Perhaps it's supposed to be, but that's not guaranteed....)
69 if (*(lineend - 1) == '\r') {
71 * Yes. The EOL starts with the CR.
76 * No. The EOL starts with the LF.
81 * I seem to remember that we once saw lines ending with LF-CR
82 * in an HTTP request or response, so check if it's *followed*
83 * by a carriage return.
85 if (lineend < (dataend - 1) && *(lineend + 1) == '\r') {
87 * It's <non-LF><LF><CR>; say it ends with the CR.
94 * Yes - the EOL starts with the LF.
100 * Point to the character after the last character.
108 * Get the length of the next token in a line, and the beginning of the
109 * next token after that (if any).
110 * Return 0 if there is no next token.
113 get_token_len(const guchar *linep, const guchar *lineend,
114 const guchar **next_token)
116 const guchar *tokenp;
122 * Search for a blank, a CR or an LF, or the end of the buffer.
124 while (linep < lineend && *linep != ' ' && *linep != '\r' && *linep != '\n')
126 token_len = (int) (linep - tokenp);
129 * Skip trailing blanks.
131 while (linep < lineend && *linep == ' ')
140 #define INITIAL_FMTBUF_SIZE 128
143 * Given a string, generate a string from it that shows non-printable
144 * characters as C-style escapes, and return a pointer to it.
147 format_text(const guchar *string, size_t len)
149 static gchar *fmtbuf[3];
150 static int fmtbuf_len[3];
153 const guchar *stringend = string + len;
160 * Allocate the buffer if it's not already allocated.
162 if (fmtbuf[idx] == NULL) {
163 fmtbuf[idx] = (gchar *)g_malloc(INITIAL_FMTBUF_SIZE);
164 fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
167 while (string < stringend) {
169 * Is there enough room for this character, if it expands to
170 * a backslash plus 3 octal digits (which is the most it can
171 * expand to), and also enough room for a terminating '\0'?
173 if (column+3+1 >= fmtbuf_len[idx]) {
175 * Double the buffer's size if it's not big enough.
176 * The size of the buffer starts at 128, so doubling its size
177 * adds at least another 128 bytes, which is more than enough
178 * for one more character plus a terminating '\0'.
180 fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
181 fmtbuf[idx] = (gchar *)g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
185 if (g_ascii_isprint(c)) {
186 fmtbuf[idx][column] = c;
189 fmtbuf[idx][column] = '\\';
194 fmtbuf[idx][column] = 'a';
199 fmtbuf[idx][column] = 'b'; /* BS */
204 fmtbuf[idx][column] = 'f'; /* FF */
209 fmtbuf[idx][column] = 'n'; /* NL */
214 fmtbuf[idx][column] = 'r'; /* CR */
219 fmtbuf[idx][column] = 't'; /* tab */
224 fmtbuf[idx][column] = 'v';
230 fmtbuf[idx][column] = i + '0';
233 fmtbuf[idx][column] = i + '0';
236 fmtbuf[idx][column] = i + '0';
242 fmtbuf[idx][column] = '\0';
247 * Given a string, generate a string from it that shows non-printable
248 * characters as C-style escapes except a whitespace character
249 * (space, tab, carriage return, new line, vertical tab, or formfeed)
250 * which will be replaced by a space, and return a pointer to it.
253 format_text_wsp(const guchar *string, size_t len)
255 static gchar *fmtbuf[3];
256 static int fmtbuf_len[3];
259 const guchar *stringend = string + len;
266 * Allocate the buffer if it's not already allocated.
268 if (fmtbuf[idx] == NULL) {
269 fmtbuf[idx] = (gchar *)g_malloc(INITIAL_FMTBUF_SIZE);
270 fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
273 while (string < stringend) {
275 * Is there enough room for this character, if it expands to
276 * a backslash plus 3 octal digits (which is the most it can
277 * expand to), and also enough room for a terminating '\0'?
279 if (column+3+1 >= fmtbuf_len[idx]) {
281 * Double the buffer's size if it's not big enough.
282 * The size of the buffer starts at 128, so doubling its size
283 * adds at least another 128 bytes, which is more than enough
284 * for one more character plus a terminating '\0'.
286 fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
287 fmtbuf[idx] = (gchar *)g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
291 if (g_ascii_isprint(c)) {
292 fmtbuf[idx][column] = c;
294 } else if (g_ascii_isspace(c)) {
295 fmtbuf[idx][column] = ' ';
298 fmtbuf[idx][column] = '\\';
303 fmtbuf[idx][column] = 'a';
308 fmtbuf[idx][column] = 'b'; /* BS */
313 fmtbuf[idx][column] = 'f'; /* FF */
318 fmtbuf[idx][column] = 'n'; /* NL */
323 fmtbuf[idx][column] = 'r'; /* CR */
328 fmtbuf[idx][column] = 't'; /* tab */
333 fmtbuf[idx][column] = 'v';
339 fmtbuf[idx][column] = i + '0';
342 fmtbuf[idx][column] = i + '0';
345 fmtbuf[idx][column] = i + '0';
351 fmtbuf[idx][column] = '\0';
356 * Given a string, generate a string from it that shows non-printable
357 * characters as the chr parameter passed, except a whitespace character
358 * (space, tab, carriage return, new line, vertical tab, or formfeed)
359 * which will be replaced by a space, and return a pointer to it.
362 format_text_chr(const guchar *string, const size_t len, const guchar chr)
364 static gchar *fmtbuf[3];
365 static int fmtbuf_len[3];
368 const guchar *stringend = string + len;
374 * Allocate the buffer if it's not already allocated.
376 if (fmtbuf[idx] == NULL) {
377 fmtbuf[idx] = (gchar *)g_malloc(INITIAL_FMTBUF_SIZE);
378 fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
381 while (string < stringend)
384 * Is there enough room for this character,
385 * and also enough room for a terminating '\0'?
387 if (column+1 >= fmtbuf_len[idx])
390 * Double the buffer's size if it's not big enough.
391 * The size of the buffer starts at 128, so doubling its size
392 * adds at least another 128 bytes, which is more than enough
393 * for one more character plus a terminating '\0'.
395 fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
396 fmtbuf[idx] = (gchar *)g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
400 if (g_ascii_isprint(c))
402 fmtbuf[idx][column] = c;
405 else if (g_ascii_isspace(c))
407 fmtbuf[idx][column] = ' ';
412 fmtbuf[idx][column] = chr;
416 fmtbuf[idx][column] = '\0';
421 is_byte_sep(guint8 c)
423 return (c == '-' || c == ':' || c == '.');
426 /* Turn a string of hex digits with optional separators (defined by
427 * is_byte_sep() into a byte array.
430 hex_str_to_bytes(const char *hex_str, GByteArray *bytes, gboolean force_separators)
433 const gchar *p, *q, *r, *s, *punct;
434 char four_digits_first_half[3];
435 char four_digits_second_half[3];
439 if (! hex_str || ! bytes) {
442 g_byte_array_set_size(bytes, 0);
450 && g_ascii_isxdigit(*p) && g_ascii_isxdigit(*q) &&
451 g_ascii_isxdigit(*r) && g_ascii_isxdigit(*s)) {
452 four_digits_first_half[0] = *p;
453 four_digits_first_half[1] = *q;
454 four_digits_first_half[2] = '\0';
455 four_digits_second_half[0] = *r;
456 four_digits_second_half[1] = *s;
457 four_digits_second_half[2] = '\0';
460 * Four or more hex digits in a row.
462 val = (guint8) strtoul(four_digits_first_half, NULL, 16);
463 g_byte_array_append(bytes, &val, 1);
464 val = (guint8) strtoul(four_digits_second_half, NULL, 16);
465 g_byte_array_append(bytes, &val, 1);
470 * Make sure the character after
471 * the forth hex digit is a byte
472 * separator, i.e. that we don't have
473 * more than four hex digits, or a
476 if (is_byte_sep(*punct)) {
480 else if (force_separators) {
487 else if (*q && g_ascii_isxdigit(*p) && g_ascii_isxdigit(*q)) {
490 two_digits[2] = '\0';
493 * Two hex digits in a row.
495 val = (guint8) strtoul(two_digits, NULL, 16);
496 g_byte_array_append(bytes, &val, 1);
500 * Make sure the character after
501 * the second hex digit is a byte
502 * separator, i.e. that we don't have
503 * more than two hex digits, or a
506 if (is_byte_sep(*punct)) {
510 else if (force_separators) {
517 else if (*q && g_ascii_isxdigit(*p) && is_byte_sep(*q)) {
522 * Only one hex digit (not at the end of the string)
524 val = (guint8) strtoul(one_digit, NULL, 16);
525 g_byte_array_append(bytes, &val, 1);
529 else if (!*q && g_ascii_isxdigit(*p)) {
534 * Only one hex digit (at the end of the string)
536 val = (guint8) strtoul(one_digit, NULL, 16);
537 g_byte_array_append(bytes, &val, 1);
549 get_valid_byte_sep(gchar c, const guint encoding)
551 gchar retval = -1; /* -1 means failure */
555 if (encoding & ENC_SEP_COLON)
559 if (encoding & ENC_SEP_DASH)
563 if (encoding & ENC_SEP_DOT)
567 if (encoding & ENC_SEP_SPACE)
571 /* we were given the end of the string, so it's fine */
575 if (g_ascii_isxdigit(c) && (encoding & ENC_SEP_NONE))
577 /* anything else means we've got a failure */
584 /* Turn a string of hex digits with optional separators (defined by is_byte_sep())
585 * into a byte array. Unlike hex_str_to_bytes(), this will read as many hex-char
586 * pairs as possible and not error if it hits a non-hex-char; instead it just ends
587 * there. (i.e., like strtol()/atoi()/etc.) Unless fail_if_partial is TRUE.
589 * The **endptr, if not NULL, is set to the char after the last hex character.
592 hex_str_to_bytes_encoding(const gchar *hex_str, GByteArray *bytes, const gchar **endptr,
593 const guint encoding, const gboolean fail_if_partial)
597 const gchar *end = hex_str;
598 gboolean retval = FALSE;
601 /* a map from ASCII hex chars to their value */
602 static const gint8 str_to_nibble[256] = {
603 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
604 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
605 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
606 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
607 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
608 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
609 -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
610 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
611 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
612 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
613 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
614 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
615 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
616 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
617 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
618 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
621 /* we must see two hex chars at the beginning, or fail */
622 if (bytes && *end && g_ascii_isxdigit(*end) && g_ascii_isxdigit(*(end+1))) {
625 /* set the separator character we'll allow; if this returns a -1, it means something's
626 * invalid after the hex, but we'll let the while-loop grab the first hex-pair anyway
628 sep = get_valid_byte_sep(*(end+2), encoding);
631 c = str_to_nibble[(guchar)*end];
633 if (fail_if_partial) retval = FALSE;
638 d = str_to_nibble[(guchar)*end];
640 if (fail_if_partial) retval = FALSE;
643 val = ((guint8)c * 16) + d;
644 g_byte_array_append(bytes, &val, 1);
647 /* check for separator and peek at next char to make sure we should keep going */
648 if (sep > 0 && *end == sep && str_to_nibble[(guchar)*(end+1)] > -1) {
649 /* yes, it's the right sep and followed by more hex, so skip the sep */
651 } else if (sep != 0 && *end) {
652 /* we either need a separator, but we don't see one; or the get_valid_byte_sep()
653 earlier didn't find a valid one to begin with */
654 if (fail_if_partial) retval = FALSE;
657 /* otherwise, either no separator allowed, or *end is null, or *end is an invalid
658 * sep, or *end is a valid sep but after it is not a hex char - in all those
659 * cases, just loop back up and let it fail later naturally.
665 if (bytes) g_byte_array_set_size(bytes, 0);
669 if (endptr) *endptr = end;
675 * Turn an RFC 3986 percent-encoded string into a byte array.
676 * XXX - We don't check for reserved characters.
678 #define HEX_DIGIT_BUF_LEN 3
680 uri_str_to_bytes(const char *uri_str, GByteArray *bytes)
684 gchar hex_digit[HEX_DIGIT_BUF_LEN];
686 g_byte_array_set_size(bytes, 0);
694 if (!g_ascii_isprint(*p))
698 if (*p == '\0') return FALSE;
701 if (*p == '\0') return FALSE;
704 if (! g_ascii_isxdigit(hex_digit[0]) || ! g_ascii_isxdigit(hex_digit[1]))
706 val = (guint8) strtoul(hex_digit, NULL, 16);
707 g_byte_array_append(bytes, &val, 1);
709 g_byte_array_append(bytes, (const guint8 *) p, 1);
718 * Given a GByteArray, generate a string from it that shows non-printable
719 * characters as percent-style escapes, and return a pointer to it.
722 format_uri(const GByteArray *bytes, const gchar *reserved_chars)
724 static gchar *fmtbuf[3];
725 static guint fmtbuf_len[3];
727 static const guchar *reserved_def = ":/?#[]@!$&'()*+,;= ";
728 const guchar *reserved = reserved_def;
731 gboolean is_reserved = FALSE;
738 reserved = reserved_chars;
741 * Allocate the buffer if it's not already allocated.
743 if (fmtbuf[idx] == NULL) {
744 fmtbuf[idx] = (gchar *)g_malloc(INITIAL_FMTBUF_SIZE);
745 fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
747 for (column = 0; column < bytes->len; column++) {
749 * Is there enough room for this character, if it expands to
750 * a percent plus 2 hex digits (which is the most it can
751 * expand to), and also enough room for a terminating '\0'?
753 if (column+2+1 >= fmtbuf_len[idx]) {
755 * Double the buffer's size if it's not big enough.
756 * The size of the buffer starts at 128, so doubling its size
757 * adds at least another 128 bytes, which is more than enough
758 * for one more character plus a terminating '\0'.
760 fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
761 fmtbuf[idx] = (gchar *)g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
763 c = bytes->data[column];
765 if (!g_ascii_isprint(c) || c == '%') {
769 for (i = 0; reserved[i]; i++) {
770 if (c == reserved[i])
775 fmtbuf[idx][column] = c;
777 fmtbuf[idx][column] = '%';
779 fmtbuf[idx][column] = hex[c >> 4];
781 fmtbuf[idx][column] = hex[c & 0xF];
784 fmtbuf[idx][column] = '\0';
789 * Create a copy of a GByteArray
791 * @param ba The byte array to be copied.
792 * @return If ba exists, a freshly allocated copy. NULL otherwise.
796 byte_array_dup(const GByteArray *ba)
803 new_ba = g_byte_array_new();
804 g_byte_array_append(new_ba, ba->data, ba->len);
808 #define SUBID_BUF_LEN 5
810 oid_str_to_bytes(const char *oid_str, GByteArray *bytes)
812 return rel_oid_str_to_bytes(oid_str, bytes, TRUE);
815 rel_oid_str_to_bytes(const char *oid_str, GByteArray *bytes, gboolean is_absolute)
817 guint32 subid0, subid, sicnt, i;
819 guint8 buf[SUBID_BUF_LEN];
821 g_byte_array_set_size(bytes, 0);
827 if (!g_ascii_isdigit(*p) && (*p != '.')) return FALSE;
829 if (p == oid_str && is_absolute) return FALSE;
830 if (!*(p+1)) return FALSE;
831 if ((p-1) == dot) return FALSE;
836 if (!dot) return FALSE;
839 sicnt = is_absolute ? 0 : 2;
840 if (!is_absolute) p++;
841 subid0 = 0; /* squelch GCC complaints */
844 while (g_ascii_isdigit(*p)) {
851 if (subid0 > 2) return FALSE;
852 } else if (sicnt == 1) {
853 if ((subid0 < 2) && (subid > 39)) return FALSE;
854 subid += 40 * subid0;
860 buf[i] = 0x80 | (subid % 0x80);
862 } while (subid && i);
863 buf[SUBID_BUF_LEN-1] &= 0x7F;
864 g_byte_array_append(bytes, buf + i, SUBID_BUF_LEN - i);
874 * Compare the contents of two GByteArrays
876 * @param ba1 A byte array
877 * @param ba2 A byte array
878 * @return If both arrays are non-NULL and their lengths are equal and
879 * their contents are equal, returns TRUE. Otherwise, returns
882 * XXX - Should this be in strutil.c?
885 byte_array_equal(GByteArray *ba1, GByteArray *ba2)
890 if (ba1->len != ba2->len)
893 if (memcmp(ba1->data, ba2->data, ba1->len) != 0)
900 /* Return a XML escaped representation of the unescaped string.
901 * The returned string must be freed when no longer in use. */
903 xml_escape(const gchar *unescaped)
905 GString *buffer = g_string_sized_new(128);
910 while ( (c = *p++) ) {
913 g_string_append(buffer, "<");
916 g_string_append(buffer, ">");
919 g_string_append(buffer, "&");
922 g_string_append(buffer, "'");
925 g_string_append(buffer, """);
928 g_string_append_c(buffer, c);
932 /* Return the string value contained within the GString
933 * after getting rid of the GString structure.
934 * This is the way to do this, see the GLib reference. */
935 return g_string_free(buffer, FALSE);
939 /* Return the first occurrence of needle in haystack.
940 * If not found, return NULL.
941 * If either haystack or needle has 0 length, return NULL.
942 * Algorithm copied from GNU's glibc 2.3.2 memmem() under LGPL 2.1+ */
944 epan_memmem(const guint8 *haystack, guint haystack_len,
945 const guint8 *needle, guint needle_len)
948 const guint8 *const last_possible = haystack + haystack_len - needle_len;
950 if (needle_len == 0) {
954 if (needle_len > haystack_len) {
958 for (begin = haystack ; begin <= last_possible; ++begin) {
959 if (begin[0] == needle[0] &&
960 !memcmp(&begin[1], needle + 1,
970 * Scan the search string to make sure it's valid hex. Return the
971 * number of bytes in nbytes.
974 convert_string_to_hex(const char *string, size_t *nbytes)
979 guint8 *bytes, *q, byte_val;
987 if (g_ascii_isspace(c))
988 continue; /* allow white space */
989 if (c==':' || c=='.' || c=='-')
990 continue; /* skip any ':', '.', or '-' between bytes */
991 if (!g_ascii_isxdigit(c)) {
992 /* Not a valid hex digit - fail */
997 * We can only match bytes, not nibbles; we must have a valid
998 * hex digit immediately after that hex digit.
1001 if (!g_ascii_isxdigit(c))
1004 /* 2 hex digits = 1 byte */
1009 * Were we given any hex digits?
1017 * OK, it's valid, and it generates "n_bytes" bytes; generate the
1020 bytes = (guint8 *)g_malloc(n_bytes);
1027 if (g_ascii_isspace(c))
1028 continue; /* allow white space */
1029 if (c==':' || c=='.' || c=='-')
1030 continue; /* skip any ':', '.', or '-' between bytes */
1031 /* From the loop above, we know this is a hex digit */
1032 byte_val = ws_xton(c);
1035 /* We also know this is a hex digit */
1037 byte_val |= ws_xton(c);
1046 * Copy if if it's a case-sensitive search; uppercase it if it's
1047 * a case-insensitive search.
1050 convert_string_case(const char *string, gboolean case_insensitive)
1053 if (case_insensitive) {
1054 return g_utf8_strup(string, -1);
1056 return g_strdup(string);
1061 epan_strcasestr(const char *haystack, const char *needle)
1063 gsize hlen = strlen(haystack);
1064 gsize nlen = strlen(needle);
1066 while (hlen-- >= nlen) {
1067 if (!g_ascii_strncasecmp(haystack, needle, nlen))
1075 string_or_null(const char *string)
1083 escape_string_len(const char *string)
1090 for (p = string; (c = *p) != '\0'; p++) {
1091 /* Backslashes and double-quotes must
1093 if (c == '\\' || c == '"') {
1096 /* Values that can't nicely be represented
1097 * in ASCII need to be escaped. */
1098 else if (!g_ascii_isprint(c)) {
1102 /* Other characters are just passed through. */
1107 return repr_len + 2; /* string plus leading and trailing quotes */
1111 escape_string(char *buf, const char *string)
1120 for (p = string; (c = *p) != '\0'; p++) {
1121 /* Backslashes and double-quotes must
1123 if (c == '\\' || c == '"') {
1127 /* Values that can't nicely be represented
1128 * in ASCII need to be escaped. */
1129 else if (!g_ascii_isprint(c)) {
1131 g_snprintf(hexbuf,sizeof(hexbuf), "%02x", (unsigned char) c);
1134 *bufp++ = hexbuf[0];
1135 *bufp++ = hexbuf[1];
1137 /* Other characters are just passed through. */
1147 #define GN_CHAR_ALPHABET_SIZE 128
1149 static gunichar IA5_default_alphabet[GN_CHAR_ALPHABET_SIZE] = {
1151 /*ITU-T recommendation T.50 specifies International Reference Alphabet 5 (IA5) */
1153 '?', '?', '?', '?', '?', '?', '?', '?',
1154 '?', '?', '?', '?', '?', '?', '?', '?',
1155 '?', '?', '?', '?', '?', '?', '?', '?',
1156 '?', '?', '?', '?', '?', '?', '?', '?',
1157 ' ', '!', '\"','#', '$', '%', '&', '\'',
1158 '(', ')', '*', '+', ',', '-', '.', '/',
1159 '0', '1', '2', '3', '4', '5', '6', '7',
1160 '8', '9', ':', ';', '<', '=', '>', '?',
1161 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
1162 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
1163 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
1164 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
1165 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1166 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1167 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1168 'x', 'y', 'z', '{', '|', '}', '~', '?'
1172 char_def_ia5_alphabet_decode(unsigned char value)
1174 if (value < GN_CHAR_ALPHABET_SIZE) {
1175 return IA5_default_alphabet[value];
1183 IA5_7BIT_decode(unsigned char * dest, const unsigned char* src, int len)
1188 for (i = 0, j = 0; j < len; j++) {
1189 buf = char_def_ia5_alphabet_decode(src[j]);
1190 i += g_unichar_to_utf8(buf,&(dest[i]));
1197 * This function takes a string and copies it, inserting a 'chr' before
1198 * every 'chr' in it.
1201 ws_strdup_escape_char (const gchar *str, const gchar chr)
1210 /* Worst case: A string that is full of 'chr' */
1211 q = new_str = (gchar *)g_malloc (strlen(str) * 2 + 1);
1225 * This function takes a string and copies it, removing any occurences of double
1226 * 'chr' with a single 'chr'.
1229 ws_strdup_unescape_char (const gchar *str, const char chr)
1238 /* Worst case: A string that contains no 'chr' */
1239 q = new_str = (gchar *)g_malloc (strlen(str) + 1);
1243 if ((*p == chr) && (*(p+1) == chr))
1253 /* Create a newly-allocated string with replacement values. */
1255 string_replace(const gchar* str, const gchar *old_val, const gchar *new_val)
1260 if (!str || !old_val) {
1264 str_parts = g_strsplit(str, old_val, 0);
1265 new_str = g_strjoinv(new_val, str_parts);
1266 g_strfreev(str_parts);
1272 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1277 * indent-tabs-mode: nil
1280 * vi: set shiftwidth=4 tabstop=8 expandtab:
1281 * :indentSize=4:tabSize=8:noTabs=true: