Add reading/writing of C integers to buffers

This commit is contained in:
Robert Mustacchi 2011-05-01 11:38:10 -07:00 committed by Ryan Dahl
parent 8a03cf7a7b
commit 9812e31e8b
6 changed files with 1043 additions and 3 deletions

View File

@ -168,3 +168,198 @@ from the original Buffer.
// abc
// !bc
### buffer.readUInt8(offset, endian)
Reads an unsigned 8 bit integer from the buffer at the specified offset. Endian
must be either 'big' or 'little' and specifies what endian ordering to read the
bytes from the buffer in.
Example:
var buf = new Buffer(4);
buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;
for (ii = 0; ii < buf.length; ii++) {
console.log(buf.readUInt8(ii, 'big');
console.log(buf.readUInt8(ii, 'little');
}
// 0x3
// 0x3
// 0x4
// 0x4
// 0x23
// 0x23
// 0x42
// 0x42
### buffer.readUInt16(offset, endian)
Reads an unsigned 16 bit integer from the buffer at the specified offset. Endian
must be either 'big' or 'little' and specifies what endian ordering to read the
bytes from the buffer in.
Example:
var buf = new Buffer(4);
buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;
console.log(buf.readUInt16(0, 'big');
console.log(buf.readUInt16(0, 'little');
console.log(buf.readUInt16(1, 'big');
console.log(buf.readUInt16(1, 'little');
console.log(buf.readUInt16(2, 'big');
console.log(buf.readUInt16(2, 'little');
// 0x0304
// 0x0403
// 0x0423
// 0x2304
// 0x2342
// 0x4223
### buffer.readUInt32(offset, endian)
Reads an unsigned 32 bit integer from the buffer at the specified offset. Endian
must be either 'big' or 'little' and specifies what endian ordering to read the
bytes from the buffer in.
Example:
var buf = new Buffer(4);
buf[0] = 0x3;
buf[1] = 0x4;
buf[2] = 0x23;
buf[3] = 0x42;
console.log(buf.readUInt32(0, 'big');
console.log(buf.readUInt32(0, 'little');
// 0x03042342
// 0x42230403
### buffer.readInt8(offset, endian)
Reads a signed 8 bit integer from the buffer at the specified offset. Endian
must be either 'big' or 'little' and specifies what endian ordering to read the
bytes from the buffer in.
Works as `buffer.readUInt8`, except buffer contents are treated as twos
complement signed values.
### buffer.readInt16(offset, endian)
Reads a signed 16 bit integer from the buffer at the specified offset. Endian
must be either 'big' or 'little' and specifies what endian ordering to read the
bytes from the buffer in.
Works as `buffer.readUInt16`, except buffer contents are treated as twos
complement signed values.
### buffer.readInt32(offset, endian)
Reads a signed 32 bit integer from the buffer at the specified offset. Endian
must be either 'big' or 'little' and specifies what endian ordering to read the
bytes from the buffer in.
Works as `buffer.readUInt32`, except buffer contents are treated as twos
complement signed values.
### buffer.writeUInt8(value, offset, endian)
Writes `value` to the buffer at the specified offset with specified endian
format. Note, `value` must be a valid 8 bit unsigned integer.
Example:
var buf = new Buffer(4);
buf.writeUInt8(0x3, 0, 'big');
buf.writeUInt8(0x4, 1, 'big');
buf.writeUInt8(0x23, 2, 'big');
buf.writeUInt8(0x42, 3, 'big');
console.log(buf);
buf.writeUInt8(0x3, 0, 'little');
buf.writeUInt8(0x4, 1, 'little');
buf.writeUInt8(0x23, 2, 'little');
buf.writeUInt8(0x42, 3, 'little');
console.log(buf);
// <Buffer 03 04 23 42>
// <Buffer 03 04 23 42>
### buffer.writeUInt16(value, offset, endian)
Writes `value` to the buffer at the specified offset with specified endian
format. Note, `value` must be a valid 16 bit unsigned integer.
Example:
var buf = new Buffer(4);
buf.writeUInt16(0xdead, 0, 'big');
buf.writeUInt16(0xbeef, 2, 'big');
console.log(buf);
buf.writeUInt16(0xdead, 0, 'little');
buf.writeUInt16(0xbeef, 2, 'little');
console.log(buf);
// <Buffer de ad be ef>
// <Buffer ad de ef be>
### buffer.writeUInt32(value, offset, endian)
Writes `value` to the buffer at the specified offset with specified endian
format. Note, `value` must be a valid 32 bit unsigned integer.
Example:
var buf = new Buffer(4);
buf.writeUInt32(0xfeedface, 0, 'big');
console.log(buf);
buf.writeUInt32(0xfeedface, 0, 'little');
console.log(buf);
// <Buffer fe ed fa ce>
// <Buffer ce fa ed fe>
### buffer.writeInt8(value, offset, endian)
Writes `value` to the buffer at the specified offset with specified endian
format. Note, `value` must be a valid 16 bit signed integer.
Works as `buffer.writeUInt8`, except value is written out as a two's complement
signed integer into `buffer`.
### buffer.writeInt16(value, offset, endian)
Writes `value` to the buffer at the specified offset with specified endian
format. Note, `value` must be a valid 16 bit unsigned integer.
Works as `buffer.writeUInt16`, except value is written out as a two's complement
signed integer into `buffer`.
### buffer.writeInt32(value, offset, endian)
Writes `value` to the buffer at the specified offset with specified endian
format. Note, `value` must be a valid 16 bit signed integer.
Works as `buffer.writeUInt832, except value is written out as a two's complement
signed integer into `buffer`.

View File

@ -20,6 +20,7 @@
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var SlowBuffer = process.binding('buffer').SlowBuffer;
var assert = require('assert');
function toHex(n) {
@ -45,7 +46,7 @@ SlowBuffer.prototype.hexSlice = function(start, end) {
if (!end || end < 0 || end > len) end = len;
var out = '';
for (var i = start; i < end; i ++) {
for (var i = start; i < end; i++) {
out += toHex(this[i]);
}
return out;
@ -98,13 +99,13 @@ SlowBuffer.prototype.hexWrite = function(string, offset) {
if (len % 2) {
throw new Error('Invalid hex string');
}
for (var i = 0; i < len / 2; i ++) {
for (var i = 0; i < len / 2; i++) {
var byte = parseInt(string.substr(i * 2, 2), 16);
if (isNaN(byte)) throw new Error('Invalid hex string');
this[offset + i] = byte;
}
return i;
}
};
SlowBuffer.prototype.write = function(string, offset, encoding) {
@ -449,3 +450,444 @@ Buffer.prototype.asciiWrite = function(string, offset) {
return this.write(string, offset, 'ascii');
};
Buffer.prototype.readUInt8 = function(offset, endian) {
var buffer = this;
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset < buffer.length,
'Trying to read beyond buffer length');
return buffer[offset];
};
Buffer.prototype.readUInt16 = function(offset, endian) {
var val = 0;
var buffer = this;
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 1 < buffer.length,
'Trying to read beyond buffer length');
if (endian == 'big') {
val = buffer[offset] << 8;
val |= buffer[offset + 1];
} else {
val = buffer[offset];
val |= buffer[offset + 1] << 8;
}
return val;
};
Buffer.prototype.readUInt32 = function(offset, endian) {
var val = 0;
var buffer = this;
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 3 < buffer.length,
'Trying to read beyond buffer length');
if (endian == 'big') {
val = buffer[offset + 1] << 16;
val |= buffer[offset + 2] << 8;
val |= buffer[offset + 3];
val = val + (buffer[offset] << 24 >>> 0);
} else {
val = buffer[offset + 2] << 16;
val |= buffer[offset + 1] << 8;
val |= buffer[offset];
val = val + (buffer[offset + 3] << 24 >>> 0);
}
return val;
};
/*
* Signed integer types, yay team! A reminder on how two's complement actually
* works. The first bit is the signed bit, i.e. tells us whether or not the
* number should be positive or negative. If the two's complement value is
* positive, then we're done, as it's equivalent to the unsigned representation.
*
* Now if the number is positive, you're pretty much done, you can just leverage
* the unsigned translations and return those. Unfortunately, negative numbers
* aren't quite that straightforward.
*
* At first glance, one might be inclined to use the traditional formula to
* translate binary numbers between the positive and negative values in two's
* complement. (Though it doesn't quite work for the most negative value)
* Mainly:
* - invert all the bits
* - add one to the result
*
* Of course, this doesn't quite work in Javascript. Take for example the value
* of -128. This could be represented in 16 bits (big-endian) as 0xff80. But of
* course, Javascript will do the following:
*
* > ~0xff80
* -65409
*
* Whoh there, Javascript, that's not quite right. But wait, according to
* Javascript that's perfectly correct. When Javascript ends up seeing the
* constant 0xff80, it has no notion that it is actually a signed number. It
* assumes that we've input the unsigned value 0xff80. Thus, when it does the
* binary negation, it casts it into a signed value, (positive 0xff80). Then
* when you perform binary negation on that, it turns it into a negative number.
*
* Instead, we're going to have to use the following general formula, that works
* in a rather Javascript friendly way. I'm glad we don't support this kind of
* weird numbering scheme in the kernel.
*
* (BIT-MAX - (unsigned)val + 1) * -1
*
* The astute observer, may think that this doesn't make sense for 8-bit numbers
* (really it isn't necessary for them). However, when you get 16-bit numbers,
* you do. Let's go back to our prior example and see how this will look:
*
* (0xffff - 0xff80 + 1) * -1
* (0x007f + 1) * -1
* (0x0080) * -1
*/
Buffer.prototype.readInt8 = function(offset, endian) {
var buffer = this;
var neg;
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset < buffer.length,
'Trying to read beyond buffer length');
neg = buffer[offset] & 0x80;
if (!neg) {
return (buffer[offset]);
}
return ((0xff - buffer[offset] + 1) * -1);
};
Buffer.prototype.readInt16 = function(offset, endian) {
var buffer = this;
var neg;
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 1 < buffer.length,
'Trying to read beyond buffer length');
val = buffer.readUInt16(offset, endian);
neg = val & 0x8000;
if (!neg) {
return val;
}
return (0xffff - val + 1) * -1;
};
Buffer.prototype.readInt32 = function(offset, endian) {
var buffer = this;
var neg;
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 3 < buffer.length,
'Trying to read beyond buffer length');
val = buffer.readUInt32(offset, endian);
neg = val & 0x80000000;
if (!neg) {
return (val);
}
return (0xffffffff - val + 1) * -1;
};
/*
* We have to make sure that the value is a valid integer. This means that it is
* non-negative. It has no fractional component and that it does not exceed the
* maximum allowed value.
*
* value The number to check for validity
*
* max The maximum value
*/
function verifuint(value, max) {
assert.ok(typeof (value) == 'number',
'cannot write a non-number as a number');
assert.ok(value >= 0,
'specified a negative value for writing an unsigned value');
assert.ok(value <= max, 'value is larger than maximum value for type');
assert.ok(Math.floor(value) === value, 'value has a fractional component');
}
Buffer.prototype.writeUInt8 = function(value, offset, endian) {
var buffer = this;
assert.ok(value !== undefined && value !== null,
'missing value');
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset < buffer.length,
'trying to read beyond buffer length');
verifuint(value, 0xff);
buffer[offset] = value;
};
Buffer.prototype.writeUInt16 = function(value, offset, endian) {
var buffer = this;
assert.ok(value !== undefined && value !== null,
'missing value');
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 1 < buffer.length,
'trying to read beyond buffer length');
verifuint(value, 0xffff);
if (endian == 'big') {
buffer[offset] = (value & 0xff00) >>> 8;
buffer[offset + 1] = value & 0x00ff;
} else {
buffer[offset + 1] = (value & 0xff00) >>> 8;
buffer[offset] = value & 0x00ff;
}
};
Buffer.prototype.writeUInt32 = function(value, offset, endian) {
var buffer = this;
assert.ok(value !== undefined && value !== null,
'missing value');
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 3 < buffer.length,
'trying to read beyond buffer length');
verifuint(value, 0xffffffff);
if (endian == 'big') {
buffer[offset] = (value >>> 24) & 0xff;
buffer[offset + 1] = (value >>> 16) & 0xff;
buffer[offset + 2] = (value >>> 8) & 0xff;
buffer[offset + 3] = value & 0xff;
} else {
buffer[offset + 3] = (value >>> 24) & 0xff;
buffer[offset + 2] = (value >>> 16) & 0xff;
buffer[offset + 1] = (value >>> 8) & 0xff;
buffer[offset] = value & 0xff;
}
};
/*
* We now move onto our friends in the signed number category. Unlike unsigned
* numbers, we're going to have to worry a bit more about how we put values into
* arrays. Since we are only worrying about signed 32-bit values, we're in
* slightly better shape. Unfortunately, we really can't do our favorite binary
* & in this system. It really seems to do the wrong thing. For example:
*
* > -32 & 0xff
* 224
*
* What's happening above is really: 0xe0 & 0xff = 0xe0. However, the results of
* this aren't treated as a signed number. Ultimately a bad thing.
*
* What we're going to want to do is basically create the unsigned equivalent of
* our representation and pass that off to the wuint* functions. To do that
* we're going to do the following:
*
* - if the value is positive
* we can pass it directly off to the equivalent wuint
* - if the value is negative
* we do the following computation:
* mb + val + 1, where
* mb is the maximum unsigned value in that byte size
* val is the Javascript negative integer
*
*
* As a concrete value, take -128. In signed 16 bits this would be 0xff80. If
* you do out the computations:
*
* 0xffff - 128 + 1
* 0xffff - 127
* 0xff80
*
* You can then encode this value as the signed version. This is really rather
* hacky, but it should work and get the job done which is our goal here.
*/
/*
* A series of checks to make sure we actually have a signed 32-bit number
*/
function verifsint(value, max, min) {
assert.ok(typeof (value) == 'number',
'cannot write a non-number as a number');
assert.ok(value <= max, 'value larger than maximum allowed value');
assert.ok(value >= min, 'value smaller than minimum allowed value');
assert.ok(Math.floor(value) === value, 'value has a fractional component');
}
Buffer.prototype.writeInt8 = function(value, offset, endian) {
var buffer = this;
assert.ok(value !== undefined && value !== null,
'missing value');
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset < buffer.length,
'Trying to read beyond buffer length');
verifsint(value, 0x7f, -0xf0);
if (value >= 0) {
buffer.writeUInt8(value, offset, endian);
} else {
buffer.writeUInt8(0xff + value + 1, offset, endian);
}
};
Buffer.prototype.writeInt16 = function(value, offset, endian) {
var buffer = this;
assert.ok(value !== undefined && value !== null,
'missing value');
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 1 < buffer.length,
'Trying to read beyond buffer length');
verifsint(value, 0x7fff, -0xf000);
if (value >= 0) {
buffer.writeUInt16(value, offset, endian);
} else {
buffer.writeUInt16(0xffff + value + 1, offset, endian);
}
};
Buffer.prototype.writeInt32 = function(value, offset, endian) {
var buffer = this;
assert.ok(value !== undefined && value !== null,
'missing value');
assert.ok(endian !== undefined && endian !== null,
'missing endian');
assert.ok(endian == 'big' || endian == 'little',
'bad endian value');
assert.ok(offset !== undefined && offset !== null,
'missing offset');
assert.ok(offset + 3 < buffer.length,
'Trying to read beyond buffer length');
verifsint(value, 0x7fffffff, -0xf0000000);
if (value >= 0) {
buffer.writeUInt32(value, offset, endian);
} else {
buffer.writeUInt32(0xffffffff + value + 1, offset, endian);
}
};

100
test/simple/test-readint.js Normal file
View File

@ -0,0 +1,100 @@
/*
* Tests to verify we're reading in signed integers correctly
*/
var ASSERT = require('assert');
/*
* Test 8 bit signed integers
*/
function test8() {
var data = new Buffer(4);
data[0] = 0x23;
ASSERT.equal(0x23, data.readInt8(0, 'big'));
ASSERT.equal(0x23, data.readInt8(0, 'little'));
data[0] = 0xff;
ASSERT.equal(-1, data.readInt8(0, 'big'));
ASSERT.equal(-1, data.readInt8(0, 'little'));
data[0] = 0x87;
data[1] = 0xab;
data[2] = 0x7c;
data[3] = 0xef;
ASSERT.equal(-121, data.readInt8(0, 'big'));
ASSERT.equal(-85, data.readInt8(1, 'big'));
ASSERT.equal(124, data.readInt8(2, 'big'));
ASSERT.equal(-17, data.readInt8(3, 'big'));
ASSERT.equal(-121, data.readInt8(0, 'little'));
ASSERT.equal(-85, data.readInt8(1, 'little'));
ASSERT.equal(124, data.readInt8(2, 'little'));
ASSERT.equal(-17, data.readInt8(3, 'little'));
}
function test16() {
var buffer = new Buffer(6);
buffer[0] = 0x16;
buffer[1] = 0x79;
ASSERT.equal(0x1679, buffer.readInt16(0, 'big'));
ASSERT.equal(0x7916, buffer.readInt16(0, 'little'));
buffer[0] = 0xff;
buffer[1] = 0x80;
ASSERT.equal(-128, buffer.readInt16(0, 'big'));
ASSERT.equal(-32513, buffer.readInt16(0, 'little'));
/* test offset with weenix */
buffer[0] = 0x77;
buffer[1] = 0x65;
buffer[2] = 0x65;
buffer[3] = 0x6e;
buffer[4] = 0x69;
buffer[5] = 0x78;
ASSERT.equal(0x7765, buffer.readInt16(0, 'big'));
ASSERT.equal(0x6565, buffer.readInt16(1, 'big'));
ASSERT.equal(0x656e, buffer.readInt16(2, 'big'));
ASSERT.equal(0x6e69, buffer.readInt16(3, 'big'));
ASSERT.equal(0x6978, buffer.readInt16(4, 'big'));
ASSERT.equal(0x6577, buffer.readInt16(0, 'little'));
ASSERT.equal(0x6565, buffer.readInt16(1, 'little'));
ASSERT.equal(0x6e65, buffer.readInt16(2, 'little'));
ASSERT.equal(0x696e, buffer.readInt16(3, 'little'));
ASSERT.equal(0x7869, buffer.readInt16(4, 'little'));
}
function test32() {
var buffer = new Buffer(6);
buffer[0] = 0x43;
buffer[1] = 0x53;
buffer[2] = 0x16;
buffer[3] = 0x79;
ASSERT.equal(0x43531679, buffer.readInt32(0, 'big'));
ASSERT.equal(0x79165343, buffer.readInt32(0, 'little'));
buffer[0] = 0xff;
buffer[1] = 0xfe;
buffer[2] = 0xef;
buffer[3] = 0xfa;
ASSERT.equal(-69638, buffer.readInt32(0, 'big'));
ASSERT.equal(-84934913, buffer.readInt32(0, 'little'));
buffer[0] = 0x42;
buffer[1] = 0xc3;
buffer[2] = 0x95;
buffer[3] = 0xa9;
buffer[4] = 0x36;
buffer[5] = 0x17;
ASSERT.equal(0x42c395a9, buffer.readInt32(0, 'big'));
ASSERT.equal(-1013601994, buffer.readInt32(1, 'big'));
ASSERT.equal(-1784072681, buffer.readInt32(2, 'big'));
ASSERT.equal(-1449802942, buffer.readInt32(0, 'little'));
ASSERT.equal(917083587, buffer.readInt32(1, 'little'));
ASSERT.equal(389458325, buffer.readInt32(2, 'little'));
}
test8();
test16();
test32();

View File

@ -0,0 +1,94 @@
/*
* A battery of tests to help us read a series of uints
*/
var ASSERT = require('assert');
/*
* We need to check the following things:
* - We are correctly resolving big endian (doesn't mean anything for 8 bit)
* - Correctly resolving little endian (doesn't mean anything for 8 bit)
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
function test8() {
var data = new Buffer(4);
data[0] = 23;
data[1] = 23;
data[2] = 23;
data[3] = 23;
ASSERT.equal(23, data.readUInt8(0, 'big'));
ASSERT.equal(23, data.readUInt8(0, 'little'));
ASSERT.equal(23, data.readUInt8(1, 'big'));
ASSERT.equal(23, data.readUInt8(1, 'little'));
ASSERT.equal(23, data.readUInt8(2, 'big'));
ASSERT.equal(23, data.readUInt8(2, 'little'));
ASSERT.equal(23, data.readUInt8(3, 'big'));
ASSERT.equal(23, data.readUInt8(3, 'little'));
data[0] = 255; /* If it became a signed int, would be -1 */
ASSERT.equal(255, data.readUInt8(0, 'big'));
ASSERT.equal(255, data.readUInt8(0, 'little'));
}
/*
* Test 16 bit unsigned integers. We need to verify the same set as 8 bit, only
* now some of the issues actually matter:
* - We are correctly resolving big endian
* - Correctly resolving little endian
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
function test16() {
var data = new Buffer(4);
data[0] = 0;
data[1] = 0x23;
data[2] = 0x42;
data[3] = 0x3f;
ASSERT.equal(0x23, data.readUInt16(0, 'big'));
ASSERT.equal(0x2342, data.readUInt16(1, 'big'));
ASSERT.equal(0x423f, data.readUInt16(2, 'big'));
ASSERT.equal(0x2300, data.readUInt16(0, 'little'));
ASSERT.equal(0x4223, data.readUInt16(1, 'little'));
ASSERT.equal(0x3f42, data.readUInt16(2, 'little'));
data[0] = 0xfe;
data[1] = 0xfe;
ASSERT.equal(0xfefe, data.readUInt16(0, 'big'));
ASSERT.equal(0xfefe, data.readUInt16(0, 'little'));
}
/*
* Test 32 bit unsigned integers. We need to verify the same set as 8 bit, only
* now some of the issues actually matter:
* - We are correctly resolving big endian
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
function test32() {
var data = new Buffer(8);
data[0] = 0x32;
data[1] = 0x65;
data[2] = 0x42;
data[3] = 0x56;
data[4] = 0x23;
data[5] = 0xff;
ASSERT.equal(0x32654256, data.readUInt32(0, 'big'));
ASSERT.equal(0x65425623, data.readUInt32(1, 'big'));
ASSERT.equal(0x425623ff, data.readUInt32(2, 'big'));
ASSERT.equal(0x56426532, data.readUInt32(0, 'little'));
ASSERT.equal(0x23564265, data.readUInt32(1, 'little'));
ASSERT.equal(0xff235642, data.readUInt32(2, 'little'));
}
test8();
test16();
test32();

View File

@ -0,0 +1,91 @@
/*
* Tests to verify we're writing signed integers correctly
*/
var ASSERT = require('assert');
function test8() {
var buffer = new Buffer(4);
buffer.writeInt8(0x23, 0, 'big');
buffer.writeInt8(0x23, 1, 'little');
buffer.writeInt8(-5, 2, 'big');
buffer.writeInt8(-5, 3, 'little');
ASSERT.equal(0x23, buffer[0]);
ASSERT.equal(0x23, buffer[1]);
ASSERT.equal(0xfb, buffer[2]);
ASSERT.equal(0xfb, buffer[3]);
/* Make sure we handle truncation correctly */
ASSERT.throws(function() {
buffer.writeInt8(0xabc, 0, 'big');
});
ASSERT.throws(function() {
buffer.writeInt8(0xabc, 0, 'little');
});
}
function test16() {
var buffer = new Buffer(6);
buffer.writeInt16(0x0023, 0, 'big');
buffer.writeInt16(0x0023, 2, 'little');
ASSERT.equal(0x00, buffer[0]);
ASSERT.equal(0x23, buffer[1]);
ASSERT.equal(0x23, buffer[2]);
ASSERT.equal(0x00, buffer[3]);
buffer.writeInt16(-5, 0, 'big');
buffer.writeInt16(-5, 2, 'little');
ASSERT.equal(0xff, buffer[0]);
ASSERT.equal(0xfb, buffer[1]);
ASSERT.equal(0xfb, buffer[2]);
ASSERT.equal(0xff, buffer[3]);
buffer.writeInt16(-1679, 1, 'big');
buffer.writeInt16(-1679, 3, 'little');
ASSERT.equal(0xf9, buffer[1]);
ASSERT.equal(0x71, buffer[2]);
ASSERT.equal(0x71, buffer[3]);
ASSERT.equal(0xf9, buffer[4]);
}
function test32() {
var buffer = new Buffer(8);
buffer.writeInt32(0x23, 0, 'big');
buffer.writeInt32(0x23, 4, 'little');
ASSERT.equal(0x00, buffer[0]);
ASSERT.equal(0x00, buffer[1]);
ASSERT.equal(0x00, buffer[2]);
ASSERT.equal(0x23, buffer[3]);
ASSERT.equal(0x23, buffer[4]);
ASSERT.equal(0x00, buffer[5]);
ASSERT.equal(0x00, buffer[6]);
ASSERT.equal(0x00, buffer[7]);
buffer.writeInt32(-5, 0, 'big');
buffer.writeInt32(-5, 4, 'little');
ASSERT.equal(0xff, buffer[0]);
ASSERT.equal(0xff, buffer[1]);
ASSERT.equal(0xff, buffer[2]);
ASSERT.equal(0xfb, buffer[3]);
ASSERT.equal(0xfb, buffer[4]);
ASSERT.equal(0xff, buffer[5]);
ASSERT.equal(0xff, buffer[6]);
ASSERT.equal(0xff, buffer[7]);
buffer.writeInt32(-805306713, 0, 'big');
buffer.writeInt32(-805306713, 4, 'little');
ASSERT.equal(0xcf, buffer[0]);
ASSERT.equal(0xff, buffer[1]);
ASSERT.equal(0xfe, buffer[2]);
ASSERT.equal(0xa7, buffer[3]);
ASSERT.equal(0xa7, buffer[4]);
ASSERT.equal(0xfe, buffer[5]);
ASSERT.equal(0xff, buffer[6]);
ASSERT.equal(0xcf, buffer[7]);
}
test8();
test16();
test32();

View File

@ -0,0 +1,118 @@
/*
* A battery of tests to help us read a series of uints
*/
var ASSERT = require('assert');
/*
* We need to check the following things:
* - We are correctly resolving big endian (doesn't mean anything for 8 bit)
* - Correctly resolving little endian (doesn't mean anything for 8 bit)
* - Correctly using the offsets
* - Correctly interpreting values that are beyond the signed range as unsigned
*/
function test8() {
var data = new Buffer(4);
data.writeUInt8(23, 0, 'big');
data.writeUInt8(23, 1, 'big');
data.writeUInt8(23, 2, 'big');
data.writeUInt8(23, 3, 'big');
ASSERT.equal(23, data[0]);
ASSERT.equal(23, data[1]);
ASSERT.equal(23, data[2]);
ASSERT.equal(23, data[3]);
data.writeUInt8(23, 0, 'little');
data.writeUInt8(23, 1, 'little');
data.writeUInt8(23, 2, 'little');
data.writeUInt8(23, 3, 'little');
ASSERT.equal(23, data[0]);
ASSERT.equal(23, data[1]);
ASSERT.equal(23, data[2]);
ASSERT.equal(23, data[3]);
data.writeUInt8(255, 0, 'big');
ASSERT.equal(255, data[0]);
data.writeUInt8(255, 0, 'little');
ASSERT.equal(255, data[0]);
}
function test16() {
var value = 0x2343;
var data = new Buffer(4);
data.writeUInt16(value, 0, 'big');
ASSERT.equal(0x23, data[0]);
ASSERT.equal(0x43, data[1]);
data.writeUInt16(value, 1, 'big');
ASSERT.equal(0x23, data[1]);
ASSERT.equal(0x43, data[2]);
data.writeUInt16(value, 2, 'big');
ASSERT.equal(0x23, data[2]);
ASSERT.equal(0x43, data[3]);
data.writeUInt16(value, 0, 'little');
ASSERT.equal(0x23, data[1]);
ASSERT.equal(0x43, data[0]);
data.writeUInt16(value, 1, 'little');
ASSERT.equal(0x23, data[2]);
ASSERT.equal(0x43, data[1]);
data.writeUInt16(value, 2, 'little');
ASSERT.equal(0x23, data[3]);
ASSERT.equal(0x43, data[2]);
value = 0xff80;
data.writeUInt16(value, 0, 'little');
ASSERT.equal(0xff, data[1]);
ASSERT.equal(0x80, data[0]);
data.writeUInt16(value, 0, 'big');
ASSERT.equal(0xff, data[0]);
ASSERT.equal(0x80, data[1]);
}
function test32() {
var data = new Buffer(6);
var value = 0xe7f90a6d;
data.writeUInt32(value, 0, 'big');
ASSERT.equal(0xe7, data[0]);
ASSERT.equal(0xf9, data[1]);
ASSERT.equal(0x0a, data[2]);
ASSERT.equal(0x6d, data[3]);
data.writeUInt32(value, 1, 'big');
ASSERT.equal(0xe7, data[1]);
ASSERT.equal(0xf9, data[2]);
ASSERT.equal(0x0a, data[3]);
ASSERT.equal(0x6d, data[4]);
data.writeUInt32(value, 2, 'big');
ASSERT.equal(0xe7, data[2]);
ASSERT.equal(0xf9, data[3]);
ASSERT.equal(0x0a, data[4]);
ASSERT.equal(0x6d, data[5]);
data.writeUInt32(value, 0, 'little');
ASSERT.equal(0xe7, data[3]);
ASSERT.equal(0xf9, data[2]);
ASSERT.equal(0x0a, data[1]);
ASSERT.equal(0x6d, data[0]);
data.writeUInt32(value, 1, 'little');
ASSERT.equal(0xe7, data[4]);
ASSERT.equal(0xf9, data[3]);
ASSERT.equal(0x0a, data[2]);
ASSERT.equal(0x6d, data[1]);
data.writeUInt32(value, 2, 'little');
ASSERT.equal(0xe7, data[5]);
ASSERT.equal(0xf9, data[4]);
ASSERT.equal(0x0a, data[3]);
ASSERT.equal(0x6d, data[2]);
}
test8();
test16();
test32();