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.
38 * If a user _does_ pass in a too-small buffer, this is probably
39 * going to be too long to fit. However, even a partial string
40 * starting with "[Buf" should provide enough of a clue to be
43 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
46 low_nibble_of_octet_to_hex(guint8 oct)
48 /* At least one version of Apple's C compiler/linker is buggy, causing
49 a complaint from the linker about the "literal C string section"
50 not ending with '\0' if we initialize a 16-element "char" array with
51 a 16-character string, the fact that initializing such an array with
52 such a string is perfectly legitimate ANSI C nonwithstanding, the 17th
53 '\0' byte in the string nonwithstanding. */
54 static const gchar hex_digits[16] =
55 { '0', '1', '2', '3', '4', '5', '6', '7',
56 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
58 return hex_digits[oct & 0xF];
62 byte_to_hex(char *out, guint32 dword) {
63 *out++ = low_nibble_of_octet_to_hex(dword >> 4);
64 *out++ = low_nibble_of_octet_to_hex(dword);
69 word_to_hex(char *out, guint16 word) {
70 out = byte_to_hex(out, word >> 8);
71 out = byte_to_hex(out, word);
76 word_to_hex_npad(char *out, guint16 word) {
78 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 12));
80 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 8));
82 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 4));
83 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 0));
88 dword_to_hex(char *out, guint32 dword) {
89 out = byte_to_hex(out, dword >> 24);
90 out = byte_to_hex(out, dword >> 16);
91 out = byte_to_hex(out, dword >> 8);
92 out = byte_to_hex(out, dword);
97 dword_to_hex_punct(char *out, guint32 dword, char punct) {
98 out = byte_to_hex(out, dword >> 24);
100 out = byte_to_hex(out, dword >> 16);
102 out = byte_to_hex(out, dword >> 8);
104 out = byte_to_hex(out, dword);
109 * This does *not* null-terminate the string. It returns a pointer
110 * to the position in the string following the last character it
111 * puts there, so that the caller can either put the null terminator
112 * in or can append more stuff to the buffer.
114 * There needs to be at least len * 2 bytes left in the buffer.
117 bytes_to_hexstr(char *out, const guint8 *ad, guint32 len) {
121 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr()");
123 for (i = 0; i < len; i++)
124 out = byte_to_hex(out, ad[i]);
129 * This does *not* null-terminate the string. It returns a pointer
130 * to the position in the string following the last character it
131 * puts there, so that the caller can either put the null terminator
132 * in or can append more stuff to the buffer.
134 * There needs to be at least len * 3 - 1 bytes left in the buffer.
137 bytes_to_hexstr_punct(char *out, const guint8 *ad, guint32 len, char punct) {
141 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr_punct()");
143 out = byte_to_hex(out, ad[0]);
144 for (i = 1; i < len; i++) {
146 out = byte_to_hex(out, ad[i]);
151 /* Routine to convert a sequence of bytes to a hex string, one byte/two hex
152 * digits at at a time, with a specified punctuation character between
155 * If punct is '\0', no punctuation is applied (and thus
156 * the resulting string is (len-1) bytes shorter)
159 bytestring_to_str(const guint8 *ad, const guint32 len, const char punct) {
164 REPORT_DISSECTOR_BUG("Null pointer passed to bytestring_to_str()");
166 /* XXX, Old code was using int as iterator... Why len is guint32 anyway?! (darkjames) */
167 if ( ((int) len) < 0)
178 buf=(gchar *)ep_alloc(buflen);
181 bytes_to_hexstr_punct(buf, ad, len, punct);
183 bytes_to_hexstr(buf, ad, len);
185 buf[buflen-1] = '\0';
189 /* Max string length for displaying byte string. */
190 #define MAX_BYTE_STR_LEN 48
193 bytes_to_str(const guint8 *bd, int bd_len) {
199 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_str()");
201 cur=(gchar *)ep_alloc(MAX_BYTE_STR_LEN+3+1);
202 if (bd_len <= 0) { cur[0] = '\0'; return cur; }
204 if (bd_len > MAX_BYTE_STR_LEN/2) { /* bd_len > 24 */
206 bd_len = MAX_BYTE_STR_LEN/2;
209 cur_ptr = bytes_to_hexstr(cur, bd, bd_len); /* max MAX_BYTE_STR_LEN bytes */
212 cur_ptr = g_stpcpy(cur_ptr, "..."); /* 3 bytes */
214 *cur_ptr = '\0'; /* 1 byte */
218 /* Turn an array of bytes into a string showing the bytes in hex with
219 * punct as a bytes separator.
222 bytes_to_str_punct(const guint8 *bd, int bd_len, gchar punct) {
228 return bytes_to_str(bd, bd_len);
230 cur=(gchar *)ep_alloc(MAX_BYTE_STR_LEN+3+1);
231 if (bd_len <= 0) { cur[0] = '\0'; return cur; }
233 if (bd_len > MAX_BYTE_STR_LEN/3) { /* bd_len > 16 */
235 bd_len = MAX_BYTE_STR_LEN/3;
238 cur_ptr = bytes_to_hexstr_punct(cur, bd, bd_len, punct); /* max MAX_BYTE_STR_LEN-1 bytes */
241 *cur_ptr++ = punct; /* 1 byte */
242 cur_ptr = g_stpcpy(cur_ptr, "..."); /* 3 bytes */
250 guint32_to_str_buf_len(const guint32 u) {
251 if (u >= 1000000000)return 10;
252 if (u >= 100000000) return 9;
253 if (u >= 10000000) return 8;
254 if (u >= 1000000) return 7;
255 if (u >= 100000) return 6;
256 if (u >= 10000) return 5;
257 if (u >= 1000) return 4;
258 if (u >= 100) return 3;
259 if (u >= 10) return 2;
264 static const char fast_strings[][4] = {
265 "0", "1", "2", "3", "4", "5", "6", "7",
266 "8", "9", "10", "11", "12", "13", "14", "15",
267 "16", "17", "18", "19", "20", "21", "22", "23",
268 "24", "25", "26", "27", "28", "29", "30", "31",
269 "32", "33", "34", "35", "36", "37", "38", "39",
270 "40", "41", "42", "43", "44", "45", "46", "47",
271 "48", "49", "50", "51", "52", "53", "54", "55",
272 "56", "57", "58", "59", "60", "61", "62", "63",
273 "64", "65", "66", "67", "68", "69", "70", "71",
274 "72", "73", "74", "75", "76", "77", "78", "79",
275 "80", "81", "82", "83", "84", "85", "86", "87",
276 "88", "89", "90", "91", "92", "93", "94", "95",
277 "96", "97", "98", "99", "100", "101", "102", "103",
278 "104", "105", "106", "107", "108", "109", "110", "111",
279 "112", "113", "114", "115", "116", "117", "118", "119",
280 "120", "121", "122", "123", "124", "125", "126", "127",
281 "128", "129", "130", "131", "132", "133", "134", "135",
282 "136", "137", "138", "139", "140", "141", "142", "143",
283 "144", "145", "146", "147", "148", "149", "150", "151",
284 "152", "153", "154", "155", "156", "157", "158", "159",
285 "160", "161", "162", "163", "164", "165", "166", "167",
286 "168", "169", "170", "171", "172", "173", "174", "175",
287 "176", "177", "178", "179", "180", "181", "182", "183",
288 "184", "185", "186", "187", "188", "189", "190", "191",
289 "192", "193", "194", "195", "196", "197", "198", "199",
290 "200", "201", "202", "203", "204", "205", "206", "207",
291 "208", "209", "210", "211", "212", "213", "214", "215",
292 "216", "217", "218", "219", "220", "221", "222", "223",
293 "224", "225", "226", "227", "228", "229", "230", "231",
294 "232", "233", "234", "235", "236", "237", "238", "239",
295 "240", "241", "242", "243", "244", "245", "246", "247",
296 "248", "249", "250", "251", "252", "253", "254", "255"
299 char *uint_to_str_back(char *ptr, guint32 value);
302 guint32_to_str_buf(guint32 u, gchar *buf, int buf_len) {
303 int str_len = guint32_to_str_buf_len(u)+1;
305 gchar *bp = &buf[str_len];
307 if (buf_len < str_len) {
308 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
314 uint_to_str_back(bp, u);
318 guint32_to_str(const guint32 u) {
319 int str_len = 16; /* guint32_to_str_buf_len(u)+1; */
321 gchar *bp = (gchar *)ep_alloc(str_len);
322 guint32_to_str_buf(u, bp, str_len);
327 #define PLURALIZE(n) (((n) > 1) ? "s" : "")
328 #define COMMA(do_it) ((do_it) ? ", " : "")
331 * Maximum length of a string showing days/hours/minutes/seconds.
332 * (Does not include the terminating '\0'.)
333 * Includes space for a '-' sign for any negative components.
334 * -12345 days, 12 hours, 12 minutes, 12.123 seconds
336 #define TIME_SECS_LEN (10+1+4+2+2+5+2+2+7+2+2+7+4)
339 * Convert a value in seconds and fractions of a second to a string,
340 * giving time in days, hours, minutes, and seconds, and put the result
342 * "is_nsecs" says that "frac" is microseconds if true and milliseconds
344 * If time is negative, add a '-' to all non-null components.
347 time_secs_to_str_buf(gint32 time_val, const guint32 frac, const gboolean is_nsecs,
350 int hours, mins, secs;
351 const gchar *msign = "";
352 gboolean do_comma = FALSE;
354 if(time_val == G_MININT32) { /* That Which Shall Not Be Negated */
355 ep_strbuf_append_printf(buf, "Unable to cope with time value %d", time_val);
360 time_val = -time_val;
364 secs = time_val % 60;
366 mins = time_val % 60;
368 hours = time_val % 24;
372 ep_strbuf_append_printf(buf, "%s%u day%s", msign, time_val, PLURALIZE(time_val));
377 ep_strbuf_append_printf(buf, "%s%s%u hour%s", COMMA(do_comma), msign, hours, PLURALIZE(hours));
382 ep_strbuf_append_printf(buf, "%s%s%u minute%s", COMMA(do_comma), msign, mins, PLURALIZE(mins));
386 if (secs != 0 || frac != 0) {
389 ep_strbuf_append_printf(buf, "%s%s%u.%09u seconds", COMMA(do_comma), msign, secs, frac);
391 ep_strbuf_append_printf(buf, "%s%s%u.%03u seconds", COMMA(do_comma), msign, secs, frac);
393 ep_strbuf_append_printf(buf, "%s%s%u second%s", COMMA(do_comma), msign, secs, PLURALIZE(secs));
398 time_secs_to_str(const gint32 time_val)
402 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1, TIME_SECS_LEN+1);
405 ep_strbuf_append(buf, "0 seconds");
409 time_secs_to_str_buf(time_val, 0, FALSE, buf);
414 time_secs_to_str_buf_unsigned(guint32 time_val, const guint32 frac, const gboolean is_nsecs,
417 int hours, mins, secs;
418 gboolean do_comma = FALSE;
420 secs = time_val % 60;
422 mins = time_val % 60;
424 hours = time_val % 24;
428 ep_strbuf_append_printf(buf, "%u day%s", time_val, PLURALIZE(time_val));
432 ep_strbuf_append_printf(buf, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
436 ep_strbuf_append_printf(buf, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
439 if (secs != 0 || frac != 0) {
442 ep_strbuf_append_printf(buf, "%s%u.%09u seconds", COMMA(do_comma), secs, frac);
444 ep_strbuf_append_printf(buf, "%s%u.%03u seconds", COMMA(do_comma), secs, frac);
446 ep_strbuf_append_printf(buf, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
451 time_secs_to_str_unsigned(const guint32 time_val)
455 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1, TIME_SECS_LEN+1);
458 ep_strbuf_append(buf, "0 seconds");
462 time_secs_to_str_buf_unsigned(time_val, 0, FALSE, buf);
468 time_msecs_to_str(gint32 time_val)
473 buf=ep_strbuf_sized_new(TIME_SECS_LEN+1+3+1, TIME_SECS_LEN+1+3+1);
476 ep_strbuf_append(buf, "0 seconds");
481 /* oops we got passed a negative time */
483 msecs = time_val % 1000;
487 msecs = time_val % 1000;
491 time_secs_to_str_buf(time_val, msecs, FALSE, buf);
495 static const char mon_names[12][4] = {
510 static const gchar *get_zonename(struct tm *tmp) {
511 #if defined(HAVE_TM_ZONE)
514 if ((tmp->tm_isdst != 0) && (tmp->tm_isdst != 1)) {
517 # if defined(HAVE_TZNAME)
518 return tzname[tmp->tm_isdst];
520 # elif defined(_WIN32)
521 /* Windows C Runtime: */
522 /* _tzname is encoded using the "system default ansi code page" */
523 /* ("which is not necessarily the same as the C library locale"). */
524 /* So: _tzname must be converted to UTF8 before use. */
525 /* Alternative: use Windows GetTimeZoneInformation() to get the */
526 /* timezone name in UTF16 and convert same to UTF8. */
527 /* XXX: the result is that the timezone name will be based upon the */
528 /* system code page (iow: the charset of the system). */
529 /* Since Wireshark is not internationalized, it would seem more */
530 /* correct to show the timezone name in English, no matter what */
531 /* the system code page, but I don't how to do that (or if it's */
532 /* really even possible). */
533 /* In any case converting to UTF8 presumably at least keeps GTK */
534 /* happy. (A bug was reported wherein Wireshark crashed in GDK */
535 /* on a "Japanese version of Windows XP" when trying to copy */
536 /* the date/time string (containing a copy of _tz_name) to the */
540 static char *ws_tzname[2] = {NULL, NULL};
542 /* The g_malloc'd value returned from g_locale_to_utf8() is */
543 /* cached for all further use so there's no need to ever */
544 /* g_free() that value. */
545 if (ws_tzname[tmp->tm_isdst] == NULL) {
546 ws_tzname[tmp->tm_isdst] = g_locale_to_utf8(_tzname[tmp->tm_isdst], -1, NULL, NULL, NULL);
547 if (ws_tzname[tmp->tm_isdst] == NULL) {
548 ws_tzname[tmp->tm_isdst] = "???";
551 return ws_tzname[tmp->tm_isdst];
554 return tmp->tm_isdst ? "?DT" : "?ST";
561 abs_time_to_str(const nstime_t *abs_time, const absolute_time_display_e fmt,
564 struct tm *tmp = NULL;
565 const char *zonename = "???";
568 #if (defined _WIN32) && (_MSC_VER < 1500)
569 /* calling localtime() on MSVC 2005 with huge values causes it to crash */
570 /* XXX - find the exact value that still does work */
571 /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
572 if(abs_time->secs > 2000000000) {
578 case ABSOLUTE_TIME_UTC:
579 case ABSOLUTE_TIME_DOY_UTC:
580 tmp = gmtime(&abs_time->secs);
584 case ABSOLUTE_TIME_LOCAL:
585 tmp = localtime(&abs_time->secs);
587 zonename = get_zonename(tmp);
594 case ABSOLUTE_TIME_DOY_UTC:
596 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d.%09ld %s",
602 (long)abs_time->nsecs,
605 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d.%09ld",
611 (long)abs_time->nsecs);
615 case ABSOLUTE_TIME_UTC:
616 case ABSOLUTE_TIME_LOCAL:
618 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d.%09ld %s",
619 mon_names[tmp->tm_mon],
625 (long)abs_time->nsecs,
628 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d.%09ld",
629 mon_names[tmp->tm_mon],
635 (long)abs_time->nsecs);
640 buf = ep_strdup("Not representable");
645 abs_time_secs_to_str(const time_t abs_time, const absolute_time_display_e fmt,
648 struct tm *tmp = NULL;
649 const char *zonename = "???";
652 #if (defined _WIN32) && (_MSC_VER < 1500)
653 /* calling localtime() on MSVC 2005 with huge values causes it to crash */
654 /* XXX - find the exact value that still does work */
655 /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
656 if(abs_time > 2000000000) {
662 case ABSOLUTE_TIME_UTC:
663 case ABSOLUTE_TIME_DOY_UTC:
664 tmp = gmtime(&abs_time);
668 case ABSOLUTE_TIME_LOCAL:
669 tmp = localtime(&abs_time);
671 zonename = get_zonename(tmp);
678 case ABSOLUTE_TIME_DOY_UTC:
680 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d %s",
688 buf = ep_strdup_printf("%04d/%03d:%02d:%02d:%02d",
697 case ABSOLUTE_TIME_UTC:
698 case ABSOLUTE_TIME_LOCAL:
700 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d %s",
701 mon_names[tmp->tm_mon],
709 buf = ep_strdup_printf("%s %2d, %d %02d:%02d:%02d",
710 mon_names[tmp->tm_mon],
720 buf = ep_strdup("Not representable");
725 display_signed_time(gchar *buf, int buflen, const gint32 sec, gint32 frac,
726 const to_str_time_res_t units)
728 /* If the fractional part of the time stamp is negative,
729 print its absolute value and, if the seconds part isn't
730 (the seconds part should be zero in that case), stick
731 a "-" in front of the entire time stamp. */
745 case TO_STR_TIME_RES_T_SECS:
746 g_snprintf(buf, buflen, "%d", sec);
749 case TO_STR_TIME_RES_T_DSECS:
750 g_snprintf(buf, buflen, "%d.%01d", sec, frac);
753 case TO_STR_TIME_RES_T_CSECS:
754 g_snprintf(buf, buflen, "%d.%02d", sec, frac);
757 case TO_STR_TIME_RES_T_MSECS:
758 g_snprintf(buf, buflen, "%d.%03d", sec, frac);
761 case TO_STR_TIME_RES_T_USECS:
762 g_snprintf(buf, buflen, "%d.%06d", sec, frac);
765 case TO_STR_TIME_RES_T_NSECS:
766 g_snprintf(buf, buflen, "%d.%09d", sec, frac);
773 display_epoch_time(gchar *buf, int buflen, const time_t sec, gint32 frac,
774 const to_str_time_res_t units)
778 elapsed_secs = difftime(sec,(time_t)0);
780 /* This code copied from display_signed_time; keep it in case anyone
781 is looking at captures from before 1970 (???).
782 If the fractional part of the time stamp is negative,
783 print its absolute value and, if the seconds part isn't
784 (the seconds part should be zero in that case), stick
785 a "-" in front of the entire time stamp. */
788 if (elapsed_secs >= 0) {
799 case TO_STR_TIME_RES_T_SECS:
800 g_snprintf(buf, buflen, "%0.0f", elapsed_secs);
803 case TO_STR_TIME_RES_T_DSECS:
804 g_snprintf(buf, buflen, "%0.0f.%01d", elapsed_secs, frac);
807 case TO_STR_TIME_RES_T_CSECS:
808 g_snprintf(buf, buflen, "%0.0f.%02d", elapsed_secs, frac);
811 case TO_STR_TIME_RES_T_MSECS:
812 g_snprintf(buf, buflen, "%0.0f.%03d", elapsed_secs, frac);
815 case TO_STR_TIME_RES_T_USECS:
816 g_snprintf(buf, buflen, "%0.0f.%06d", elapsed_secs, frac);
819 case TO_STR_TIME_RES_T_NSECS:
820 g_snprintf(buf, buflen, "%0.0f.%09d", elapsed_secs, frac);
826 * Display a relative time as days/hours/minutes/seconds.
829 rel_time_to_str(const nstime_t *rel_time)
835 buf=ep_strbuf_sized_new(1+TIME_SECS_LEN+1+6+1, 1+TIME_SECS_LEN+1+6+1);
837 /* If the nanoseconds part of the time stamp is negative,
838 print its absolute value and, if the seconds part isn't
839 (the seconds part should be zero in that case), stick
840 a "-" in front of the entire time stamp. */
841 time_val = (gint) rel_time->secs;
842 nsec = rel_time->nsecs;
843 if (time_val == 0 && nsec == 0) {
844 ep_strbuf_append(buf, "0.000000000 seconds");
849 ep_strbuf_append_c(buf, '-');
852 * We assume here that "rel_time->secs" is negative
853 * or zero; if it's not, the time stamp is bogus,
854 * with a positive seconds and negative microseconds.
856 time_val = (gint) -rel_time->secs;
859 time_secs_to_str_buf(time_val, nsec, TRUE, buf);
863 #define REL_TIME_SECS_LEN (1+10+1+9+1)
866 * Display a relative time as seconds.
869 rel_time_to_secs_str(const nstime_t *rel_time)
873 buf=(gchar *)ep_alloc(REL_TIME_SECS_LEN);
875 display_signed_time(buf, REL_TIME_SECS_LEN, (gint32) rel_time->secs,
876 rel_time->nsecs, TO_STR_TIME_RES_T_NSECS);
881 * Generates a string representing the bits in a bitfield at "bit_offset" from an 8 bit boundary
882 * with the length in bits of no_of_bits based on value.
887 decode_bits_in_field(const guint bit_offset, const gint no_of_bits, const guint64 value)
889 guint64 mask = 0,tmp;
895 mask = mask << (no_of_bits-1);
897 /* Prepare the string, 256 pos for the bits and zero termination, + 64 for the spaces */
898 str=(char *)ep_alloc0(256+64);
899 for(bit=0;bit<((int)(bit_offset&0x07));bit++){
908 /* read the bits for the int */
909 for(i=0;i<no_of_bits;i++){
941 /* Generate, into "buf", a string showing the bits of a bitfield.
942 Return a pointer to the character after that string. */
943 /*XXX this needs a buf_len check */
945 other_decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width)
953 bit = 1 << (width - 1);
956 /* This bit is part of the field. Show its value. */
962 /* This bit is not part of the field. */
977 decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width)
981 p = other_decode_bitfield_value(buf, val, mask, width);
982 p = g_stpcpy(p, " = ");
987 /* Generate a string describing a Boolean bitfield (a one-bit field that
988 says something is either true or false). */
990 decode_boolean_bitfield(const guint32 val, const guint32 mask, const int width,
991 const char *truedesc, const char *falsedesc)
996 buf=(char *)ep_alloc(1025); /* is this a bit overkill? */
997 p = decode_bitfield_value(buf, val, mask, width);
1001 strcpy(p, falsedesc);
1005 /* Generate a string describing a numeric bitfield (an N-bit field whose
1006 value is just a number). */
1008 decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width,
1015 buf=(char *)ep_alloc(1025); /* isnt this a bit overkill? */
1016 /* Compute the number of bits we have to shift the bitfield right
1017 to extract its value. */
1018 while ((mask & (1<<shift)) == 0)
1021 p = decode_bitfield_value(buf, val, mask, width);
1022 g_snprintf(p, (gulong) (1025-(p-buf)), fmt, (val & mask) >> shift);
1027 This function is very fast and this function is called a lot.
1028 XXX update the ep_address_to_str stuff to use this function.
1031 ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len)
1033 register gchar const *p;
1034 register gchar *b=buf;
1036 if (buf_len < MAX_IP_STR_LEN) {
1037 g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
1041 p=fast_strings[*ad++];
1048 p=fast_strings[*ad++];
1055 p=fast_strings[*ad++];
1062 p=fast_strings[*ad];
1070 gchar* guid_to_str(const e_guid_t *guid) {
1073 buf=(gchar *)ep_alloc(GUID_STR_LEN);
1074 return guid_to_str_buf(guid, buf, GUID_STR_LEN);
1077 gchar* guid_to_str_buf(const e_guid_t *guid, gchar *buf, int buf_len) {
1078 char *tempptr = buf;
1080 if (buf_len < GUID_STR_LEN) {
1081 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);/* Let the unexpected value alert user */
1086 tempptr = dword_to_hex(tempptr, guid->data1); /* 8 bytes */
1087 *tempptr++ = '-'; /* 1 byte */
1088 tempptr = word_to_hex(tempptr, guid->data2); /* 4 bytes */
1089 *tempptr++ = '-'; /* 1 byte */
1090 tempptr = word_to_hex(tempptr, guid->data3); /* 4 bytes */
1091 *tempptr++ = '-'; /* 1 byte */
1092 tempptr = bytes_to_hexstr(tempptr, &guid->data4[0], 2); /* 4 bytes */
1093 *tempptr++ = '-'; /* 1 byte */
1094 tempptr = bytes_to_hexstr(tempptr, &guid->data4[2], 6); /* 12 bytes */
1100 const gchar* port_type_to_str (port_type type) {
1102 case PT_NONE: return "NONE";
1103 case PT_SCTP: return "SCTP";
1104 case PT_TCP: return "TCP";
1105 case PT_UDP: return "UDP";
1106 case PT_DCCP: return "DCCP";
1107 case PT_IPX: return "IPX";
1108 case PT_NCP: return "NCP";
1109 case PT_EXCHG: return "FC EXCHG";
1110 case PT_DDP: return "DDP";
1111 case PT_SBCCS: return "FICON SBCCS";
1112 case PT_IDP: return "IDP";
1113 case PT_TIPC: return "TIPC";
1114 case PT_USB: return "USB";
1115 case PT_I2C: return "I2C";
1116 case PT_IBQP: return "IBQP";
1117 case PT_BLUETOOTH: return "BLUETOOTH";
1118 default: return "[Unknown]";
1123 oct_to_str_back(char *ptr, guint32 value)
1126 *(--ptr) = '0' + (value & 0x7);
1135 hex_to_str_back(char *ptr, int pad, guint32 value)
1138 *(--ptr) = low_nibble_of_octet_to_hex(value);
1156 uint_to_str_back(char *ptr, guint32 value)
1164 while (value >= 10) {
1165 p = fast_strings[100 + (value % 100)];
1174 *(--ptr) = (value) | '0';
1180 int_to_str_back(char *ptr, gint32 value)
1183 ptr = uint_to_str_back(ptr, -value);
1186 ptr = uint_to_str_back(ptr, value);