2 * Routines for utilities to convert various other types to strings.
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37 * If a user _does_ pass in a too-small buffer, this is probably
38 * going to be too long to fit. However, even a partial string
39 * starting with "[Buf" should provide enough of a clue to be
42 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
45 byte_to_hex(char *out, guint32 dword) {
46 /* At least one version of Apple's C compiler/linker is buggy, causing
47 a complaint from the linker about the "literal C string section"
48 not ending with '\0' if we initialize a 16-element "char" array with
49 a 16-character string, the fact that initializing such an array with
50 such a string is perfectly legitimate ANSI C nonwithstanding, the 17th
51 '\0' byte in the string nonwithstanding. */
52 static const gchar hex_digits[16] =
53 { '0', '1', '2', '3', '4', '5', '6', '7',
54 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
56 *out++ = hex_digits[(dword >> 4) & 0xF];
57 *out++ = hex_digits[dword & 0xF];
62 word_to_hex(char *out, guint16 word) {
63 out = byte_to_hex(out, word >> 8);
64 out = byte_to_hex(out, word);
69 word_to_hex_npad(char *out, guint16 word) {
70 static const gchar hex_digits[16] =
71 { '0', '1', '2', '3', '4', '5', '6', '7',
72 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
75 *out++ = hex_digits[(word >> 12) & 0xF];
77 *out++ = hex_digits[(word >> 8) & 0xF];
79 *out++ = hex_digits[(word >> 4) & 0xF];
80 *out++ = hex_digits[word & 0xF];
85 dword_to_hex(char *out, guint32 dword) {
86 out = byte_to_hex(out, dword >> 24);
87 out = byte_to_hex(out, dword >> 16);
88 out = byte_to_hex(out, dword >> 8);
89 out = byte_to_hex(out, dword);
94 dword_to_hex_punct(char *out, guint32 dword, char punct) {
95 out = byte_to_hex(out, dword >> 24);
97 out = byte_to_hex(out, dword >> 16);
99 out = byte_to_hex(out, dword >> 8);
101 out = byte_to_hex(out, dword);
106 * This does *not* null-terminate the string. It returns a pointer
107 * to the position in the string following the last character it
108 * puts there, so that the caller can either put the null terminator
109 * in or can append more stuff to the buffer.
111 * There needs to be at least len * 2 bytes left in the buffer.
114 bytes_to_hexstr(char *out, const guint8 *ad, guint32 len) {
118 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr()");
120 for (i = 0; i < len; i++)
121 out = byte_to_hex(out, ad[i]);
126 * This does *not* null-terminate the string. It returns a pointer
127 * to the position in the string following the last character it
128 * puts there, so that the caller can either put the null terminator
129 * in or can append more stuff to the buffer.
131 * There needs to be at least len * 3 - 1 bytes left in the buffer.
134 bytes_to_hexstr_punct(char *out, const guint8 *ad, guint32 len, char punct) {
138 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr_punct()");
140 out = byte_to_hex(out, ad[0]);
141 for (i = 1; i < len; i++) {
143 out = byte_to_hex(out, ad[i]);
148 /* Routine to convert a sequence of bytes to a hex string, one byte/two hex
149 * digits at at a time, with a specified punctuation character between
152 * If punct is '\0', no punctuation is applied (and thus
153 * the resulting string is (len-1) bytes shorter)
156 bytestring_to_str(const guint8 *ad, const guint32 len, const char punct) {
161 REPORT_DISSECTOR_BUG("Null pointer passed to bytestring_to_str()");
163 /* XXX, Old code was using int as iterator... Why len is guint32 anyway?! (darkjames) */
164 if ( ((int) len) < 0)
175 buf=ep_alloc(buflen);
178 bytes_to_hexstr_punct(buf, ad, len, punct);
180 bytes_to_hexstr(buf, ad, len);
182 buf[buflen-1] = '\0';
186 /* Max string length for displaying byte string. */
187 #define MAX_BYTE_STR_LEN 48
190 bytes_to_str(const guint8 *bd, int bd_len) {
196 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_str()");
198 cur=ep_alloc(MAX_BYTE_STR_LEN+3+1);
199 if (bd_len <= 0) { cur[0] = '\0'; return cur; }
201 if (bd_len > MAX_BYTE_STR_LEN/2) { /* bd_len > 24 */
203 bd_len = MAX_BYTE_STR_LEN/2;
206 cur_ptr = bytes_to_hexstr(cur, bd, bd_len); /* max MAX_BYTE_STR_LEN bytes */
209 cur_ptr = g_stpcpy(cur_ptr, "..."); /* 3 bytes */
211 *cur_ptr = '\0'; /* 1 byte */
215 /* Turn an array of bytes into a string showing the bytes in hex with
216 * punct as a bytes separator.
219 bytes_to_str_punct(const guint8 *bd, int bd_len, gchar punct) {
225 return bytes_to_str(bd, bd_len);
227 cur=ep_alloc(MAX_BYTE_STR_LEN+3+1);
228 if (bd_len <= 0) { cur[0] = '\0'; return cur; }
230 if (bd_len > MAX_BYTE_STR_LEN/3) { /* bd_len > 16 */
232 bd_len = MAX_BYTE_STR_LEN/3;
235 cur_ptr = bytes_to_hexstr_punct(cur, bd, bd_len, punct); /* max MAX_BYTE_STR_LEN-1 bytes */
238 *cur_ptr++ = punct; /* 1 byte */
239 cur_ptr = g_stpcpy(cur_ptr, "..."); /* 3 bytes */
247 guint32_to_str_buf_len(const guint32 u) {
248 if (u >= 1000000000)return 10;
249 if (u >= 100000000) return 9;
250 if (u >= 10000000) return 8;
251 if (u >= 1000000) return 7;
252 if (u >= 100000) return 6;
253 if (u >= 10000) return 5;
254 if (u >= 1000) return 4;
255 if (u >= 100) return 3;
256 if (u >= 10) return 2;
261 static const char * const fast_strings[] = {
262 "0", "1", "2", "3", "4", "5", "6", "7",
263 "8", "9", "10", "11", "12", "13", "14", "15",
264 "16", "17", "18", "19", "20", "21", "22", "23",
265 "24", "25", "26", "27", "28", "29", "30", "31",
266 "32", "33", "34", "35", "36", "37", "38", "39",
267 "40", "41", "42", "43", "44", "45", "46", "47",
268 "48", "49", "50", "51", "52", "53", "54", "55",
269 "56", "57", "58", "59", "60", "61", "62", "63",
270 "64", "65", "66", "67", "68", "69", "70", "71",
271 "72", "73", "74", "75", "76", "77", "78", "79",
272 "80", "81", "82", "83", "84", "85", "86", "87",
273 "88", "89", "90", "91", "92", "93", "94", "95",
274 "96", "97", "98", "99", "100", "101", "102", "103",
275 "104", "105", "106", "107", "108", "109", "110", "111",
276 "112", "113", "114", "115", "116", "117", "118", "119",
277 "120", "121", "122", "123", "124", "125", "126", "127",
278 "128", "129", "130", "131", "132", "133", "134", "135",
279 "136", "137", "138", "139", "140", "141", "142", "143",
280 "144", "145", "146", "147", "148", "149", "150", "151",
281 "152", "153", "154", "155", "156", "157", "158", "159",
282 "160", "161", "162", "163", "164", "165", "166", "167",
283 "168", "169", "170", "171", "172", "173", "174", "175",
284 "176", "177", "178", "179", "180", "181", "182", "183",
285 "184", "185", "186", "187", "188", "189", "190", "191",
286 "192", "193", "194", "195", "196", "197", "198", "199",
287 "200", "201", "202", "203", "204", "205", "206", "207",
288 "208", "209", "210", "211", "212", "213", "214", "215",
289 "216", "217", "218", "219", "220", "221", "222", "223",
290 "224", "225", "226", "227", "228", "229", "230", "231",
291 "232", "233", "234", "235", "236", "237", "238", "239",
292 "240", "241", "242", "243", "244", "245", "246", "247",
293 "248", "249", "250", "251", "252", "253", "254", "255"
297 guint32_to_str_buf(guint32 u, gchar *buf, int buf_len) {
298 int str_len = guint32_to_str_buf_len(u)+1;
300 gchar *bp = &buf[str_len];
303 if (buf_len < str_len) {
304 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
311 p = fast_strings[100 + (u % 100)];
319 if (bp != buf) /* ugly, fixme! */
320 *--bp = (u % 10) | '0';
324 guint32_to_str(const guint32 u) {
325 int str_len = 16; /* guint32_to_str_buf_len(u)+1; */
327 gchar *bp = ep_alloc(str_len);
328 guint32_to_str_buf(u, bp, str_len);
333 #define PLURALIZE(n) (((n) > 1) ? "s" : "")
334 #define COMMA(do_it) ((do_it) ? ", " : "")
337 * Maximum length of a string showing days/hours/minutes/seconds.
338 * (Does not include the terminating '\0'.)
339 * Includes space for a '-' sign for any negative components.
340 * -12345 days, 12 hours, 12 minutes, 12.123 seconds
342 #define TIME_SECS_LEN (10+1+4+2+2+5+2+2+7+2+2+7+4)
345 * Convert a value in seconds and fractions of a second to a string,
346 * giving time in days, hours, minutes, and seconds, and put the result
348 * "is_nsecs" says that "frac" is microseconds if true and milliseconds
350 * If time is negative, add a '-' to all non-null components.
353 time_secs_to_str_buf(gint32 time_val, const guint32 frac, const gboolean is_nsecs,
356 int hours, mins, secs;
357 const gchar *msign = "";
358 gboolean do_comma = FALSE;
360 if(time_val == G_MININT32) { /* That Which Shall Not Be Negated */
361 ep_strbuf_append_printf(buf, "Unable to cope with time value %d", time_val);
366 time_val = -time_val;
370 secs = time_val % 60;
372 mins = time_val % 60;
374 hours = time_val % 24;
378 ep_strbuf_append_printf(buf, "%s%u day%s", msign, time_val, PLURALIZE(time_val));
383 ep_strbuf_append_printf(buf, "%s%s%u hour%s", COMMA(do_comma), msign, hours, PLURALIZE(hours));
388 ep_strbuf_append_printf(buf, "%s%s%u minute%s", COMMA(do_comma), msign, mins, PLURALIZE(mins));
392 if (secs != 0 || frac != 0) {
395 ep_strbuf_append_printf(buf, "%s%s%u.%09u seconds", COMMA(do_comma), msign, secs, frac);
397 ep_strbuf_append_printf(buf, "%s%s%u.%03u seconds", COMMA(do_comma), msign, secs, frac);
399 ep_strbuf_append_printf(buf, "%s%s%u second%s", COMMA(do_comma), msign, secs, PLURALIZE(secs));
404 time_secs_to_str(const gint32 time_val)
408 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1, TIME_SECS_LEN+1);
411 ep_strbuf_append(buf, "0 seconds");
415 time_secs_to_str_buf(time_val, 0, FALSE, buf);
420 time_secs_to_str_buf_unsigned(guint32 time_val, const guint32 frac, const gboolean is_nsecs,
423 int hours, mins, secs;
424 gboolean do_comma = FALSE;
426 secs = time_val % 60;
428 mins = time_val % 60;
430 hours = time_val % 24;
434 ep_strbuf_append_printf(buf, "%u day%s", time_val, PLURALIZE(time_val));
438 ep_strbuf_append_printf(buf, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
442 ep_strbuf_append_printf(buf, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
445 if (secs != 0 || frac != 0) {
448 ep_strbuf_append_printf(buf, "%s%u.%09u seconds", COMMA(do_comma), secs, frac);
450 ep_strbuf_append_printf(buf, "%s%u.%03u seconds", COMMA(do_comma), secs, frac);
452 ep_strbuf_append_printf(buf, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
457 time_secs_to_str_unsigned(const guint32 time_val)
461 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1, TIME_SECS_LEN+1);
464 ep_strbuf_append(buf, "0 seconds");
468 time_secs_to_str_buf_unsigned(time_val, 0, FALSE, buf);
474 time_msecs_to_str(gint32 time_val)
479 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1+3+1, TIME_SECS_LEN+1+3+1);
482 ep_strbuf_append(buf, "0 seconds");
487 /* oops we got passed a negative time */
489 msecs = time_val % 1000;
493 msecs = time_val % 1000;
497 time_secs_to_str_buf(time_val, msecs, FALSE, buf);
501 static const char *mon_names[12] = {
516 static const gchar *get_zonename(struct tm *tmp) {
517 #if defined(HAVE_TM_ZONE)
520 if ((tmp->tm_isdst != 0) && (tmp->tm_isdst != 1)) {
523 # if defined(HAVE_TZNAME)
524 return tzname[tmp->tm_isdst];
526 # elif defined(_WIN32)
527 /* Windows C Runtime: */
528 /* _tzname is encoded using the "system default ansi code page" */
529 /* ("which is not necessarily the same as the C library locale"). */
530 /* So: _tzname must be converted to UTF8 before use. */
531 /* Alternative: use Windows GetTimeZoneInformation() to get the */
532 /* timezone name in UTF16 and convert same to UTF8. */
533 /* XXX: the result is that the timezone name will be based upon the */
534 /* system code page (iow: the charset of the system). */
535 /* Since Wireshark is not internationalized, it would seem more */
536 /* correct to show the timezone name in English, no matter what */
537 /* the system code page, but I don't how to do that (or if it's */
538 /* really even possible). */
539 /* In any case converting to UTF8 presumably at least keeps GTK */
540 /* happy. (A bug was reported wherein Wireshark crashed in GDK */
541 /* on a "Japanese version of Windows XP" when trying to copy */
542 /* the date/time string (containing a copy of _tz_name) to the */
546 static char *ws_tzname[2] = {NULL, NULL};
548 /* The g_malloc'd value returned from g_locale_to_utf8() is */
549 /* cached for all further use so there's no need to ever */
550 /* g_free() that value. */
551 if (ws_tzname[tmp->tm_isdst] == NULL) {
552 ws_tzname[tmp->tm_isdst] = g_locale_to_utf8(_tzname[tmp->tm_isdst], -1, NULL, NULL, NULL);
553 if (ws_tzname[tmp->tm_isdst] == NULL) {
554 ws_tzname[tmp->tm_isdst] = "???";
557 return ws_tzname[tmp->tm_isdst];
560 return tmp->tm_isdst ? "?DT" : "?ST";
567 abs_time_to_str(const nstime_t *abs_time, const absolute_time_display_e fmt,
570 struct tm *tmp = NULL;
571 const char *zonename = "???";
574 #if (defined _WIN32) && (_MSC_VER < 1500)
575 /* calling localtime() on MSVC 2005 with huge values causes it to crash */
576 /* XXX - find the exact value that still does work */
577 /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
578 if(abs_time->secs > 2000000000) {
584 case ABSOLUTE_TIME_UTC:
585 case ABSOLUTE_TIME_DOY_UTC:
586 tmp = gmtime(&abs_time->secs);
590 case ABSOLUTE_TIME_LOCAL:
591 tmp = localtime(&abs_time->secs);
593 zonename = get_zonename(tmp);
600 case ABSOLUTE_TIME_DOY_UTC:
602 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d.%09ld %s",
608 (long)abs_time->nsecs,
611 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d.%09ld",
617 (long)abs_time->nsecs);
621 case ABSOLUTE_TIME_UTC:
622 case ABSOLUTE_TIME_LOCAL:
624 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d.%09ld %s",
625 mon_names[tmp->tm_mon],
631 (long)abs_time->nsecs,
634 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d.%09ld",
635 mon_names[tmp->tm_mon],
641 (long)abs_time->nsecs);
646 buf = ep_strdup("Not representable");
651 abs_time_secs_to_str(const time_t abs_time, const absolute_time_display_e fmt,
654 struct tm *tmp = NULL;
655 const char *zonename = "???";
658 #if (defined _WIN32) && (_MSC_VER < 1500)
659 /* calling localtime() on MSVC 2005 with huge values causes it to crash */
660 /* XXX - find the exact value that still does work */
661 /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
662 if(abs_time > 2000000000) {
668 case ABSOLUTE_TIME_UTC:
669 case ABSOLUTE_TIME_DOY_UTC:
670 tmp = gmtime(&abs_time);
674 case ABSOLUTE_TIME_LOCAL:
675 tmp = localtime(&abs_time);
677 zonename = get_zonename(tmp);
684 case ABSOLUTE_TIME_DOY_UTC:
686 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d %s",
694 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d",
703 case ABSOLUTE_TIME_UTC:
704 case ABSOLUTE_TIME_LOCAL:
706 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d %s",
707 mon_names[tmp->tm_mon],
715 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d",
716 mon_names[tmp->tm_mon],
726 buf = ep_strdup("Not representable");
731 display_signed_time(gchar *buf, int buflen, const gint32 sec, gint32 frac,
732 const to_str_time_res_t units)
734 /* If the fractional part of the time stamp is negative,
735 print its absolute value and, if the seconds part isn't
736 (the seconds part should be zero in that case), stick
737 a "-" in front of the entire time stamp. */
751 case TO_STR_TIME_RES_T_SECS:
752 g_snprintf(buf, buflen, "%d", sec);
755 case TO_STR_TIME_RES_T_DSECS:
756 g_snprintf(buf, buflen, "%d.%01d", sec, frac);
759 case TO_STR_TIME_RES_T_CSECS:
760 g_snprintf(buf, buflen, "%d.%02d", sec, frac);
763 case TO_STR_TIME_RES_T_MSECS:
764 g_snprintf(buf, buflen, "%d.%03d", sec, frac);
767 case TO_STR_TIME_RES_T_USECS:
768 g_snprintf(buf, buflen, "%d.%06d", sec, frac);
771 case TO_STR_TIME_RES_T_NSECS:
772 g_snprintf(buf, buflen, "%d.%09d", sec, frac);
779 display_epoch_time(gchar *buf, int buflen, const time_t sec, gint32 frac,
780 const to_str_time_res_t units)
784 elapsed_secs = difftime(sec,(time_t)0);
786 /* This code copied from display_signed_time; keep it in case anyone
787 is looking at captures from before 1970 (???).
788 If the fractional part of the time stamp is negative,
789 print its absolute value and, if the seconds part isn't
790 (the seconds part should be zero in that case), stick
791 a "-" in front of the entire time stamp. */
794 if (elapsed_secs >= 0) {
805 case TO_STR_TIME_RES_T_SECS:
806 g_snprintf(buf, buflen, "%0.0f", elapsed_secs);
809 case TO_STR_TIME_RES_T_DSECS:
810 g_snprintf(buf, buflen, "%0.0f.%01d", elapsed_secs, frac);
813 case TO_STR_TIME_RES_T_CSECS:
814 g_snprintf(buf, buflen, "%0.0f.%02d", elapsed_secs, frac);
817 case TO_STR_TIME_RES_T_MSECS:
818 g_snprintf(buf, buflen, "%0.0f.%03d", elapsed_secs, frac);
821 case TO_STR_TIME_RES_T_USECS:
822 g_snprintf(buf, buflen, "%0.0f.%06d", elapsed_secs, frac);
825 case TO_STR_TIME_RES_T_NSECS:
826 g_snprintf(buf, buflen, "%0.0f.%09d", elapsed_secs, frac);
832 * Display a relative time as days/hours/minutes/seconds.
835 rel_time_to_str(const nstime_t *rel_time)
841 buf=ep_strbuf_sized_new(1+TIME_SECS_LEN+1+6+1, 1+TIME_SECS_LEN+1+6+1);
843 /* If the nanoseconds part of the time stamp is negative,
844 print its absolute value and, if the seconds part isn't
845 (the seconds part should be zero in that case), stick
846 a "-" in front of the entire time stamp. */
847 time_val = (gint) rel_time->secs;
848 nsec = rel_time->nsecs;
849 if (time_val == 0 && nsec == 0) {
850 ep_strbuf_append(buf, "0.000000000 seconds");
855 ep_strbuf_append_c(buf, '-');
858 * We assume here that "rel_time->secs" is negative
859 * or zero; if it's not, the time stamp is bogus,
860 * with a positive seconds and negative microseconds.
862 time_val = (gint) -rel_time->secs;
865 time_secs_to_str_buf(time_val, nsec, TRUE, buf);
869 #define REL_TIME_SECS_LEN (1+10+1+9+1)
872 * Display a relative time as seconds.
875 rel_time_to_secs_str(const nstime_t *rel_time)
879 buf=ep_alloc(REL_TIME_SECS_LEN);
881 display_signed_time(buf, REL_TIME_SECS_LEN, (gint32) rel_time->secs,
882 rel_time->nsecs, TO_STR_TIME_RES_T_NSECS);
887 * Generates a string representing the bits in a bitfield at "bit_offset" from an 8 bit boundary
888 * with the length in bits of no_of_bits based on value.
893 decode_bits_in_field(const guint bit_offset, const gint no_of_bits, const guint64 value)
895 guint64 mask = 0,tmp;
901 mask = mask << (no_of_bits-1);
903 /* Prepare the string, 256 pos for the bits and zero termination, + 64 for the spaces */
904 str=ep_alloc0(256+64);
905 for(bit=0;bit<((int)(bit_offset&0x07));bit++){
914 /* read the bits for the int */
915 for(i=0;i<no_of_bits;i++){
947 /* Generate, into "buf", a string showing the bits of a bitfield.
948 Return a pointer to the character after that string. */
949 /*XXX this needs a buf_len check */
951 other_decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width)
959 bit = 1 << (width - 1);
962 /* This bit is part of the field. Show its value. */
968 /* This bit is not part of the field. */
983 decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width)
987 p = other_decode_bitfield_value(buf, val, mask, width);
993 /* Generate a string describing a Boolean bitfield (a one-bit field that
994 says something is either true or false). */
996 decode_boolean_bitfield(const guint32 val, const guint32 mask, const int width,
997 const char *truedesc, const char *falsedesc)
1002 buf=ep_alloc(1025); /* is this a bit overkill? */
1003 p = decode_bitfield_value(buf, val, mask, width);
1005 strcpy(p, truedesc);
1007 strcpy(p, falsedesc);
1011 /* Generate a string describing a numeric bitfield (an N-bit field whose
1012 value is just a number). */
1014 decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width,
1021 buf=ep_alloc(1025); /* isnt this a bit overkill? */
1022 /* Compute the number of bits we have to shift the bitfield right
1023 to extract its value. */
1024 while ((mask & (1<<shift)) == 0)
1027 p = decode_bitfield_value(buf, val, mask, width);
1028 g_snprintf(p, (gulong) (1025-(p-buf)), fmt, (val & mask) >> shift);
1033 This function is very fast and this function is called a lot.
1034 XXX update the ep_address_to_str stuff to use this function.
1037 ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len)
1039 register gchar const *p;
1040 register gchar *b=buf;
1042 if (buf_len < MAX_IP_STR_LEN) {
1043 g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
1047 p=fast_strings[*ad++];
1054 p=fast_strings[*ad++];
1061 p=fast_strings[*ad++];
1068 p=fast_strings[*ad];
1076 gchar* guid_to_str(const e_guid_t *guid) {
1079 buf=ep_alloc(GUID_STR_LEN);
1080 return guid_to_str_buf(guid, buf, GUID_STR_LEN);
1083 gchar* guid_to_str_buf(const e_guid_t *guid, gchar *buf, int buf_len) {
1084 char *tempptr = buf;
1086 if (buf_len < GUID_STR_LEN) {
1087 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);/* Let the unexpected value alert user */
1092 tempptr = dword_to_hex(tempptr, guid->data1); /* 8 bytes */
1093 *tempptr++ = '-'; /* 1 byte */
1094 tempptr = word_to_hex(tempptr, guid->data2); /* 4 bytes */
1095 *tempptr++ = '-'; /* 1 byte */
1096 tempptr = word_to_hex(tempptr, guid->data3); /* 4 bytes */
1097 *tempptr++ = '-'; /* 1 byte */
1098 tempptr = bytes_to_hexstr(tempptr, &guid->data4[0], 2); /* 4 bytes */
1099 *tempptr++ = '-'; /* 1 byte */
1100 tempptr = bytes_to_hexstr(tempptr, &guid->data4[2], 6); /* 12 bytes */