Skip to content

Commit

Permalink
FEAT: new BINCODE's read functions: SB (signed bits) and ALIGN (align…
Browse files Browse the repository at this point in the history
…s bit stream to byte)
  • Loading branch information
Oldes committed Dec 14, 2018
1 parent c821763 commit 035df2a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 13 deletions.
69 changes: 56 additions & 13 deletions src/core/u-bincode.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@
#define ASSERT_READ_SIZE(v, p, e, n) if((p + n) > e) Trap1(RE_OUT_OF_RANGE, v);
#define ASSERT_INDEX_RANGE(v, p, e) if(i < 0 || i > VAL_TAIL(v)) Trap1(RE_OUT_OF_RANGE, e);

#define IS_BIT_SET(v, b) ((v & b) == b)
#define NEXT_IN_BIT(inBit) \
do { \
inBit = inBit >> 1; \
if (inBit == 0) { \
inBit = 0x80; \
ASSERT_READ_SIZE(value, cp, ep, 1); \
cp++; \
VAL_INDEX(buffer_read)++; \
} \
} while (0)
#define STORE_IN_BIT(val, inBit) SET_INT32(VAL_OBJ_VALUE(val, BINCODE_READ_BITMASK), inBit);

//**********************************************************************
//MUST be in order like the values in system/standard/bincode object bellow!!!
enum BincodeContextValues {
Expand Down Expand Up @@ -136,7 +149,7 @@ system/standard/bincode: make object! [
REBSER *obj;
REBVAL *buffer_write;
REBVAL *buffer_read;
REBCNT inBit;
REBCNT inBit, nbits;
REBYTE *cp, *bp, *ep;
REBCNT n, count, index, tail, tail_new;
i32 i, len;
Expand Down Expand Up @@ -690,7 +703,7 @@ system/standard/bincode: make object! [
DS_DROP; // remove temp
}

if (ref_read) {
if (ref_read) {
//printf("\nREADING... in-index: %i\n\n", VAL_INDEX(buffer_read));

cp = BIN_DATA(bin) + VAL_INDEX(buffer_read);
Expand Down Expand Up @@ -873,23 +886,43 @@ system/standard/bincode: make object! [
i = 0;
if (inBit == 0) inBit = 0x80;
// could be optimized?
REBCNT nbits = VAL_INT32(next);
//printf("bits: %i\n", nbits);
nbits = VAL_INT32(next);
//printf("bits: %i %i\n", nbits, 1 << nbits);
nbits = 1 << nbits;
ASSERT_READ_SIZE(value, cp, ep, 1);
while(nbits > 1) {
nbits = nbits >> 1;
if((cp[0] & inBit) == inBit){
i = i | nbits;
}
if(IS_BIT_SET(cp[0], inBit)) i = i | nbits;
//printf("?? %i %i\n", inBit, i);
inBit = inBit >> 1;
if (inBit == 0) {
inBit = 0x80;
ASSERT_READ_SIZE(value, cp, ep, 1);
cp++;
VAL_INDEX(buffer_read)++;
NEXT_IN_BIT(inBit);
//printf("inBit: %i\n", inBit);
}
VAL_SET(temp, REB_INTEGER);
SET_INT32(temp, i);
STORE_IN_BIT(val_ctx, inBit);
break;
case SYM_SB:
next = ++value;
if (IS_GET_WORD(next)) next = Get_Var(next);
if (!IS_INTEGER(next)) Trap1(RE_INVALID_SPEC, value);
i = 0;
if (inBit == 0) inBit = 0x80;
// could be optimized?
nbits = VAL_INT32(next);
nbits = 1 << nbits;
if (nbits > 0) {
//printf("nbits: %i\n", nbits);
ASSERT_READ_SIZE(value, cp, ep, 1);
BOOL negative = IS_BIT_SET(cp[0], inBit);
nbits = nbits >> 1;
NEXT_IN_BIT(inBit);
while (nbits > 1) {
nbits = nbits >> 1;
if (IS_BIT_SET(cp[0], inBit)) i = i | nbits;
//printf("?? %i %i\n", inBit, i);
NEXT_IN_BIT(inBit);
}
if(negative) i = -i;
}
VAL_SET(temp, REB_INTEGER);
SET_INT32(temp, i);
Expand All @@ -907,7 +940,17 @@ system/standard/bincode: make object! [
}
inBit = inBit >> 1;
if(inBit == 0) n++;
STORE_IN_BIT(val_ctx, inBit);
break;
case SYM_ALIGN:
// aligns bit buffer to byte boundary
if (inBit > 0) {
inBit = 0;
cp++;
VAL_INDEX(buffer_read)++;
STORE_IN_BIT(val_ctx, inBit);
}
continue;
case SYM_UI16LE:
n = 2;
ASSERT_READ_SIZE(value, cp, ep, n);
Expand Down
13 changes: 13 additions & 0 deletions src/tests/units/bincode-test.r3
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ is-protected-error?: func[code][
--assert object? binary/init b none ; just clear existing bincode
--assert empty? b/buffer
--assert empty? b/buffer-write

===end-group===

===start-group=== "BinCode basic read/write functions"

--test-- "BinCode - write positive unsigned integers (big endian)"
b: binary 64
--assert object? binary/write b [ui64 1 ui32 1 ui24 1 ui16 1 ui8 1]
Expand Down Expand Up @@ -221,6 +226,14 @@ is-protected-error?: func[code][
--assert str = "test"
--assert i = 42

--test-- "BinCode - bits (SB, UB, ALIGN)"
b: binary 2#{01011011 10110011 11111111}
--assert [2 -2 3 -3 255] = binary/read b [SB 3 SB 3 UB 2 SB 4 ALIGN UI8]

===end-group===



probe

~~~end-file~~~

0 comments on commit 035df2a

Please sign in to comment.