@@ -114,6 +114,17 @@ system/standard/bincode: make object! [
114
114
]
115
115
116
116
***********************************************************************/
117
+
118
+ static REBCNT EncodedU32_Size (u32 value ) {
119
+ REBCNT count = 0 ;
120
+ if (value == 0 ) return 1 ;
121
+ else while (value > 0 ) {
122
+ value = value >> 7 ;
123
+ count ++ ;
124
+ }
125
+ return count ;
126
+ }
127
+
117
128
/***********************************************************************
118
129
**
119
130
*/ REBNATIVE (binary )
@@ -153,7 +164,8 @@ system/standard/bincode: make object! [
153
164
REBYTE * cp , * bp , * ep ;
154
165
REBCNT n , count , index , tail , tail_new ;
155
166
i32 i , len ;
156
- //u64 u;
167
+ u64 u ;
168
+ u32 ulong ;
157
169
158
170
REBVAL * value , * next ;
159
171
REBVAL * data ;
@@ -408,6 +420,14 @@ system/standard/bincode: make object! [
408
420
continue ;
409
421
}
410
422
goto error ;
423
+
424
+ case SYM_ENCODEDU32 :
425
+ if (IS_INTEGER (next )) {
426
+ count += EncodedU32_Size (VAL_INT64 (next ));
427
+ continue ;
428
+ }
429
+ goto error ;
430
+
411
431
case SYM_UNIXTIME_NOW :
412
432
case SYM_UNIXTIME_NOW_LE :
413
433
value -- ; //there is no argument so no next
@@ -654,6 +674,22 @@ system/standard/bincode: make object! [
654
674
cp = BIN_DATA (bin ) + VAL_INDEX (buffer_write );
655
675
n = 0 ;
656
676
break ;
677
+
678
+ case SYM_ENCODEDU32 :
679
+ ASSERT_U32_RANGE (next );
680
+ ulong = (u32 )VAL_INT64 (next );
681
+ if (ulong == 0 ) {
682
+ n = 1 ;
683
+ cp [0 ] = 0 ;
684
+ } else {
685
+ n = EncodedU32_Size (VAL_INT64 (next ));
686
+ for (u = 0 ; u < n - 1 ; u ++ ) {
687
+ cp [u ] = (char )(128 + ((ulong >> (u * 7 )) & 127 ));
688
+ }
689
+ cp [n - 1 ] = (char )((ulong >> ((n - 1 ) * 7 )) & 255 );
690
+ }
691
+ break ;
692
+
657
693
case SYM_UNIXTIME_NOW :
658
694
value -- ; // no args
659
695
n = 4 ;
@@ -879,6 +915,38 @@ system/standard/bincode: make object! [
879
915
}
880
916
n ++ ;
881
917
break ;
918
+ case SYM_ENCODEDU32 :
919
+ ASSERT_READ_SIZE (value , cp , ep , 1 );
920
+ u = (u64 )cp [0 ];
921
+ if (!(u & 0x00000080 )) {
922
+ n = 1 ;
923
+ goto setEnU32Result ;
924
+ }
925
+ ASSERT_READ_SIZE (value , cp , ep , 2 );
926
+ u = (u & 0x0000007f ) | cp [1 ] << 7 ;
927
+ if (!(u & 0x00004000 )) {
928
+ n = 2 ;
929
+ goto setEnU32Result ;
930
+ }
931
+ ASSERT_READ_SIZE (value , cp , ep , 3 );
932
+ u = (u & 0x00003fff ) | cp [2 ] << 14 ;
933
+ if (!(u & 0x00200000 )) {
934
+ n = 3 ;
935
+ goto setEnU32Result ;
936
+ }
937
+ ASSERT_READ_SIZE (value , cp , ep , 4 );
938
+ u = (u & 0x001fffff ) | cp [3 ] << 21 ;
939
+ if (!(u & 0x10000000 )) {
940
+ n = 4 ;
941
+ goto setEnU32Result ;
942
+ }
943
+ ASSERT_READ_SIZE (value , cp , ep , 5 );
944
+ u = (u & 0x0fffffff ) | cp [4 ] << 28 ;
945
+ n = 5 ;
946
+ setEnU32Result :
947
+ VAL_SET (temp , REB_INTEGER );
948
+ VAL_UNT64 (temp ) = u & 0xffffffff ; // limits result to 32 bit unsigned integer!
949
+ break ;
882
950
case SYM_UB :
883
951
next = ++ value ;
884
952
if (IS_GET_WORD (next )) next = Get_Var (next );
0 commit comments