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; }