aboutsummaryrefslogtreecommitdiffstats
path: root/lib/erl_interface/src/decode/decode_binary.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/erl_interface/src/decode/decode_binary.c')
-rw-r--r--lib/erl_interface/src/decode/decode_binary.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/erl_interface/src/decode/decode_binary.c b/lib/erl_interface/src/decode/decode_binary.c
index 5b8d234984..0d28c67230 100644
--- a/lib/erl_interface/src/decode/decode_binary.c
+++ b/lib/erl_interface/src/decode/decode_binary.c
@@ -40,4 +40,41 @@ int ei_decode_binary(const char *buf, int *index, void *p, long *lenp)
return 0;
}
+int ei_decode_bitstring(const char *buf, int *index,
+ const char** pp,
+ unsigned int* bitoffsp,
+ size_t *nbitsp)
+{
+ const char *s = buf + *index;
+ const char *s0 = s;
+ unsigned char last_bits;
+ const unsigned char tag = get8(s);
+ size_t len = get32be(s);
+
+ switch(tag) {
+ case ERL_BINARY_EXT:
+ if (nbitsp)
+ *nbitsp = len * 8;
+ break;
+ case ERL_BIT_BINARY_EXT:
+ last_bits = get8(s);
+ if (((last_bits==0) != (len==0)) || last_bits > 8)
+ return -1;
+
+ if (nbitsp)
+ *nbitsp = (len == 0) ? 0 : ((len-1) * 8) + last_bits;
+ break;
+ default:
+ return -1;
+ }
+
+ if (pp)
+ *pp = s;
+ if (bitoffsp)
+ *bitoffsp = 0;
+
+ s += len;
+ *index += s-s0;
+ return 0;
+}