2 * Routines for utilities to convert various other types to strings.
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.
31 #include "wmem/wmem.h"
34 #include "to_str-int.h"
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)
64 *out++ = low_nibble_of_octet_to_hex(dword >> 4);
65 *out++ = low_nibble_of_octet_to_hex(dword);
70 word_to_hex(char *out, guint16 word)
72 out = byte_to_hex(out, word >> 8);
73 out = byte_to_hex(out, word);
78 word_to_hex_npad(char *out, guint16 word)
81 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 12));
83 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 8));
85 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 4));
86 *out++ = low_nibble_of_octet_to_hex((guint8)(word >> 0));
91 dword_to_hex(char *out, guint32 dword)
93 out = byte_to_hex(out, dword >> 24);
94 out = byte_to_hex(out, dword >> 16);
95 out = byte_to_hex(out, dword >> 8);
96 out = byte_to_hex(out, dword);
101 dword_to_hex_punct(char *out, guint32 dword, char punct)
103 out = byte_to_hex(out, dword >> 24);
105 out = byte_to_hex(out, dword >> 16);
107 out = byte_to_hex(out, dword >> 8);
109 out = byte_to_hex(out, dword);
114 * This does *not* null-terminate the string. It returns a pointer
115 * to the position in the string following the last character it
116 * puts there, so that the caller can either put the null terminator
117 * in or can append more stuff to the buffer.
119 * There needs to be at least len * 2 bytes left in the buffer.
122 bytes_to_hexstr(char *out, const guint8 *ad, guint32 len)
127 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr()");
129 for (i = 0; i < len; i++)
130 out = byte_to_hex(out, ad[i]);
135 * This does *not* null-terminate the string. It returns a pointer
136 * to the position in the string following the last character it
137 * puts there, so that the caller can either put the null terminator
138 * in or can append more stuff to the buffer.
140 * There needs to be at least len * 3 - 1 bytes left in the buffer.
143 bytes_to_hexstr_punct(char *out, const guint8 *ad, guint32 len, char punct)
148 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr_punct()");
150 out = byte_to_hex(out, ad[0]);
151 for (i = 1; i < len; i++) {
153 out = byte_to_hex(out, ad[i]);
158 /* Routine to convert a sequence of bytes to a hex string, one byte/two hex
159 * digits at at a time, with a specified punctuation character between
162 * If punct is '\0', no punctuation is applied (and thus
163 * the resulting string is (len-1) bytes shorter)
166 bytestring_to_ep_str(const guint8 *ad, const guint32 len, const char punct)
172 REPORT_DISSECTOR_BUG("Null pointer passed to bytestring_to_ep_str()");
174 /* XXX, Old code was using int as iterator... Why len is guint32 anyway?! (darkjames) */
175 if ( ((int) len) < 0)
186 buf=(gchar *)ep_alloc(buflen);
189 bytes_to_hexstr_punct(buf, ad, len, punct);
191 bytes_to_hexstr(buf, ad, len);
193 buf[buflen-1] = '\0';
198 bytestring_to_str(wmem_allocator_t *scope, const guint8 *ad, const guint32 len, const char punct)
204 REPORT_DISSECTOR_BUG("Null pointer passed to bytestring_to_str()");
207 return wmem_strdup(scope, "");
214 buf=(gchar *)wmem_alloc(scope, buflen);
217 bytes_to_hexstr_punct(buf, ad, len, punct);
219 bytes_to_hexstr(buf, ad, len);
221 buf[buflen-1] = '\0';
225 /* Max string length for displaying byte string. */
226 #define MAX_BYTE_STR_LEN 48
229 bytes_to_ep_str(const guint8 *bd, int bd_len)
236 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_ep_str()");
238 cur=(gchar *)ep_alloc(MAX_BYTE_STR_LEN+3+1);
239 if (bd_len <= 0) { cur[0] = '\0'; return cur; }
241 if (bd_len > MAX_BYTE_STR_LEN/2) { /* bd_len > 24 */
243 bd_len = MAX_BYTE_STR_LEN/2;
246 cur_ptr = bytes_to_hexstr(cur, bd, bd_len); /* max MAX_BYTE_STR_LEN bytes */
249 cur_ptr = g_stpcpy(cur_ptr, "..."); /* 3 bytes */
251 *cur_ptr = '\0'; /* 1 byte */
255 /* Turn an array of bytes into a string showing the bytes in hex with
256 * punct as a bytes separator.
259 bytes_to_ep_str_punct(const guint8 *bd, int bd_len, gchar punct)
266 return bytes_to_ep_str(bd, bd_len);
268 cur=(gchar *)ep_alloc(MAX_BYTE_STR_LEN+3+1);
269 if (bd_len <= 0) { cur[0] = '\0'; return cur; }
271 if (bd_len > MAX_BYTE_STR_LEN/3) { /* bd_len > 16 */
273 bd_len = MAX_BYTE_STR_LEN/3;
276 cur_ptr = bytes_to_hexstr_punct(cur, bd, bd_len, punct); /* max MAX_BYTE_STR_LEN-1 bytes */
279 *cur_ptr++ = punct; /* 1 byte */
280 cur_ptr = g_stpcpy(cur_ptr, "..."); /* 3 bytes */
288 guint32_to_str_buf_len(const guint32 u)
290 if (u >= 1000000000)return 10;
291 if (u >= 100000000) return 9;
292 if (u >= 10000000) return 8;
293 if (u >= 1000000) return 7;
294 if (u >= 100000) return 6;
295 if (u >= 10000) return 5;
296 if (u >= 1000) return 4;
297 if (u >= 100) return 3;
298 if (u >= 10) return 2;
303 static const char fast_strings[][4] = {
304 "0", "1", "2", "3", "4", "5", "6", "7",
305 "8", "9", "10", "11", "12", "13", "14", "15",
306 "16", "17", "18", "19", "20", "21", "22", "23",
307 "24", "25", "26", "27", "28", "29", "30", "31",
308 "32", "33", "34", "35", "36", "37", "38", "39",
309 "40", "41", "42", "43", "44", "45", "46", "47",
310 "48", "49", "50", "51", "52", "53", "54", "55",
311 "56", "57", "58", "59", "60", "61", "62", "63",
312 "64", "65", "66", "67", "68", "69", "70", "71",
313 "72", "73", "74", "75", "76", "77", "78", "79",
314 "80", "81", "82", "83", "84", "85", "86", "87",
315 "88", "89", "90", "91", "92", "93", "94", "95",
316 "96", "97", "98", "99", "100", "101", "102", "103",
317 "104", "105", "106", "107", "108", "109", "110", "111",
318 "112", "113", "114", "115", "116", "117", "118", "119",
319 "120", "121", "122", "123", "124", "125", "126", "127",
320 "128", "129", "130", "131", "132", "133", "134", "135",
321 "136", "137", "138", "139", "140", "141", "142", "143",
322 "144", "145", "146", "147", "148", "149", "150", "151",
323 "152", "153", "154", "155", "156", "157", "158", "159",
324 "160", "161", "162", "163", "164", "165", "166", "167",
325 "168", "169", "170", "171", "172", "173", "174", "175",
326 "176", "177", "178", "179", "180", "181", "182", "183",
327 "184", "185", "186", "187", "188", "189", "190", "191",
328 "192", "193", "194", "195", "196", "197", "198", "199",
329 "200", "201", "202", "203", "204", "205", "206", "207",
330 "208", "209", "210", "211", "212", "213", "214", "215",
331 "216", "217", "218", "219", "220", "221", "222", "223",
332 "224", "225", "226", "227", "228", "229", "230", "231",
333 "232", "233", "234", "235", "236", "237", "238", "239",
334 "240", "241", "242", "243", "244", "245", "246", "247",
335 "248", "249", "250", "251", "252", "253", "254", "255"
339 guint32_to_str_buf(guint32 u, gchar *buf, int buf_len)
341 int str_len = guint32_to_str_buf_len(u)+1;
343 gchar *bp = &buf[str_len];
345 if (buf_len < str_len) {
346 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
352 uint_to_str_back(bp, u);
355 #define PLURALIZE(n) (((n) > 1) ? "s" : "")
356 #define COMMA(do_it) ((do_it) ? ", " : "")
359 * Maximum length of a string showing days/hours/minutes/seconds.
360 * (Does not include the terminating '\0'.)
361 * Includes space for a '-' sign for any negative components.
362 * -12345 days, 12 hours, 12 minutes, 12.123 seconds
364 #define TIME_SECS_LEN (10+1+4+2+2+5+2+2+7+2+2+7+4)
367 * Convert a value in seconds and fractions of a second to a string,
368 * giving time in days, hours, minutes, and seconds, and put the result
370 * "is_nsecs" says that "frac" is microseconds if true and milliseconds
372 * If time is negative, add a '-' to all non-null components.
375 time_secs_to_str_buf(gint32 time_val, const guint32 frac, const gboolean is_nsecs,
378 int hours, mins, secs;
379 const gchar *msign = "";
380 gboolean do_comma = FALSE;
382 if(time_val == G_MININT32) { /* That Which Shall Not Be Negated */
383 wmem_strbuf_append_printf(buf, "Unable to cope with time value %d", time_val);
388 time_val = -time_val;
392 secs = time_val % 60;
394 mins = time_val % 60;
396 hours = time_val % 24;
400 wmem_strbuf_append_printf(buf, "%s%u day%s", msign, time_val, PLURALIZE(time_val));
405 wmem_strbuf_append_printf(buf, "%s%s%u hour%s", COMMA(do_comma), msign, hours, PLURALIZE(hours));
410 wmem_strbuf_append_printf(buf, "%s%s%u minute%s", COMMA(do_comma), msign, mins, PLURALIZE(mins));
414 if (secs != 0 || frac != 0) {
417 wmem_strbuf_append_printf(buf, "%s%s%u.%09u seconds", COMMA(do_comma), msign, secs, frac);
419 wmem_strbuf_append_printf(buf, "%s%s%u.%03u seconds", COMMA(do_comma), msign, secs, frac);
421 wmem_strbuf_append_printf(buf, "%s%s%u second%s", COMMA(do_comma), msign, secs, PLURALIZE(secs));
426 time_secs_to_str(wmem_allocator_t *scope, const gint32 time_val)
431 return wmem_strdup(scope, "0 seconds");
434 buf = wmem_strbuf_sized_new(scope, TIME_SECS_LEN+1, TIME_SECS_LEN+1);
436 time_secs_to_str_buf(time_val, 0, FALSE, buf);
438 return wmem_strbuf_finalize(buf);
442 time_secs_to_str_buf_unsigned(guint32 time_val, const guint32 frac, const gboolean is_nsecs,
445 int hours, mins, secs;
446 gboolean do_comma = FALSE;
448 secs = time_val % 60;
450 mins = time_val % 60;
452 hours = time_val % 24;
456 wmem_strbuf_append_printf(buf, "%u day%s", time_val, PLURALIZE(time_val));
460 wmem_strbuf_append_printf(buf, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
464 wmem_strbuf_append_printf(buf, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
467 if (secs != 0 || frac != 0) {
470 wmem_strbuf_append_printf(buf, "%s%u.%09u seconds", COMMA(do_comma), secs, frac);
472 wmem_strbuf_append_printf(buf, "%s%u.%03u seconds", COMMA(do_comma), secs, frac);
474 wmem_strbuf_append_printf(buf, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
479 time_secs_to_str_unsigned(wmem_allocator_t *scope, const guint32 time_val)
484 return wmem_strdup(scope, "0 seconds");
487 buf = wmem_strbuf_sized_new(scope, TIME_SECS_LEN+1, TIME_SECS_LEN+1);
489 time_secs_to_str_buf_unsigned(time_val, 0, FALSE, buf);
491 return wmem_strbuf_finalize(buf);
496 time_msecs_to_str(wmem_allocator_t *scope, gint32 time_val)
502 return wmem_strdup(scope, "0 seconds");
505 buf = wmem_strbuf_sized_new(scope, TIME_SECS_LEN+1+3+1, TIME_SECS_LEN+1+3+1);
508 /* oops we got passed a negative time */
510 msecs = time_val % 1000;
514 msecs = time_val % 1000;
518 time_secs_to_str_buf(time_val, msecs, FALSE, buf);
520 return wmem_strbuf_finalize(buf);
523 static const char mon_names[12][4] = {
539 get_zonename(struct tm *tmp)
541 #if defined(HAVE_TM_ZONE)
544 if ((tmp->tm_isdst != 0) && (tmp->tm_isdst != 1)) {
547 # if defined(HAVE_TZNAME)
548 return tzname[tmp->tm_isdst];
550 # elif defined(_WIN32)
551 /* Windows C Runtime: */
552 /* _tzname is encoded using the "system default ansi code page" */
553 /* ("which is not necessarily the same as the C library locale"). */
554 /* So: _tzname must be converted to UTF8 before use. */
555 /* Alternative: use Windows GetTimeZoneInformation() to get the */
556 /* timezone name in UTF16 and convert same to UTF8. */
557 /* XXX: the result is that the timezone name will be based upon the */
558 /* system code page (iow: the charset of the system). */
559 /* Since Wireshark is not internationalized, it would seem more */
560 /* correct to show the timezone name in English, no matter what */
561 /* the system code page, but I don't how to do that (or if it's */
562 /* really even possible). */
563 /* In any case converting to UTF8 presumably at least keeps GTK */
564 /* happy. (A bug was reported wherein Wireshark crashed in GDK */
565 /* on a "Japanese version of Windows XP" when trying to copy */
566 /* the date/time string (containing a copy of _tz_name) to the */
570 static char *ws_tzname[2] = {NULL, NULL};
572 /* The g_malloc'd value returned from g_locale_to_utf8() is */
573 /* cached for all further use so there's no need to ever */
574 /* g_free() that value. */
575 if (ws_tzname[tmp->tm_isdst] == NULL) {
576 ws_tzname[tmp->tm_isdst] = g_locale_to_utf8(_tzname[tmp->tm_isdst], -1, NULL, NULL, NULL);
577 if (ws_tzname[tmp->tm_isdst] == NULL) {
578 ws_tzname[tmp->tm_isdst] = "???";
581 return ws_tzname[tmp->tm_isdst];
584 return tmp->tm_isdst ? "?DT" : "?ST";
591 abs_time_to_str(wmem_allocator_t *scope, const nstime_t *abs_time, const absolute_time_display_e fmt,
594 struct tm *tmp = NULL;
595 const char *zonename = "???";
601 case ABSOLUTE_TIME_UTC:
602 case ABSOLUTE_TIME_DOY_UTC:
603 tmp = gmtime(&abs_time->secs);
607 case ABSOLUTE_TIME_LOCAL:
608 tmp = localtime(&abs_time->secs);
610 zonename = get_zonename(tmp);
617 case ABSOLUTE_TIME_DOY_UTC:
619 buf = wmem_strdup_printf(scope,
620 "%04d/%03d:%02d:%02d:%02d.%09ld %s",
626 (long)abs_time->nsecs,
629 buf = wmem_strdup_printf(scope,
630 "%04d/%03d:%02d:%02d:%02d.%09ld",
636 (long)abs_time->nsecs);
640 case ABSOLUTE_TIME_UTC:
641 case ABSOLUTE_TIME_LOCAL:
643 buf = wmem_strdup_printf(scope,
644 "%s %2d, %d %02d:%02d:%02d.%09ld %s",
645 mon_names[tmp->tm_mon],
651 (long)abs_time->nsecs,
654 buf = wmem_strdup_printf(scope,
655 "%s %2d, %d %02d:%02d:%02d.%09ld",
656 mon_names[tmp->tm_mon],
662 (long)abs_time->nsecs);
667 buf = wmem_strdup(scope, "Not representable");
672 abs_time_secs_to_str(wmem_allocator_t *scope, const time_t abs_time, const absolute_time_display_e fmt,
675 struct tm *tmp = NULL;
676 const char *zonename = "???";
681 case ABSOLUTE_TIME_UTC:
682 case ABSOLUTE_TIME_DOY_UTC:
683 tmp = gmtime(&abs_time);
687 case ABSOLUTE_TIME_LOCAL:
688 tmp = localtime(&abs_time);
690 zonename = get_zonename(tmp);
697 case ABSOLUTE_TIME_DOY_UTC:
699 buf = wmem_strdup_printf(scope,
700 "%04d/%03d:%02d:%02d:%02d %s",
708 buf = wmem_strdup_printf(scope,
709 "%04d/%03d:%02d:%02d:%02d",
718 case ABSOLUTE_TIME_UTC:
719 case ABSOLUTE_TIME_LOCAL:
721 buf = wmem_strdup_printf(scope,
722 "%s %2d, %d %02d:%02d:%02d %s",
723 mon_names[tmp->tm_mon],
731 buf = wmem_strdup_printf(scope,
732 "%s %2d, %d %02d:%02d:%02d",
733 mon_names[tmp->tm_mon],
743 buf = wmem_strdup(scope, "Not representable");
748 display_signed_time(gchar *buf, int buflen, const gint32 sec, gint32 frac,
749 const to_str_time_res_t units)
751 /* this buffer is not NUL terminated */
752 gint8 num_buf[16]; /* max: '-2147483648', '.1000000000' */
753 gint8 *num_end = &num_buf[16];
760 /* If the fractional part of the time stamp is negative,
761 print its absolute value and, if the seconds part isn't
762 (the seconds part should be zero in that case), stick
763 a "-" in front of the entire time stamp. */
773 num_ptr = int_to_str_back(num_end, sec);
775 num_len = MIN((int) (num_end - num_ptr), buflen);
776 memcpy(buf, num_ptr, num_len);
781 case TO_STR_TIME_RES_T_SECS:
787 case TO_STR_TIME_RES_T_DSECS:
788 num_ptr = uint_to_str_back_len(num_end, frac, 1);
791 case TO_STR_TIME_RES_T_CSECS:
792 num_ptr = uint_to_str_back_len(num_end, frac, 2);
795 case TO_STR_TIME_RES_T_MSECS:
796 num_ptr = uint_to_str_back_len(num_end, frac, 3);
799 case TO_STR_TIME_RES_T_USECS:
800 num_ptr = uint_to_str_back_len(num_end, frac, 6);
803 case TO_STR_TIME_RES_T_NSECS:
804 num_ptr = uint_to_str_back_len(num_end, frac, 9);
812 num_len = MIN((int) (num_end - num_ptr), buflen);
813 memcpy(buf, num_ptr, num_len);
818 /* need to NUL terminate, we know that buffer had at least 1 byte */
826 display_epoch_time(gchar *buf, int buflen, const time_t sec, gint32 frac,
827 const to_str_time_res_t units)
831 elapsed_secs = difftime(sec,(time_t)0);
833 /* This code copied from display_signed_time; keep it in case anyone
834 is looking at captures from before 1970 (???).
835 If the fractional part of the time stamp is negative,
836 print its absolute value and, if the seconds part isn't
837 (the seconds part should be zero in that case), stick
838 a "-" in front of the entire time stamp. */
841 if (elapsed_secs >= 0) {
852 case TO_STR_TIME_RES_T_SECS:
853 g_snprintf(buf, buflen, "%0.0f", elapsed_secs);
856 case TO_STR_TIME_RES_T_DSECS:
857 g_snprintf(buf, buflen, "%0.0f.%01d", elapsed_secs, frac);
860 case TO_STR_TIME_RES_T_CSECS:
861 g_snprintf(buf, buflen, "%0.0f.%02d", elapsed_secs, frac);
864 case TO_STR_TIME_RES_T_MSECS:
865 g_snprintf(buf, buflen, "%0.0f.%03d", elapsed_secs, frac);
868 case TO_STR_TIME_RES_T_USECS:
869 g_snprintf(buf, buflen, "%0.0f.%06d", elapsed_secs, frac);
872 case TO_STR_TIME_RES_T_NSECS:
873 g_snprintf(buf, buflen, "%0.0f.%09d", elapsed_secs, frac);
879 * Display a relative time as days/hours/minutes/seconds.
882 rel_time_to_str(wmem_allocator_t *scope, const nstime_t *rel_time)
888 /* If the nanoseconds part of the time stamp is negative,
889 print its absolute value and, if the seconds part isn't
890 (the seconds part should be zero in that case), stick
891 a "-" in front of the entire time stamp. */
892 time_val = (gint) rel_time->secs;
893 nsec = rel_time->nsecs;
894 if (time_val == 0 && nsec == 0) {
895 return wmem_strdup(scope, "0.000000000 seconds");
898 buf = wmem_strbuf_sized_new(scope, 1+TIME_SECS_LEN+1+6+1, 1+TIME_SECS_LEN+1+6+1);
902 wmem_strbuf_append_c(buf, '-');
905 * We assume here that "rel_time->secs" is negative
906 * or zero; if it's not, the time stamp is bogus,
907 * with a positive seconds and negative microseconds.
909 time_val = (gint) -rel_time->secs;
912 time_secs_to_str_buf(time_val, nsec, TRUE, buf);
914 return wmem_strbuf_finalize(buf);
917 #define REL_TIME_SECS_LEN (1+10+1+9+1)
920 * Display a relative time as seconds.
923 rel_time_to_secs_str(wmem_allocator_t *scope, const nstime_t *rel_time)
927 buf=(gchar *)wmem_alloc(scope, REL_TIME_SECS_LEN);
929 display_signed_time(buf, REL_TIME_SECS_LEN, (gint32) rel_time->secs,
930 rel_time->nsecs, TO_STR_TIME_RES_T_NSECS);
935 * Generates a string representing the bits in a bitfield at "bit_offset" from an 8 bit boundary
936 * with the length in bits of no_of_bits based on value.
941 decode_bits_in_field(const guint bit_offset, const gint no_of_bits, const guint64 value)
943 guint64 mask = 0,tmp;
949 mask = mask << (no_of_bits-1);
951 /* Prepare the string, 256 pos for the bits and zero termination, + 64 for the spaces */
952 str=(char *)ep_alloc0(256+64);
953 for(bit=0;bit<((int)(bit_offset&0x07));bit++){
962 /* read the bits for the int */
963 for(i=0;i<no_of_bits;i++){
995 /* Generate, into "buf", a string showing the bits of a bitfield.
996 Return a pointer to the character after that string. */
997 /*XXX this needs a buf_len check */
999 other_decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width)
1007 bit = 1 << (width - 1);
1010 /* This bit is part of the field. Show its value. */
1016 /* This bit is not part of the field. */
1031 decode_bitfield_value(char *buf, const guint32 val, const guint32 mask, const int width)
1035 p = other_decode_bitfield_value(buf, val, mask, width);
1036 p = g_stpcpy(p, " = ");
1041 /* Generate a string describing a numeric bitfield (an N-bit field whose
1042 value is just a number). */
1044 decode_numeric_bitfield(const guint32 val, const guint32 mask, const int width,
1051 buf=(char *)ep_alloc(1025); /* isn't this a bit overkill? */
1052 /* Compute the number of bits we have to shift the bitfield right
1053 to extract its value. */
1054 while ((mask & (1<<shift)) == 0)
1057 p = decode_bitfield_value(buf, val, mask, width);
1058 g_snprintf(p, (gulong) (1025-(p-buf)), fmt, (val & mask) >> shift);
1063 This function is very fast and this function is called a lot.
1064 XXX update the ep_address_to_str stuff to use this function.
1067 ip_to_str_buf(const guint8 *ad, gchar *buf, const int buf_len)
1069 register gchar const *p;
1070 register gchar *b=buf;
1072 if (buf_len < MAX_IP_STR_LEN) {
1073 g_snprintf ( buf, buf_len, BUF_TOO_SMALL_ERR ); /* Let the unexpected value alert user */
1077 p=fast_strings[*ad++];
1084 p=fast_strings[*ad++];
1091 p=fast_strings[*ad++];
1098 p=fast_strings[*ad];
1107 guid_to_ep_str(const e_guid_t *guid)
1111 buf=(gchar *)ep_alloc(GUID_STR_LEN);
1112 return guid_to_str_buf(guid, buf, GUID_STR_LEN);
1116 guid_to_str_buf(const e_guid_t *guid, gchar *buf, int buf_len)
1118 char *tempptr = buf;
1120 if (buf_len < GUID_STR_LEN) {
1121 g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len);/* Let the unexpected value alert user */
1126 tempptr = dword_to_hex(tempptr, guid->data1); /* 8 bytes */
1127 *tempptr++ = '-'; /* 1 byte */
1128 tempptr = word_to_hex(tempptr, guid->data2); /* 4 bytes */
1129 *tempptr++ = '-'; /* 1 byte */
1130 tempptr = word_to_hex(tempptr, guid->data3); /* 4 bytes */
1131 *tempptr++ = '-'; /* 1 byte */
1132 tempptr = bytes_to_hexstr(tempptr, &guid->data4[0], 2); /* 4 bytes */
1133 *tempptr++ = '-'; /* 1 byte */
1134 tempptr = bytes_to_hexstr(tempptr, &guid->data4[2], 6); /* 12 bytes */
1141 port_type_to_str (port_type type)
1144 case PT_NONE: return "NONE";
1145 case PT_SCTP: return "SCTP";
1146 case PT_TCP: return "TCP";
1147 case PT_UDP: return "UDP";
1148 case PT_DCCP: return "DCCP";
1149 case PT_IPX: return "IPX";
1150 case PT_NCP: return "NCP";
1151 case PT_EXCHG: return "FC EXCHG";
1152 case PT_DDP: return "DDP";
1153 case PT_SBCCS: return "FICON SBCCS";
1154 case PT_IDP: return "IDP";
1155 case PT_TIPC: return "TIPC";
1156 case PT_USB: return "USB";
1157 case PT_I2C: return "I2C";
1158 case PT_IBQP: return "IBQP";
1159 case PT_BLUETOOTH: return "BLUETOOTH";
1160 default: return "[Unknown]";
1165 oct_to_str_back(char *ptr, guint32 value)
1168 *(--ptr) = '0' + (value & 0x7);
1177 hex_to_str_back(char *ptr, int len, guint32 value)
1180 *(--ptr) = low_nibble_of_octet_to_hex(value);
1198 uint_to_str_back(char *ptr, guint32 value)
1206 while (value >= 10) {
1207 p = fast_strings[100 + (value % 100)];
1216 *(--ptr) = (value) | '0';
1222 uint_to_str_back_len(char *ptr, guint32 value, int len)
1226 new_ptr = uint_to_str_back(ptr, value);
1228 /* substract from len number of generated characters */
1229 len -= (int)(ptr - new_ptr);
1231 /* pad remaining with '0' */
1242 int_to_str_back(char *ptr, gint32 value)
1245 ptr = uint_to_str_back(ptr, -value);
1248 ptr = uint_to_str_back(ptr, value);
1254 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1259 * indent-tabs-mode: t
1262 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1263 * :indentSize=8:tabSize=8:noTabs=false: