mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
buffer: move checkFloat from lib into src
The type and range checks performed by this function can be done more efficiently in native code. PR-URL: https://github.com/nodejs/node/pull/3763 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
committed by
Trevor Norris
parent
55b1eccae6
commit
22478d3669
@@ -1028,20 +1028,13 @@ Buffer.prototype.writeInt32BE = function(value, offset, noAssert) {
|
||||
};
|
||||
|
||||
|
||||
function checkFloat(buffer, value, offset, ext) {
|
||||
if (!(buffer instanceof Buffer))
|
||||
throw new TypeError('"buffer" argument 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);
|
||||
binding.writeFloatLE(this, val, offset);
|
||||
binding.writeFloatLE(this, val, offset);
|
||||
else
|
||||
binding.writeFloatLE(this, val, offset, true);
|
||||
return offset + 4;
|
||||
};
|
||||
|
||||
@@ -1050,8 +1043,9 @@ Buffer.prototype.writeFloatBE = function writeFloatBE(val, offset, noAssert) {
|
||||
val = +val;
|
||||
offset = offset >>> 0;
|
||||
if (!noAssert)
|
||||
checkFloat(this, val, offset, 4);
|
||||
binding.writeFloatBE(this, val, offset);
|
||||
binding.writeFloatBE(this, val, offset);
|
||||
else
|
||||
binding.writeFloatBE(this, val, offset, true);
|
||||
return offset + 4;
|
||||
};
|
||||
|
||||
@@ -1060,8 +1054,9 @@ Buffer.prototype.writeDoubleLE = function writeDoubleLE(val, offset, noAssert) {
|
||||
val = +val;
|
||||
offset = offset >>> 0;
|
||||
if (!noAssert)
|
||||
checkFloat(this, val, offset, 8);
|
||||
binding.writeDoubleLE(this, val, offset);
|
||||
binding.writeDoubleLE(this, val, offset);
|
||||
else
|
||||
binding.writeDoubleLE(this, val, offset, true);
|
||||
return offset + 8;
|
||||
};
|
||||
|
||||
@@ -1070,7 +1065,8 @@ Buffer.prototype.writeDoubleBE = function writeDoubleBE(val, offset, noAssert) {
|
||||
val = +val;
|
||||
offset = offset >>> 0;
|
||||
if (!noAssert)
|
||||
checkFloat(this, val, offset, 8);
|
||||
binding.writeDoubleBE(this, val, offset);
|
||||
binding.writeDoubleBE(this, val, offset);
|
||||
else
|
||||
binding.writeDoubleBE(this, val, offset, true);
|
||||
return offset + 8;
|
||||
};
|
||||
|
||||
@@ -730,15 +730,37 @@ void ReadDoubleBE(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
|
||||
template <typename T, enum Endianness endianness>
|
||||
uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
|
||||
SPREAD_ARG(args[0], ts_obj);
|
||||
void WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
bool should_assert = args.Length() < 4;
|
||||
|
||||
if (should_assert) {
|
||||
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
|
||||
}
|
||||
|
||||
Local<Uint8Array> ts_obj = args[0].As<Uint8Array>();
|
||||
ArrayBuffer::Contents ts_obj_c = ts_obj->Buffer()->GetContents();
|
||||
const size_t ts_obj_offset = ts_obj->ByteOffset();
|
||||
const size_t ts_obj_length = ts_obj->ByteLength();
|
||||
char* const ts_obj_data =
|
||||
static_cast<char*>(ts_obj_c.Data()) + ts_obj_offset;
|
||||
if (ts_obj_length > 0)
|
||||
CHECK_NE(ts_obj_data, nullptr);
|
||||
|
||||
T val = args[1]->NumberValue(env->context()).FromMaybe(0);
|
||||
size_t offset = args[2]->IntegerValue(env->context()).FromMaybe(0);
|
||||
|
||||
T val = args[1]->NumberValue();
|
||||
uint32_t offset = args[2]->Uint32Value();
|
||||
size_t memcpy_num = sizeof(T);
|
||||
if (offset + sizeof(T) > ts_obj_length)
|
||||
memcpy_num = ts_obj_length - offset;
|
||||
|
||||
if (should_assert) {
|
||||
CHECK_NOT_OOB(offset + memcpy_num >= memcpy_num);
|
||||
CHECK_NOT_OOB(offset + memcpy_num <= ts_obj_length);
|
||||
}
|
||||
CHECK_LE(offset + memcpy_num, ts_obj_length);
|
||||
|
||||
union NoAlias {
|
||||
T val;
|
||||
char bytes[sizeof(T)];
|
||||
@@ -749,31 +771,26 @@ uint32_t WriteFloatGeneric(const FunctionCallbackInfo<Value>& args) {
|
||||
if (endianness != GetEndianness())
|
||||
Swizzle(na.bytes, sizeof(na.bytes));
|
||||
memcpy(ptr, na.bytes, memcpy_num);
|
||||
return offset + memcpy_num;
|
||||
}
|
||||
|
||||
|
||||
void WriteFloatLE(const FunctionCallbackInfo<Value>& args) {
|
||||
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
|
||||
args.GetReturnValue().Set(WriteFloatGeneric<float, kLittleEndian>(args));
|
||||
WriteFloatGeneric<float, kLittleEndian>(args);
|
||||
}
|
||||
|
||||
|
||||
void WriteFloatBE(const FunctionCallbackInfo<Value>& args) {
|
||||
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
|
||||
args.GetReturnValue().Set(WriteFloatGeneric<float, kBigEndian>(args));
|
||||
WriteFloatGeneric<float, kBigEndian>(args);
|
||||
}
|
||||
|
||||
|
||||
void WriteDoubleLE(const FunctionCallbackInfo<Value>& args) {
|
||||
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
|
||||
args.GetReturnValue().Set(WriteFloatGeneric<double, kLittleEndian>(args));
|
||||
WriteFloatGeneric<double, kLittleEndian>(args);
|
||||
}
|
||||
|
||||
|
||||
void WriteDoubleBE(const FunctionCallbackInfo<Value>& args) {
|
||||
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
|
||||
args.GetReturnValue().Set(WriteFloatGeneric<double, kBigEndian>(args));
|
||||
WriteFloatGeneric<double, kBigEndian>(args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user