diff options
Diffstat (limited to 'src/lib/eina/eina_intbuf.x')
-rw-r--r-- | src/lib/eina/eina_intbuf.x | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/src/lib/eina/eina_intbuf.x b/src/lib/eina/eina_intbuf.x new file mode 100644 index 0000000000..b68396eaad --- /dev/null +++ b/src/lib/eina/eina_intbuf.x @@ -0,0 +1,84 @@ +static inline Eina_Intbuf *eina_intbuf_new(void) +{ + Eina_Intbuf *buf; + + buf = calloc(1, sizeof (Eina_Intbuf)); + return buf; +} + +static void eina_intbuf_free(Eina_Intbuf *buf) +{ + free(buf->bytes); + free(buf); +} + +static inline void eina_intbuf_push(Eina_Intbuf *buf, int data) +{ + int delta = data - buf->last_data; + unsigned char *tmp; + unsigned char data[5]; + unsigned char idx = 4; + Eina_Bool neg = EINA_FALSE; + + /* detect negative value */ + if (delta < 0) + { + delta *= -1; + neg = EINA_TRUE; + } + + /* Special case for storing negative value and no continuation bit */ + data[idx] = (delta & 0x3F) | (neg ? 0x40 : 0x0); + + /* Update index and delta after storing data */ + delta = delta >> 6; + idx--; + + while (delta) + { + /* Normal case where we store the data with the continuing bit */ + data[idx] = (delta & 0x7F) | 0x80; + + /* Update index and delta after storing data */ + delta = delta >> 7; + idx--; + } + + /* resize bytes buffer and store data at the end of the buffer */ + tmp = realloc(buf->bytes, buf->length + 5 - idx); + if (!tmp) return ; + + buf->bytes = tmp; + memcpy(tmp, data + idx + 1, 5 - idx); + + /* update last data to the last pushed data */ + buf->last_data = data; +} + +static inline inline Eina_Bool eina_intbuf_read(Eina_Intbuf *buf, + unsigned int *buffer_offset, + int *data) +{ + int delta = 0; + + /* end of the buffer ! */ + if (*buffer_offset >= buf->length) + return EINA_FALSE; + + /* as long as we find the continuation bit */ + while (buf->bytes[*buffer_offset] & 0x80) + { + /* we can add those bit to the current delta value */ + delta = (delta << 7) + (buf->bytes[*buffer_offset] & 0x7F); + (*buffer_offset)++; + } + + /* handling the specific case of negative value and end of integer stream */ + delta = (delta << 7) + (buf->bytes[*buffer_offset] & 0x3F); + if (buf->bytes[*buffer_offset] & 0x40) + delta *= -1; + + /* update data by delta value */ + *data += delta; + return EINA_TRUE; +} |