summaryrefslogtreecommitdiff
path: root/src/lib/eina/eina_intbuf.x
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/eina/eina_intbuf.x')
-rw-r--r--src/lib/eina/eina_intbuf.x84
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;
+}