aboutsummaryrefslogtreecommitdiff
path: root/src/mm-charsets.c
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-01-18 12:28:50 -0600
committerDan Williams <dcbw@redhat.com>2012-01-18 12:28:50 -0600
commit27b981237eff9ef6239609ed040dc8c088e943d8 (patch)
tree1ed29e11b18973bee786be0c70d9d96f5b433a3c /src/mm-charsets.c
parent178f30bdd3111ba645b92ae6511911cc6a9ece4c (diff)
core: fix some bugs in GSM7 packing code
The existing gsm_pack() had a bug where if the last septet should be in an octet by itself, that last octet wouldn't be added. Plus, kinda pointless to use a GByteArray here when we already know what the length will be through simple arithmetic. We can also simplify the function too. Furthermore, there weren't any testcases for starting packing at an offset other than zero, so add one.
Diffstat (limited to 'src/mm-charsets.c')
-rw-r--r--src/mm-charsets.c46
1 files changed, 21 insertions, 25 deletions
diff --git a/src/mm-charsets.c b/src/mm-charsets.c
index 0956e4e1..13976ba2 100644
--- a/src/mm-charsets.c
+++ b/src/mm-charsets.c
@@ -672,37 +672,33 @@ gsm_pack (const guint8 *src,
guint8 start_offset,
guint32 *out_packed_len)
{
- GByteArray *packed;
- guint8 c, add_last = 0;
- int i;
+ guint8 *packed;
+ guint octet = 0, lshift, plen;
+ int i = 0;
- packed = g_byte_array_sized_new (src_len);
+ g_return_val_if_fail (start_offset < 8, NULL);
- for (i = 0, c = 0; i < src_len; i++) {
- guint8 bits_here, offset;
- guint32 start_bit;
+ plen = (src_len * 7) + start_offset; /* total length in bits */
+ if (plen % 8)
+ plen += 8;
+ plen /= 8; /* now in bytes */
- start_bit = start_offset + (i * 7); /* Overall bit offset of char in buffer */
- offset = start_bit % 8; /* Offset to start of char in this byte */
- bits_here = offset ? (8 - offset) : 7;
-
- c |= (src[i] & 0x7F) << offset;
- if (offset) {
- /* Add this packed byte */
- g_byte_array_append (packed, &c, 1);
- c = add_last = 0;
- }
+ packed = g_malloc0 (plen);
- /* Pack the rest of this char into the next byte */
- if (bits_here != 7) {
- c = (src[i] & 0x7F) >> bits_here;
- add_last = 1;
+ for (i = 0, lshift = start_offset; i < src_len; i++) {
+ packed[octet] |= (src[i] & 0x7F) << lshift;
+ if (lshift > 1) {
+ /* Grab the lost bits and add to next octet */
+ g_assert (octet + 1 < plen);
+ packed[octet + 1] = (src[i] & 0x7F) >> (8 - lshift);
}
+ if (lshift)
+ octet++;
+ lshift = lshift ? lshift - 1 : 7;
}
- if (add_last)
- g_byte_array_append (packed, &c, 1);
- *out_packed_len = packed->len;
- return g_byte_array_free (packed, FALSE);
+ if (out_packed_len)
+ *out_packed_len = plen;
+ return packed;
}