Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
buffer: return offset for end of last write
Browse files Browse the repository at this point in the history
  • Loading branch information
trevnorris committed Jul 19, 2013
1 parent 2bedf6e commit 4a34c69
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 8 deletions.
10 changes: 10 additions & 0 deletions lib/buffer.js
Expand Up @@ -574,6 +574,7 @@ Buffer.prototype.writeUInt8 = function(value, offset, noAssert) {
if (!noAssert)
checkInt(this, value, offset, 1, 0xff, 0);
this[offset] = value;
return offset + 1;
};


Expand All @@ -594,6 +595,7 @@ Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) {
if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0);
writeUInt16(this, value, offset, false);
return offset + 2;
};


Expand All @@ -603,6 +605,7 @@ Buffer.prototype.writeUInt16BE = function(value, offset, noAssert) {
if (!noAssert)
checkInt(this, value, offset, 2, 0xffff, 0);
writeUInt16(this, value, offset, true);
return offset + 2;
};


Expand All @@ -627,6 +630,7 @@ Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) {
if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0);
writeUInt32(this, value, offset, false);
return offset + 4;
};


Expand All @@ -636,6 +640,7 @@ Buffer.prototype.writeUInt32BE = function(value, offset, noAssert) {
if (!noAssert)
checkInt(this, value, offset, 4, 0xffffffff, 0);
writeUInt32(this, value, offset, true);
return offset + 4;
};


Expand Down Expand Up @@ -683,6 +688,7 @@ Buffer.prototype.writeInt8 = function(value, offset, noAssert) {
checkInt(this, value, offset, 1, 0x7f, -0x80);
if (value < 0) value = 0xff + value + 1;
this[offset] = value;
return offset + 1;
};


Expand All @@ -693,6 +699,7 @@ Buffer.prototype.writeInt16LE = function(value, offset, noAssert) {
checkInt(this, value, offset, 2, 0x7fff, -0x8000);
if (value < 0) value = 0xffff + value + 1;
writeUInt16(this, value, offset, false);
return offset + 2;
};


Expand All @@ -703,6 +710,7 @@ Buffer.prototype.writeInt16BE = function(value, offset, noAssert) {
checkInt(this, value, offset, 2, 0x7fff, -0x8000);
if (value < 0) value = 0xffff + value + 1;
writeUInt16(this, value, offset, true);
return offset + 2;
};


Expand All @@ -713,6 +721,7 @@ Buffer.prototype.writeInt32LE = function(value, offset, noAssert) {
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
if (value < 0) value = 0xffffffff + value + 1;
writeUInt32(this, value, offset, false);
return offset + 4;
};


Expand All @@ -723,4 +732,5 @@ Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000);
if (value < 0) value = 0xffffffff + value + 1;
writeUInt32(this, value, offset, true);
return offset + 4;
};
22 changes: 14 additions & 8 deletions src/node_buffer.cc
Expand Up @@ -485,18 +485,23 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {


template <typename T, enum Endianness endianness>
void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
bool doAssert = !args[2]->BooleanValue();

T val = static_cast<T>(args[0]->NumberValue());
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) {
size_t len = Length(args.This());
if (offset + sizeof(T) > len || offset + sizeof(T) < offset)
return ThrowRangeError("Trying to write beyond buffer length");
if (offset + sizeof(T) > len || offset + sizeof(T) < offset) {
ThrowRangeError("Trying to write beyond buffer length");
return 0;
}
}

union NoAlias {
Expand All @@ -509,26 +514,27 @@ void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
char* ptr = static_cast<char*>(data) + offset;
if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes));
memcpy(ptr, na.bytes, sizeof(na.bytes));
return offset + sizeof(na.bytes);
}


void WriteFloatLE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<float, kLittleEndian>(args);
args.GetReturnValue().Set(WriteFloatGeneric<float, kLittleEndian>(args));
}


void WriteFloatBE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<float, kBigEndian>(args);
args.GetReturnValue().Set(WriteFloatGeneric<float, kBigEndian>(args));
}


void WriteDoubleLE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<double, kLittleEndian>(args);
args.GetReturnValue().Set(WriteFloatGeneric<double, kLittleEndian>(args));
}


void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) {
WriteFloatGeneric<double, kBigEndian>(args);
args.GetReturnValue().Set(WriteFloatGeneric<double, kBigEndian>(args));
}


Expand Down
8 changes: 8 additions & 0 deletions test/simple/test-buffer.js
Expand Up @@ -778,6 +778,14 @@ 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
buf = new Buffer([0, 0, 0, 0, 0]); // length: 5
var sub = buf.slice(0, 4); // length: 4
Expand Down

0 comments on commit 4a34c69

Please sign in to comment.