diff --git a/lib/buffer.js b/lib/buffer.js index 7fd297559bd..80f6a4271fa 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -581,6 +581,38 @@ Buffer.prototype.readInt32BE = function(offset, noAssert) { }; +Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return internal.readFloatLE(this, offset); +}; + + +Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 4, this.length); + return internal.readFloatBE(this, offset); +}; + + +Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 8, this.length); + return internal.readDoubleLE(this, offset); +}; + + +Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) { + offset = offset >>> 0; + if (!noAssert) + checkOffset(offset, 8, this.length); + return internal.readDoubleBE(this, offset); +}; + + function checkInt(buffer, value, offset, ext, max, min) { if (!(buffer instanceof Buffer)) throw new TypeError('buffer must be a Buffer instance'); @@ -705,3 +737,51 @@ Buffer.prototype.writeInt32BE = function(value, offset, noAssert) { this[offset + 3] = value; return offset + 4; }; + + +function checkFloat(buffer, value, offset, ext) { + if (!(buffer instanceof Buffer)) + throw new TypeError('buffer must be a Buffer instance'); + if (offset + ext > buffer.length) + throw new RangeError('index out of range'); +} + + +Buffer.prototype.writeFloatLE = function writeFloatLE(val, offset, noAssert) { + val = +val; + offset = offset >>> 0; + if (!noAssert) + checkFloat(this, val, offset, 4); + internal.writeFloatLE(this, val, offset); + return offset + 4; +}; + + +Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) { + val = +val; + offset = offset >>> 0; + if (!noAssert) + checkFloat(this, val, offset, 4); + internal.writeFloatBE(this, val, offset); + return offset + 4; +}; + + +Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) { + val = +val; + offset = offset >>> 0; + if (!noAssert) + checkFloat(this, val, offset, 8); + internal.writeDoubleLE(this, val, offset); + return offset + 8; +}; + + +Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) { + val = +val; + offset = offset >>> 0; + if (!noAssert) + checkFloat(this, val, offset, 8); + internal.writeDoubleBE(this, val, offset); + return offset + 8; +}; diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 8be551d9b0e..3f8de59b4f8 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -462,17 +462,10 @@ static inline void Swizzle(char* start, unsigned int len) { template void ReadFloatGeneric(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args.GetIsolate()); - bool doAssert = !args[1]->BooleanValue(); - size_t offset; + ARGS_THIS(args[0].As()); - CHECK_NOT_OOB(ParseArrayIndex(args[0], 0, &offset)); - - if (doAssert) { - size_t len = Length(args.This()); - if (offset + sizeof(T) > len || offset + sizeof(T) < offset) - return env->ThrowRangeError("Trying to read beyond buffer length"); - } + uint32_t offset = args[1]->Uint32Value(); + CHECK_LE(offset + sizeof(T), obj_length); union NoAlias { T val; @@ -480,8 +473,7 @@ void ReadFloatGeneric(const FunctionCallbackInfo& args) { }; union NoAlias na; - const void* data = args.This()->GetIndexedPropertiesExternalArrayData(); - const char* ptr = static_cast(data) + offset; + const char* ptr = static_cast(obj_data) + offset; memcpy(na.bytes, ptr, sizeof(na.bytes)); if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes)); @@ -512,24 +504,11 @@ void ReadDoubleBE(const FunctionCallbackInfo& args) { template uint32_t WriteFloatGeneric(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args.GetIsolate()); - bool doAssert = !args[2]->BooleanValue(); + ARGS_THIS(args[0].As()) - T val = static_cast(args[0]->NumberValue()); - size_t offset; - - if (!ParseArrayIndex(args[1], 0, &offset)) { - env->ThrowRangeError("out of range index"); - return 0; - } - - if (doAssert) { - size_t len = Length(args.This()); - if (offset + sizeof(T) > len || offset + sizeof(T) < offset) { - env->ThrowRangeError("Trying to write beyond buffer length"); - return 0; - } - } + T val = args[1]->NumberValue(); + uint32_t offset = args[2]->Uint32Value(); + CHECK_LE(offset + sizeof(T), obj_length); union NoAlias { T val; @@ -537,8 +516,7 @@ uint32_t WriteFloatGeneric(const FunctionCallbackInfo& args) { }; union NoAlias na = { val }; - void* data = args.This()->GetIndexedPropertiesExternalArrayData(); - char* ptr = static_cast(data) + offset; + char* ptr = static_cast(obj_data) + offset; if (endianness != GetEndianness()) Swizzle(na.bytes, sizeof(na.bytes)); memcpy(ptr, na.bytes, sizeof(na.bytes)); @@ -643,16 +621,6 @@ void SetupBufferJS(const FunctionCallbackInfo& args) { NODE_SET_METHOD(proto, "ucs2Write", Ucs2Write); NODE_SET_METHOD(proto, "utf8Write", Utf8Write); - NODE_SET_METHOD(proto, "readDoubleBE", ReadDoubleBE); - NODE_SET_METHOD(proto, "readDoubleLE", ReadDoubleLE); - NODE_SET_METHOD(proto, "readFloatBE", ReadFloatBE); - NODE_SET_METHOD(proto, "readFloatLE", ReadFloatLE); - - NODE_SET_METHOD(proto, "writeDoubleBE", WriteDoubleBE); - NODE_SET_METHOD(proto, "writeDoubleLE", WriteDoubleLE); - NODE_SET_METHOD(proto, "writeFloatBE", WriteFloatBE); - NODE_SET_METHOD(proto, "writeFloatLE", WriteFloatLE); - NODE_SET_METHOD(proto, "copy", Copy); // for backwards compatibility @@ -668,6 +636,16 @@ void SetupBufferJS(const FunctionCallbackInfo& args) { NODE_SET_METHOD(internal, "byteLength", ByteLength); NODE_SET_METHOD(internal, "compare", Compare); NODE_SET_METHOD(internal, "fill", Fill); + + NODE_SET_METHOD(internal, "readDoubleBE", ReadDoubleBE); + NODE_SET_METHOD(internal, "readDoubleLE", ReadDoubleLE); + NODE_SET_METHOD(internal, "readFloatBE", ReadFloatBE); + NODE_SET_METHOD(internal, "readFloatLE", ReadFloatLE); + + NODE_SET_METHOD(internal, "writeDoubleBE", WriteDoubleBE); + NODE_SET_METHOD(internal, "writeDoubleLE", WriteDoubleLE); + NODE_SET_METHOD(internal, "writeFloatBE", WriteFloatBE); + NODE_SET_METHOD(internal, "writeFloatLE", WriteFloatLE); }