@@ -1099,19 +1099,79 @@ function byteSize(buf) {
1099
1099
1100
1100
exports . byteSize = byteSize ;
1101
1101
1102
- function writeBuffer ( highLevel , lowLevel ) {
1102
+ function writeBuffer ( highLevel , highLevelOffset , lowLevel ) {
1103
1103
const elementSize = byteSize ( highLevel ) ;
1104
1104
const isUnsigned = highLevel . $$STable . REPR . type . $$STable . REPR . isUnsigned ;
1105
1105
1106
1106
let offset = 0 ;
1107
1107
for ( let i = 0 ; i < lowLevel . length / elementSize ; i ++ ) {
1108
- highLevel . array [ i ] = isUnsigned ? lowLevel . readUIntLE ( offset , elementSize ) : lowLevel . readIntLE ( offset , elementSize ) ;
1108
+ highLevel . array [ highLevelOffset + i ] = isUnsigned ? lowLevel . readUIntLE ( offset , elementSize ) : lowLevel . readIntLE ( offset , elementSize ) ;
1109
1109
offset += elementSize ;
1110
1110
}
1111
1111
}
1112
1112
1113
1113
exports . writeBuffer = writeBuffer ;
1114
1114
1115
+ const BINARY_ENDIAN_LITTLE = 1 ;
1116
+ const BINARY_ENDIAN_BIG = 2 ;
1117
+
1118
+ const BINARY_ENDIAN_MASK = BINARY_ENDIAN_LITTLE | BINARY_ENDIAN_BIG ;
1119
+
1120
+ const BINARY_SIZE_8_BIT = 0 ;
1121
+ const BINARY_SIZE_16_BIT = 4 ;
1122
+ const BINARY_SIZE_32_BIT = 8 ;
1123
+ const BINARY_SIZE_64_BIT = 12 ;
1124
+
1125
+ const isBigEndian = new Uint8Array ( new Uint32Array ( [ 0x12345678 ] ) . buffer ) [ 0 ] === 0x12 ;
1126
+
1127
+
1128
+ function writeIntToBuffer ( isSigned , buffer , offset , value , flags ) {
1129
+ const endianFlags = flags & BINARY_ENDIAN_MASK ;
1130
+ const sizeFlags = flags & ~ BINARY_ENDIAN_MASK ;
1131
+
1132
+ let sizeInBytes ;
1133
+
1134
+ if ( sizeFlags == BINARY_SIZE_8_BIT ) {
1135
+ sizeInBytes = 1 ;
1136
+ } else if ( sizeFlags == BINARY_SIZE_16_BIT ) {
1137
+ sizeInBytes = 2 ;
1138
+ } else if ( sizeFlags == BINARY_SIZE_32_BIT ) {
1139
+ sizeInBytes = 4 ;
1140
+ } else if ( sizeFlags == BINARY_SIZE_64_BIT ) {
1141
+ throw new NQPException ( '64bit writeint is not supported' ) ;
1142
+ } else {
1143
+ throw new NQPException ( 'unsupported flags: ' + flags ) ;
1144
+ }
1145
+
1146
+ const lowlevelBuffer = Buffer . alloc ( sizeInBytes ) ;
1147
+
1148
+ const shift = 32 - sizeInBytes * 8 ;
1149
+
1150
+ if ( endianFlags === BINARY_ENDIAN_BIG || ( endianFlags == 0 && isBigEndian ) ) {
1151
+ if ( isSigned ) {
1152
+ lowlevelBuffer . writeIntBE ( ( value << shift >> shift ) , 0 , sizeInBytes ) ;
1153
+ } else {
1154
+ lowlevelBuffer . writeUIntBE ( ( value << shift >>> shift ) , 0 , sizeInBytes ) ;
1155
+ }
1156
+ } else if ( endianFlags === BINARY_ENDIAN_LITTLE || ( endianFlags == 0 && ! isBigEndian ) ) {
1157
+ if ( isSigned ) {
1158
+ lowlevelBuffer . writeIntLE ( ( value << shift >> shift ) , 0 , sizeInBytes ) ;
1159
+ } else {
1160
+ lowlevelBuffer . writeUIntLE ( ( value << shift >>> shift ) , 0 , sizeInBytes ) ;
1161
+ }
1162
+ }
1163
+
1164
+ writeBuffer ( buffer , offset , lowlevelBuffer ) ;
1165
+ } ;
1166
+
1167
+ op . writeint = function ( buffer , offset , value , flags ) {
1168
+ writeIntToBuffer ( true , buffer , offset , value , flags ) ;
1169
+ } ;
1170
+
1171
+ op . writeuint = function ( buffer , offset , value , flags ) {
1172
+ writeIntToBuffer ( false , buffer , offset , value , flags ) ;
1173
+ } ;
1174
+
1115
1175
op . encodeconf = function ( str , encoding_ , output , permissive ) {
1116
1176
if ( output . array . length ) {
1117
1177
throw new NQPException ( 'encode requires an empty array' ) ;
@@ -1127,7 +1187,7 @@ op.encodeconf = function(str, encoding_, output, permissive) {
1127
1187
buffer = Buffer . from ( str , encoding ) ;
1128
1188
}
1129
1189
1130
- writeBuffer ( output , buffer ) ;
1190
+ writeBuffer ( output , 0 , buffer ) ;
1131
1191
1132
1192
1133
1193
return output ;
@@ -1152,7 +1212,7 @@ op.encoderepconf = function(str, encoding_, replacement, output, permissive) {
1152
1212
throw new NQPException ( 'encoding unsupported in encoderep' ) ;
1153
1213
}
1154
1214
1155
- writeBuffer ( output , buffer ) ;
1215
+ writeBuffer ( output , 0 , buffer ) ;
1156
1216
1157
1217
return output ;
1158
1218
} ;
0 commit comments