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.
35 #include "to_str-int.h"
39 * If a user _does_ pass in a too-small buffer, this is probably
40 * going to be too long to fit. However, even a partial string
41 * starting with "[Buf" should provide enough of a clue to be
44 #define BUF_TOO_SMALL_ERR "[Buffer too small]"
47 low_nibble_of_octet_to_hex(guint8 oct
)
49 /* At least one version of Apple's C compiler/linker is buggy, causing
50 a complaint from the linker about the "literal C string section"
51 not ending with '\0' if we initialize a 16-element "char" array with
52 a 16-character string, the fact that initializing such an array with
53 such a string is perfectly legitimate ANSI C nonwithstanding, the 17th
54 '\0' byte in the string nonwithstanding. */
55 static const gchar hex_digits
[16] =
56 { '0', '1', '2', '3', '4', '5', '6', '7',
57 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
59 return hex_digits
[oct
& 0xF];
63 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
) {
71 out
= byte_to_hex(out
, word
>> 8);
72 out
= byte_to_hex(out
, word
);
77 word_to_hex_npad(char *out
, guint16 word
) {
79 *out
++ = low_nibble_of_octet_to_hex((guint8
)(word
>> 12));
81 *out
++ = low_nibble_of_octet_to_hex((guint8
)(word
>> 8));
83 *out
++ = low_nibble_of_octet_to_hex((guint8
)(word
>> 4));
84 *out
++ = low_nibble_of_octet_to_hex((guint8
)(word
>> 0));
89 dword_to_hex(char *out
, guint32 dword
) {
90 out
= byte_to_hex(out
, dword
>> 24);
91 out
= byte_to_hex(out
, dword
>> 16);
92 out
= byte_to_hex(out
, dword
>> 8);
93 out
= byte_to_hex(out
, dword
);
98 dword_to_hex_punct(char *out
, guint32 dword
, char punct
) {
99 out
= byte_to_hex(out
, dword
>> 24);
101 out
= byte_to_hex(out
, dword
>> 16);
103 out
= byte_to_hex(out
, dword
>> 8);
105 out
= byte_to_hex(out
, dword
);
110 * This does *not* null-terminate the string. It returns a pointer
111 * to the position in the string following the last character it
112 * puts there, so that the caller can either put the null terminator
113 * in or can append more stuff to the buffer.
115 * There needs to be at least len * 2 bytes left in the buffer.
118 bytes_to_hexstr(char *out
, const guint8
*ad
, guint32 len
) {
122 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr()");
124 for (i
= 0; i
< len
; i
++)
125 out
= byte_to_hex(out
, ad
[i
]);
130 * This does *not* null-terminate the string. It returns a pointer
131 * to the position in the string following the last character it
132 * puts there, so that the caller can either put the null terminator
133 * in or can append more stuff to the buffer.
135 * There needs to be at least len * 3 - 1 bytes left in the buffer.
138 bytes_to_hexstr_punct(char *out
, const guint8
*ad
, guint32 len
, char punct
) {
142 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_hexstr_punct()");
144 out
= byte_to_hex(out
, ad
[0]);
145 for (i
= 1; i
< len
; i
++) {
147 out
= byte_to_hex(out
, ad
[i
]);
152 /* Routine to convert a sequence of bytes to a hex string, one byte/two hex
153 * digits at at a time, with a specified punctuation character between
156 * If punct is '\0', no punctuation is applied (and thus
157 * the resulting string is (len-1) bytes shorter)
160 bytestring_to_str(const guint8
*ad
, const guint32 len
, const char punct
) {
165 REPORT_DISSECTOR_BUG("Null pointer passed to bytestring_to_str()");
167 /* XXX, Old code was using int as iterator... Why len is guint32 anyway?! (darkjames) */
168 if ( ((int) len
) < 0)
179 buf
=(gchar
*)ep_alloc(buflen
);
182 bytes_to_hexstr_punct(buf
, ad
, len
, punct
);
184 bytes_to_hexstr(buf
, ad
, len
);
186 buf
[buflen
-1] = '\0';
190 /* Max string length for displaying byte string. */
191 #define MAX_BYTE_STR_LEN 48
194 bytes_to_str(const guint8
*bd
, int bd_len
) {
200 REPORT_DISSECTOR_BUG("Null pointer passed to bytes_to_str()");
202 cur
=(gchar
*)ep_alloc(MAX_BYTE_STR_LEN
+3+1);
203 if (bd_len
<= 0) { cur
[0] = '\0'; return cur
; }
205 if (bd_len
> MAX_BYTE_STR_LEN
/2) { /* bd_len > 24 */
207 bd_len
= MAX_BYTE_STR_LEN
/2;
210 cur_ptr
= bytes_to_hexstr(cur
, bd
, bd_len
); /* max MAX_BYTE_STR_LEN bytes */
213 cur_ptr
= g_stpcpy(cur_ptr
, "..."); /* 3 bytes */
215 *cur_ptr
= '\0'; /* 1 byte */
219 /* Turn an array of bytes into a string showing the bytes in hex with
220 * punct as a bytes separator.
223 bytes_to_str_punct(const guint8
*bd
, int bd_len
, gchar punct
) {
229 return bytes_to_str(bd
, bd_len
);
231 cur
=(gchar
*)ep_alloc(MAX_BYTE_STR_LEN
+3+1);
232 if (bd_len
<= 0) { cur
[0] = '\0'; return cur
; }
234 if (bd_len
> MAX_BYTE_STR_LEN
/3) { /* bd_len > 16 */
236 bd_len
= MAX_BYTE_STR_LEN
/3;
239 cur_ptr
= bytes_to_hexstr_punct(cur
, bd
, bd_len
, punct
); /* max MAX_BYTE_STR_LEN-1 bytes */
242 *cur_ptr
++ = punct
; /* 1 byte */
243 cur_ptr
= g_stpcpy(cur_ptr
, "..."); /* 3 bytes */
251 guint32_to_str_buf_len(const guint32 u
) {
252 if (u
>= 1000000000)return 10;
253 if (u
>= 100000000) return 9;
254 if (u
>= 10000000) return 8;
255 if (u
>= 1000000) return 7;
256 if (u
>= 100000) return 6;
257 if (u
>= 10000) return 5;
258 if (u
>= 1000) return 4;
259 if (u
>= 100) return 3;
260 if (u
>= 10) return 2;
265 static const char fast_strings
[][4] = {
266 "0", "1", "2", "3", "4", "5", "6", "7",
267 "8", "9", "10", "11", "12", "13", "14", "15",
268 "16", "17", "18", "19", "20", "21", "22", "23",
269 "24", "25", "26", "27", "28", "29", "30", "31",
270 "32", "33", "34", "35", "36", "37", "38", "39",
271 "40", "41", "42", "43", "44", "45", "46", "47",
272 "48", "49", "50", "51", "52", "53", "54", "55",
273 "56", "57", "58", "59", "60", "61", "62", "63",
274 "64", "65", "66", "67", "68", "69", "70", "71",
275 "72", "73", "74", "75", "76", "77", "78", "79",
276 "80", "81", "82", "83", "84", "85", "86", "87",
277 "88", "89", "90", "91", "92", "93", "94", "95",
278 "96", "97", "98", "99", "100", "101", "102", "103",
279 "104", "105", "106", "107", "108", "109", "110", "111",
280 "112", "113", "114", "115", "116", "117", "118", "119",
281 "120", "121", "122", "123", "124", "125", "126", "127",
282 "128", "129", "130", "131", "132", "133", "134", "135",
283 "136", "137", "138", "139", "140", "141", "142", "143",
284 "144", "145", "146", "147", "148", "149", "150", "151",
285 "152", "153", "154", "155", "156", "157", "158", "159",
286 "160", "161", "162", "163", "164", "165", "166", "167",
287 "168", "169", "170", "171", "172", "173", "174", "175",
288 "176", "177", "178", "179", "180", "181", "182", "183",
289 "184", "185", "186", "187", "188", "189", "190", "191",
290 "192", "193", "194", "195", "196", "197", "198", "199",
291 "200", "201", "202", "203", "204", "205", "206", "207",
292 "208", "209", "210", "211", "212", "213", "214", "215",
293 "216", "217", "218", "219", "220", "221", "222", "223",
294 "224", "225", "226", "227", "228", "229", "230", "231",
295 "232", "233", "234", "235", "236", "237", "238", "239",
296 "240", "241", "242", "243", "244", "245", "246", "247",
297 "248", "249", "250", "251", "252", "253", "254", "255"
300 char *uint_to_str_back(char *ptr
, guint32 value
);
303 guint32_to_str_buf(guint32 u
, gchar
*buf
, int buf_len
) {
304 int str_len
= guint32_to_str_buf_len(u
)+1;
306 gchar
*bp
= &buf
[str_len
];
308 if (buf_len
< str_len
) {
309 g_strlcpy(buf
, BUF_TOO_SMALL_ERR
, buf_len
); /* Let the unexpected value alert user */
315 uint_to_str_back(bp
, u
);
319 guint32_to_str(const guint32 u
) {
320 int str_len
= 16; /* guint32_to_str_buf_len(u)+1; */
322 gchar
*bp
= (gchar
*)ep_alloc(str_len
);
323 guint32_to_str_buf(u
, bp
, str_len
);
328 #define PLURALIZE(n) (((n) > 1) ? "s" : "")
329 #define COMMA(do_it) ((do_it) ? ", " : "")
332 * Maximum length of a string showing days/hours/minutes/seconds.
333 * (Does not include the terminating '\0'.)
334 * Includes space for a '-' sign for any negative components.
335 * -12345 days, 12 hours, 12 minutes, 12.123 seconds
337 #define TIME_SECS_LEN (10+1+4+2+2+5+2+2+7+2+2+7+4)
340 * Convert a value in seconds and fractions of a second to a string,
341 * giving time in days, hours, minutes, and seconds, and put the result
343 * "is_nsecs" says that "frac" is microseconds if true and milliseconds
345 * If time is negative, add a '-' to all non-null components.
348 time_secs_to_str_buf(gint32 time_val
, const guint32 frac
, const gboolean is_nsecs
,
351 int hours
, mins
, secs
;
352 const gchar
*msign
= "";
353 gboolean do_comma
= FALSE
;
355 if(time_val
== G_MININT32
) { /* That Which Shall Not Be Negated */
356 ep_strbuf_append_printf(buf
, "Unable to cope with time value %d", time_val
);
361 time_val
= -time_val
;
365 secs
= time_val
% 60;
367 mins
= time_val
% 60;
369 hours
= time_val
% 24;
373 ep_strbuf_append_printf(buf
, "%s%u day%s", msign
, time_val
, PLURALIZE(time_val
));
378 ep_strbuf_append_printf(buf
, "%s%s%u hour%s", COMMA(do_comma
), msign
, hours
, PLURALIZE(hours
));
383 ep_strbuf_append_printf(buf
, "%s%s%u minute%s", COMMA(do_comma
), msign
, mins
, PLURALIZE(mins
));
387 if (secs
!= 0 || frac
!= 0) {
390 ep_strbuf_append_printf(buf
, "%s%s%u.%09u seconds", COMMA(do_comma
), msign
, secs
, frac
);
392 ep_strbuf_append_printf(buf
, "%s%s%u.%03u seconds", COMMA(do_comma
), msign
, secs
, frac
);
394 ep_strbuf_append_printf(buf
, "%s%s%u second%s", COMMA(do_comma
), msign
, secs
, PLURALIZE(secs
));
399 time_secs_to_str(const gint32 time_val
)
403 buf
=ep_strbuf_sized_new(TIME_SECS_LEN
+1, TIME_SECS_LEN
+1);
406 ep_strbuf_append(buf
, "0 seconds");
410 time_secs_to_str_buf(time_val
, 0, FALSE
, buf
);
415 time_secs_to_str_buf_unsigned(guint32 time_val
, const guint32 frac
, const gboolean is_nsecs
,
418 int hours
, mins
, secs
;
419 gboolean do_comma
= FALSE
;
421 secs
= time_val
% 60;
423 mins
= time_val
% 60;
425 hours
= time_val
% 24;
429 ep_strbuf_append_printf(buf
, "%u day%s", time_val
, PLURALIZE(time_val
));
433 ep_strbuf_append_printf(buf
, "%s%u hour%s", COMMA(do_comma
), hours
, PLURALIZE(hours
));
437 ep_strbuf_append_printf(buf
, "%s%u minute%s", COMMA(do_comma
), mins
, PLURALIZE(mins
));
440 if (secs
!= 0 || frac
!= 0) {
443 ep_strbuf_append_printf(buf
, "%s%u.%09u seconds", COMMA(do_comma
), secs
, frac
);
445 ep_strbuf_append_printf(buf
, "%s%u.%03u seconds", COMMA(do_comma
), secs
, frac
);
447 ep_strbuf_append_printf(buf
, "%s%u second%s", COMMA(do_comma
), secs
, PLURALIZE(secs
));
452 time_secs_to_str_unsigned(const guint32 time_val
)
456 buf
=ep_strbuf_sized_new(TIME_SECS_LEN
+1, TIME_SECS_LEN
+1);
459 ep_strbuf_append(buf
, "0 seconds");
463 time_secs_to_str_buf_unsigned(time_val
, 0, FALSE
, buf
);
469 time_msecs_to_str(gint32 time_val
)
474 buf
=ep_strbuf_sized_new(TIME_SECS_LEN
+1+3+1, TIME_SECS_LEN
+1+3+1);
477 ep_strbuf_append(buf
, "0 seconds");
482 /* oops we got passed a negative time */
484 msecs
= time_val
% 1000;
488 msecs
= time_val
% 1000;
492 time_secs_to_str_buf(time_val
, msecs
, FALSE
, buf
);
496 static const char mon_names
[12][4] = {
511 static const gchar
*get_zonename(struct tm
*tmp
) {
512 #if defined(HAVE_TM_ZONE)
515 if ((tmp
->tm_isdst
!= 0) && (tmp
->tm_isdst
!= 1)) {
518 # if defined(HAVE_TZNAME)
519 return tzname
[tmp
->tm_isdst
];
521 # elif defined(_WIN32)
522 /* Windows C Runtime: */
523 /* _tzname is encoded using the "system default ansi code page" */
524 /* ("which is not necessarily the same as the C library locale"). */
525 /* So: _tzname must be converted to UTF8 before use. */
526 /* Alternative: use Windows GetTimeZoneInformation() to get the */
527 /* timezone name in UTF16 and convert same to UTF8. */
528 /* XXX: the result is that the timezone name will be based upon the */
529 /* system code page (iow: the charset of the system). */
530 /* Since Wireshark is not internationalized, it would seem more */
531 /* correct to show the timezone name in English, no matter what */
532 /* the system code page, but I don't how to do that (or if it's */
533 /* really even possible). */
534 /* In any case converting to UTF8 presumably at least keeps GTK */
535 /* happy. (A bug was reported wherein Wireshark crashed in GDK */
536 /* on a "Japanese version of Windows XP" when trying to copy */
537 /* the date/time string (containing a copy of _tz_name) to the */
541 static char *ws_tzname
[2] = {NULL
, NULL
};
543 /* The g_malloc'd value returned from g_locale_to_utf8() is */
544 /* cached for all further use so there's no need to ever */
545 /* g_free() that value. */
546 if (ws_tzname
[tmp
->tm_isdst
] == NULL
) {
547 ws_tzname
[tmp
->tm_isdst
] = g_locale_to_utf8(_tzname
[tmp
->tm_isdst
], -1, NULL
, NULL
, NULL
);
548 if (ws_tzname
[tmp
->tm_isdst
] == NULL
) {
549 ws_tzname
[tmp
->tm_isdst
] = "???";
552 return ws_tzname
[tmp
->tm_isdst
];
555 return tmp
->tm_isdst
? "?DT" : "?ST";
562 abs_time_to_str(const nstime_t
*abs_time
, const absolute_time_display_e fmt
,
565 struct tm
*tmp
= NULL
;
566 const char *zonename
= "???";
569 #if (defined _WIN32) && (_MSC_VER < 1500)
570 /* calling localtime() on MSVC 2005 with huge values causes it to crash */
571 /* XXX - find the exact value that still does work */
572 /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
573 if(abs_time
->secs
> 2000000000) {
579 case ABSOLUTE_TIME_UTC
:
580 case ABSOLUTE_TIME_DOY_UTC
:
581 tmp
= gmtime(&abs_time
->secs
);
585 case ABSOLUTE_TIME_LOCAL
:
586 tmp
= localtime(&abs_time
->secs
);
588 zonename
= get_zonename(tmp
);
595 case ABSOLUTE_TIME_DOY_UTC
:
597 buf
= ep_strdup_printf("%04d/%03d:%02d:%02d:%02d.%09ld %s",
603 (long)abs_time
->nsecs
,
606 buf
= ep_strdup_printf("%04d/%03d:%02d:%02d:%02d.%09ld",
612 (long)abs_time
->nsecs
);
616 case ABSOLUTE_TIME_UTC
:
617 case ABSOLUTE_TIME_LOCAL
:
619 buf
= ep_strdup_printf("%s %2d, %d %02d:%02d:%02d.%09ld %s",
620 mon_names
[tmp
->tm_mon
],
626 (long)abs_time
->nsecs
,
629 buf
= ep_strdup_printf("%s %2d, %d %02d:%02d:%02d.%09ld",
630 mon_names
[tmp
->tm_mon
],
636 (long)abs_time
->nsecs
);
641 buf
= ep_strdup("Not representable");
646 abs_time_secs_to_str(const time_t abs_time
, const absolute_time_display_e fmt
,
649 struct tm
*tmp
= NULL
;
650 const char *zonename
= "???";
653 #if (defined _WIN32) && (_MSC_VER < 1500)
654 /* calling localtime() on MSVC 2005 with huge values causes it to crash */
655 /* XXX - find the exact value that still does work */
656 /* XXX - using _USE_32BIT_TIME_T might be another way to circumvent this problem */
657 if(abs_time
> 2000000000) {
663 case ABSOLUTE_TIME_UTC
:
664 case ABSOLUTE_TIME_DOY_UTC
:
665 tmp
= gmtime(&abs_time
);
669 case ABSOLUTE_TIME_LOCAL
:
670 tmp
= localtime(&abs_time
);
672 zonename
= get_zonename(tmp
);
679 case ABSOLUTE_TIME_DOY_UTC
:
681 buf
= ep_strdup_printf("%04d/%03d:%02d:%02d:%02d %s",
689 buf
= ep_strdup_printf("%04d/%03d:%02d:%02d:%02d",
698 case ABSOLUTE_TIME_UTC
:
699 case ABSOLUTE_TIME_LOCAL
:
701 buf
= ep_strdup_printf("%s %2d, %d %02d:%02d:%02d %s",
702 mon_names
[tmp
->tm_mon
],
710 buf
= ep_strdup_printf("%s %2d, %d %02d:%02d:%02d",
711 mon_names
[tmp
->tm_mon
],
721 buf
= ep_strdup("Not representable");
726 display_signed_time(gchar
*buf
, int buflen
, const gint32 sec
, gint32 frac
,
727 const to_str_time_res_t units
)
729 /* If the fractional part of the time stamp is negative,
730 print its absolute value and, if the seconds part isn't
731 (the seconds part should be zero in that case), stick
732 a "-" in front of the entire time stamp. */
746 case TO_STR_TIME_RES_T_SECS
:
747 g_snprintf(buf
, buflen
, "%d", sec
);
750 case TO_STR_TIME_RES_T_DSECS
:
751 g_snprintf(buf
, buflen
, "%d.%01d", sec
, frac
);
754 case TO_STR_TIME_RES_T_CSECS
:
755 g_snprintf(buf
, buflen
, "%d.%02d", sec
, frac
);
758 case TO_STR_TIME_RES_T_MSECS
:
759 g_snprintf(buf
, buflen
, "%d.%03d", sec
, frac
);
762 case TO_STR_TIME_RES_T_USECS
:
763 g_snprintf(buf
, buflen
, "%d.%06d", sec
, frac
);
766 case TO_STR_TIME_RES_T_NSECS
:
767 g_snprintf(buf
, buflen
, "%d.%09d", sec
, frac
);
774 display_epoch_time(gchar
*buf
, int buflen
, const time_t sec
, gint32 frac
,
775 const to_str_time_res_t units
)
779 elapsed_secs
= difftime(sec
,(time_t)0);
781 /* This code copied from display_signed_time; keep it in case anyone
782 is looking at captures from before 1970 (???).
783 If the fractional part of the time stamp is negative,
784 print its absolute value and, if the seconds part isn't
785 (the seconds part should be zero in that case), stick
786 a "-" in front of the entire time stamp. */
789 if (elapsed_secs
>= 0) {
800 case TO_STR_TIME_RES_T_SECS
:
801 g_snprintf(buf
, buflen
, "%0.0f", elapsed_secs
);
804 case TO_STR_TIME_RES_T_DSECS
:
805 g_snprintf(buf
, buflen
, "%0.0f.%01d", elapsed_secs
, frac
);
808 case TO_STR_TIME_RES_T_CSECS
:
809 g_snprintf(buf
, buflen
, "%0.0f.%02d", elapsed_secs
, frac
);
812 case TO_STR_TIME_RES_T_MSECS
:
813 g_snprintf(buf
, buflen
, "%0.0f.%03d", elapsed_secs
, frac
);
816 case TO_STR_TIME_RES_T_USECS
:
817 g_snprintf(buf
, buflen
, "%0.0f.%06d", elapsed_secs
, frac
);
820 case TO_STR_TIME_RES_T_NSECS
:
821 g_snprintf(buf
, buflen
, "%0.0f.%09d", elapsed_secs
, frac
);
827 * Display a relative time as days/hours/minutes/seconds.
830 rel_time_to_str(const nstime_t
*rel_time
)
836 buf
=ep_strbuf_sized_new(1+TIME_SECS_LEN
+1+6+1, 1+TIME_SECS_LEN
+1+6+1);
838 /* If the nanoseconds part of the time stamp is negative,
839 print its absolute value and, if the seconds part isn't
840 (the seconds part should be zero in that case), stick
841 a "-" in front of the entire time stamp. */
842 time_val
= (gint
) rel_time
->secs
;
843 nsec
= rel_time
->nsecs
;
844 if (time_val
== 0 && nsec
== 0) {
845 ep_strbuf_append(buf
, "0.000000000 seconds");
850 ep_strbuf_append_c(buf
, '-');
853 * We assume here that "rel_time->secs" is negative
854 * or zero; if it's not, the time stamp is bogus,
855 * with a positive seconds and negative microseconds.
857 time_val
= (gint
) -rel_time
->secs
;
860 time_secs_to_str_buf(time_val
, nsec
, TRUE
, buf
);
864 #define REL_TIME_SECS_LEN (1+10+1+9+1)
867 * Display a relative time as seconds.
870 rel_time_to_secs_str(const nstime_t
*rel_time
)
874 buf
=(gchar
*)ep_alloc(REL_TIME_SECS_LEN
);
876 display_signed_time(buf
, REL_TIME_SECS_LEN
, (gint32
) rel_time
->secs
,
877 rel_time
->nsecs
, TO_STR_TIME_RES_T_NSECS
);
882 * Generates a string representing the bits in a bitfield at "bit_offset" from an 8 bit boundary
883 * with the length in bits of no_of_bits based on value.
888 decode_bits_in_field(const guint bit_offset
, const gint no_of_bits
, const guint64 value
)
890 guint64 mask
= 0,tmp
;
896 mask
= mask
<< (no_of_bits
-1);
898 /* Prepare the string, 256 pos for the bits and zero termination, + 64 for the spaces */
899 str
=(char *)ep_alloc0(256+64);
900 for(bit
=0;bit
<((int)(bit_offset
&0x07));bit
++){
909 /* read the bits for the int */
910 for(i
=0;i
<no_of_bits
;i
++){
942 /* Generate, into "buf", a string showing the bits of a bitfield.
943 Return a pointer to the character after that string. */
944 /*XXX this needs a buf_len check */
946 other_decode_bitfield_value(char *buf
, const guint32 val
, const guint32 mask
, const int width
)
954 bit
= 1 << (width
- 1);
957 /* This bit is part of the field. Show its value. */
963 /* This bit is not part of the field. */
978 decode_bitfield_value(char *buf
, const guint32 val
, const guint32 mask
, const int width
)
982 p
= other_decode_bitfield_value(buf
, val
, mask
, width
);
983 p
= g_stpcpy(p
, " = ");
988 /* Generate a string describing a Boolean bitfield (a one-bit field that
989 says something is either true or false). */
991 decode_boolean_bitfield(const guint32 val
, const guint32 mask
, const int width
,
992 const char *truedesc
, const char *falsedesc
)
997 buf
=(char *)ep_alloc(1025); /* is this a bit overkill? */
998 p
= decode_bitfield_value(buf
, val
, mask
, width
);
1000 strcpy(p
, truedesc
);
1002 strcpy(p
, falsedesc
);
1006 /* Generate a string describing a numeric bitfield (an N-bit field whose
1007 value is just a number). */
1009 decode_numeric_bitfield(const guint32 val
, const guint32 mask
, const int width
,
1016 buf
=(char *)ep_alloc(1025); /* isnt this a bit overkill? */
1017 /* Compute the number of bits we have to shift the bitfield right
1018 to extract its value. */
1019 while ((mask
& (1<<shift
)) == 0)
1022 p
= decode_bitfield_value(buf
, val
, mask
, width
);
1023 g_snprintf(p
, (gulong
) (1025-(p
-buf
)), fmt
, (val
& mask
) >> shift
);
1028 This function is very fast and this function is called a lot.
1029 XXX update the ep_address_to_str stuff to use this function.
1032 ip_to_str_buf(const guint8
*ad
, gchar
*buf
, const int buf_len
)
1034 register gchar
const *p
;
1035 register gchar
*b
=buf
;
1037 if (buf_len
< MAX_IP_STR_LEN
) {
1038 g_snprintf ( buf
, buf_len
, BUF_TOO_SMALL_ERR
); /* Let the unexpected value alert user */
1042 p
=fast_strings
[*ad
++];
1049 p
=fast_strings
[*ad
++];
1056 p
=fast_strings
[*ad
++];
1063 p
=fast_strings
[*ad
];
1071 gchar
* guid_to_str(const e_guid_t
*guid
) {
1074 buf
=(gchar
*)ep_alloc(GUID_STR_LEN
);
1075 return guid_to_str_buf(guid
, buf
, GUID_STR_LEN
);
1078 gchar
* guid_to_str_buf(const e_guid_t
*guid
, gchar
*buf
, int buf_len
) {
1079 char *tempptr
= buf
;
1081 if (buf_len
< GUID_STR_LEN
) {
1082 g_strlcpy(buf
, BUF_TOO_SMALL_ERR
, buf_len
);/* Let the unexpected value alert user */
1087 tempptr
= dword_to_hex(tempptr
, guid
->data1
); /* 8 bytes */
1088 *tempptr
++ = '-'; /* 1 byte */
1089 tempptr
= word_to_hex(tempptr
, guid
->data2
); /* 4 bytes */
1090 *tempptr
++ = '-'; /* 1 byte */
1091 tempptr
= word_to_hex(tempptr
, guid
->data3
); /* 4 bytes */
1092 *tempptr
++ = '-'; /* 1 byte */
1093 tempptr
= bytes_to_hexstr(tempptr
, &guid
->data4
[0], 2); /* 4 bytes */
1094 *tempptr
++ = '-'; /* 1 byte */
1095 tempptr
= bytes_to_hexstr(tempptr
, &guid
->data4
[2], 6); /* 12 bytes */
1101 const gchar
* port_type_to_str (port_type type
) {
1103 case PT_NONE
: return "NONE";
1104 case PT_SCTP
: return "SCTP";
1105 case PT_TCP
: return "TCP";
1106 case PT_UDP
: return "UDP";
1107 case PT_DCCP
: return "DCCP";
1108 case PT_IPX
: return "IPX";
1109 case PT_NCP
: return "NCP";
1110 case PT_EXCHG
: return "FC EXCHG";
1111 case PT_DDP
: return "DDP";
1112 case PT_SBCCS
: return "FICON SBCCS";
1113 case PT_IDP
: return "IDP";
1114 case PT_TIPC
: return "TIPC";
1115 case PT_USB
: return "USB";
1116 case PT_I2C
: return "I2C";
1117 case PT_IBQP
: return "IBQP";
1118 case PT_BLUETOOTH
: return "BLUETOOTH";
1119 default: return "[Unknown]";
1124 oct_to_str_back(char *ptr
, guint32 value
)
1127 *(--ptr
) = '0' + (value
& 0x7);
1136 hex_to_str_back(char *ptr
, int pad
, guint32 value
)
1139 *(--ptr
) = low_nibble_of_octet_to_hex(value
);
1157 uint_to_str_back(char *ptr
, guint32 value
)
1165 while (value
>= 10) {
1166 p
= fast_strings
[100 + (value
% 100)];
1175 *(--ptr
) = (value
) | '0';
1181 int_to_str_back(char *ptr
, gint32 value
)
1184 ptr
= uint_to_str_back(ptr
, -value
);
1187 ptr
= uint_to_str_back(ptr
, value
);