Browse Source

buffer: return offset for end of last write

v0.11.5-release
Trevor Norris 12 years ago
parent
commit
4a34c69cbf
  1. 10
      lib/buffer.js
  2. 22
      src/node_buffer.cc
  3. 8
      test/simple/test-buffer.js

10
lib/buffer.js

@ -574,6 +574,7 @@ Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
if (!noAssert) if (!noAssert)
checkInt(this, value, offset, 1, 0xff, 0); checkInt(this, value, offset, 1, 0xff, 0);
this[offset] = value; this[offset] = value;
return offset + 1;
}; };
@ -594,6 +595,7 @@ Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
if (!noAssert) if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0); checkInt(this, value, offset, 2, 0xffff, 0);
writeUInt16(this, value, offset, false); writeUInt16(this, value, offset, false);
return offset + 2;
}; };
@ -603,6 +605,7 @@ Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
if (!noAssert) if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0); checkInt(this, value, offset, 2, 0xffff, 0);
writeUInt16(this, value, offset, true); writeUInt16(this, value, offset, true);
return offset + 2;
}; };
@ -627,6 +630,7 @@ Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
if (!noAssert) if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0); checkInt(this, value, offset, 4, 0xffffffff, 0);
writeUInt32(this, value, offset, false); writeUInt32(this, value, offset, false);
return offset + 4;
}; };
@ -636,6 +640,7 @@ Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
if (!noAssert) if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0); checkInt(this, value, offset, 4, 0xffffffff, 0);
writeUInt32(this, value, offset, true); writeUInt32(this, value, offset, true);
return offset + 4;
}; };
@ -683,6 +688,7 @@ Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
checkInt(this, value, offset, 1, 0x7f, -0x80); checkInt(this, value, offset, 1, 0x7f, -0x80);
if (value < 0) value = 0xff + value + 1; if (value < 0) value = 0xff + value + 1;
this[offset] = value; this[offset] = value;
return offset + 1;
}; };
@ -693,6 +699,7 @@ Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
checkInt(this, value, offset, 2, 0x7fff, -0x8000); checkInt(this, value, offset, 2, 0x7fff, -0x8000);
if (value < 0) value = 0xffff + value + 1; if (value < 0) value = 0xffff + value + 1;
writeUInt16(this, value, offset, false); writeUInt16(this, value, offset, false);
return offset + 2;
}; };
@ -703,6 +710,7 @@ Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
checkInt(this, value, offset, 2, 0x7fff, -0x8000); checkInt(this, value, offset, 2, 0x7fff, -0x8000);
if (value < 0) value = 0xffff + value + 1; if (value < 0) value = 0xffff + value + 1;
writeUInt16(this, value, offset, true); writeUInt16(this, value, offset, true);
return offset + 2;
}; };
@ -713,6 +721,7 @@ Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
if (value < 0) value = 0xffffffff + value + 1; if (value < 0) value = 0xffffffff + value + 1;
writeUInt32(this, value, offset, false); writeUInt32(this, value, offset, false);
return offset + 4;
}; };
@ -723,4 +732,5 @@ Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000); checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
if (value < 0) value = 0xffffffff + value + 1; if (value < 0) value = 0xffffffff + value + 1;
writeUInt32(this, value, offset, true); writeUInt32(this, value, offset, true);
return offset + 4;
}; };

22
src/node_buffer.cc

@ -485,18 +485,23 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {
template <typename T, enum Endianness endianness> template <typename T, enum Endianness endianness>
void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) { uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
bool doAssert = !args[2]->BooleanValue(); bool doAssert = !args[2]->BooleanValue();
T val = static_cast<T>(args[0]->NumberValue()); T val = static_cast<T>(args[0]->NumberValue());
size_t offset; size_t offset;
CHECK_NOT_OOB(ParseArrayIndex(args[1], 0, &offset)); if (!ParseArrayIndex(args[1], 0, &offset)) {
ThrowRangeError("out of range index");
return 0;
}
if (doAssert) { if (doAssert) {
size_t len = Length(args.This()); size_t len = Length(args.This());
if (offset + sizeof(T) > len || offset + sizeof(T) < offset) if (offset + sizeof(T) > len || offset + sizeof(T) < offset) {
return ThrowRangeError("Trying to write beyond buffer length"); ThrowRangeError("Trying to write beyond buffer length");
return 0;
}
} }
union NoAlias { union NoAlias {
@ -509,26 +514,27 @@ void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
char* ptr = static_cast<char*>(data) + offset; char* ptr = static_cast<char*>(data) + offset;
if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes)); if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes));
memcpy(ptr, na.bytes, sizeof(na.bytes)); memcpy(ptr, na.bytes, sizeof(na.bytes));
return offset + sizeof(na.bytes);
} }
void WriteFloatLE(const FunctionCallbackInfo<Value>& args) { void WriteFloatLE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<float, kLittleEndian>(args); args.GetReturnValue().Set(WriteFloatGeneric<float, kLittleEndian>(args));
} }
void WriteFloatBE(const FunctionCallbackInfo<Value>& args) { void WriteFloatBE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<float, kBigEndian>(args); args.GetReturnValue().Set(WriteFloatGeneric<float, kBigEndian>(args));
} }
void WriteDoubleLE(const FunctionCallbackInfo<Value>& args) { void WriteDoubleLE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<double, kLittleEndian>(args); args.GetReturnValue().Set(WriteFloatGeneric<double, kLittleEndian>(args));
} }
void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) { void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<double, kBigEndian>(args); args.GetReturnValue().Set(WriteFloatGeneric<double, kBigEndian>(args));
} }

8
test/simple/test-buffer.js

@ -778,6 +778,14 @@ assert.equal(buf[3], 0xFF);
assert.equal(buf[3], 0xFF); assert.equal(buf[3], 0xFF);
}); });
// test offset returns are correct
var b = new Buffer(16);
assert.equal(4, b.writeUInt32LE(0, 0));
assert.equal(6, b.writeUInt16LE(0, 4));
assert.equal(7, b.writeUInt8(0, 6));
assert.equal(8, b.writeInt8(0, 7));
assert.equal(16, b.writeDoubleLE(0, 8));
// test for buffer overrun // test for buffer overrun
buf = new Buffer([0, 0, 0, 0, 0]); // length: 5 buf = new Buffer([0, 0, 0, 0, 0]); // length: 5
var sub = buf.slice(0, 4); // length: 4 var sub = buf.slice(0, 4); // length: 4

Loading…
Cancel
Save