Introduce two new functions for Unicode (UTF-16) string handling:
authorsfisher <sfisher@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 3 Jan 2011 18:29:29 +0000 (18:29 +0000)
committersfisher <sfisher@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 3 Jan 2011 18:29:29 +0000 (18:29 +0000)
tvb_get_unicode_string()
tvb_get_ephemeral_unicode_string()

These function like their counterparts, tvb_get_string and
tvb_get_epemeral_string, for standard strings.

Also update comment on what the first such function,
tvb_get_ephemeral_unicode_stringz does regarding updating lengthp.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@35344 f5534014-38df-0310-8fa8-9805f1628bb7

epan/tvbuff.c
epan/tvbuff.h

index d3e31ff9d7e2e17c09a177b045295c70407f081c..7aabb14d62b497073a7d928faab62c37c1f4f38b 100644 (file)
@@ -2254,6 +2254,55 @@ tvb_get_string(tvbuff_t *tvb, const gint offset, const gint length)
        strbuf[length] = '\0';
        return strbuf;
 }
+
+/*
+ * Unicode (UTF-16) version of tvb_get_string()
+ * 
+ * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
+ *
+ * Specify length in bytes
+ * 
+ * Returns an UTF-8 string that must be freed by the caller
+ */
+gchar *
+tvb_get_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
+{
+       gchar *tmpbuf = NULL;
+       gunichar2 uchar;
+       gint i; /* Byte counter for tvbuff */
+       gint tmpbuf_len;
+       GString *strbuf = NULL;
+
+       strbuf = g_string_new(NULL);
+
+       for(i = 0; i < length; i += 2) {
+
+               if(encoding == ENC_BIG_ENDIAN)
+                       uchar = tvb_get_ntohs(tvb, offset + i);
+               else
+                       uchar = tvb_get_letohs(tvb, offset + i);
+
+               /* Calculate how much space is needed to store UTF-16 character
+                * in UTF-8 */
+               tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
+
+               tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
+                                                   * terminator */
+
+               g_unichar_to_utf8(uchar, tmpbuf);
+
+               /* NULL terminate the tmpbuf so g_string_append knows where
+                * to stop */
+               tmpbuf[tmpbuf_len] = '\0';
+
+               g_string_append(strbuf, tmpbuf);
+
+               g_free(tmpbuf);
+       }
+
+       return g_string_free(strbuf, FALSE);
+}
+
 /*
  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
  * to hold a non-null-terminated string of that length at that offset,
@@ -2285,6 +2334,54 @@ tvb_get_ephemeral_string(tvbuff_t *tvb, const gint offset, const gint length)
        return strbuf;
 }
 
+/*
+ * Unicode (UTF-16) version of tvb_get_ephemeral_string()
+ * 
+ * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
+ *
+ * Specify length in bytes
+ * 
+ * Returns an ep_ allocated UTF-8 string
+ */
+gchar *
+tvb_get_ephemeral_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding)
+{
+       gchar *tmpbuf = NULL;
+       gunichar2 uchar;
+       gint i; /* Byte counter for tvbuff */
+       gint tmpbuf_len;
+       emem_strbuf_t *strbuf = NULL;
+
+       strbuf = ep_strbuf_new(NULL);
+
+       for(i = 0; i < length; i += 2) {
+
+               if(encoding == ENC_BIG_ENDIAN)
+                       uchar = tvb_get_ntohs(tvb, offset + i);
+               else
+                       uchar = tvb_get_letohs(tvb, offset + i);
+
+               /* Calculate how much space is needed to store UTF-16 character
+                * in UTF-8 */
+               tmpbuf_len = g_unichar_to_utf8(uchar, NULL);
+
+               tmpbuf = g_malloc(tmpbuf_len + 1); /* + 1 to make room for null
+                                                   * terminator */
+
+               g_unichar_to_utf8(uchar, tmpbuf);
+
+               /* NULL terminate the tmpbuf so ep_strbuf_append knows where
+                * to stop */
+               tmpbuf[tmpbuf_len] = '\0';
+
+               ep_strbuf_append(strbuf, tmpbuf);
+
+               g_free(tmpbuf);
+       }
+
+       return strbuf->str;
+}
+
 /*
  * Given a tvbuff, an offset, and a length, allocate a buffer big enough
  * to hold a non-null-terminated string of that length at that offset,
@@ -2368,7 +2465,7 @@ tvb_get_ephemeral_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp)
  * 
  * Encoding paramter should be ENC_BIG_ENDIAN or ENC_LITTLE_ENDIAN
  *
- * Returns an ep_ allocated UTF-8 string
+ * Returns an ep_ allocated UTF-8 string and updates lengthp pointer with length of string (in bytes)
  */
 gchar *
 tvb_get_ephemeral_unicode_stringz(tvbuff_t *tvb, const gint offset, gint *lengthp, const guint encoding)
index 55a688bc91aabe92bcded832c7ee5d5f7917778f..62189e2228f5c58f7fe6f58bfe344796b8719e31 100644 (file)
@@ -486,16 +486,22 @@ extern gchar *tvb_format_stringzpad_wsp(tvbuff_t *tvb, const gint offset, const
  *                   MUST be g_free() by the caller in order not to leak
  *                   memory.
  *
+ * tvb_get_unicode_string() Unicode (UTF-16) version of above
+ *
  * tvb_get_ephemeral_string() returns a string that does not need to be freed,
  *                   instead it will automatically be freed once the next
  *                   packet is dissected.
  *
+ * tvb_get_ephemeral_unicode_string() Unicode (UTF-16) version of above
+ *
  * tvb_get_seasonal_string() returns a string that does not need to be freed,
  *                   instead it will automatically be freed when a new capture
  *                   or file is opened.
  */
 extern guint8 *tvb_get_string(tvbuff_t *tvb, const gint offset, const gint length);
+extern gchar  *tvb_get_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding);
 extern guint8 *tvb_get_ephemeral_string(tvbuff_t *tvb, const gint offset, const gint length);
+extern gchar  *tvb_get_ephemeral_unicode_string(tvbuff_t *tvb, const gint offset, gint length, const guint encoding);
 extern guint8 *tvb_get_seasonal_string(tvbuff_t *tvb, const gint offset, const gint length);