summaryrefslogtreecommitdiff
path: root/src/node_buffer.cc
diff options
context:
space:
mode:
authorJames M Snell <jasnell@gmail.com>2016-10-11 14:12:31 -0700
committerJames M Snell <jasnell@gmail.com>2016-10-25 10:12:02 -0700
commite8eaaa772414e6193702f3933cbee919d6fcdc95 (patch)
tree22268649a84bd380c35c54d0f3a06337589d36f5 /src/node_buffer.cc
parent1cf55f806b8a483398272d32a65882fc7b1933d0 (diff)
downloadandroid-node-v8-e8eaaa772414e6193702f3933cbee919d6fcdc95.tar.gz
android-node-v8-e8eaaa772414e6193702f3933cbee919d6fcdc95.tar.bz2
android-node-v8-e8eaaa772414e6193702f3933cbee919d6fcdc95.zip
buffer: add buffer.transcode
Add buffer.transcode(source, from, to) method. Primarily uses ICU to transcode a buffer's content from one of Node.js' supported encodings to another. Originally part of a proposal to add a new unicode module. Decided to refactor the approach towrds individual PRs without a new module. Refs: https://github.com/nodejs/node/pull/8075 PR-URL: https://github.com/nodejs/node/pull/9038 Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node_buffer.cc')
-rw-r--r--src/node_buffer.cc55
1 files changed, 19 insertions, 36 deletions
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index 07a4106642..540de1827f 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -22,23 +22,6 @@
if (!(r)) return env->ThrowRangeError("out of range index"); \
} while (0)
-#define THROW_AND_RETURN_UNLESS_BUFFER(env, obj) \
- do { \
- if (!HasInstance(obj)) \
- return env->ThrowTypeError("argument should be a Buffer"); \
- } while (0)
-
-#define SPREAD_ARG(val, name) \
- CHECK((val)->IsUint8Array()); \
- Local<Uint8Array> name = (val).As<Uint8Array>(); \
- ArrayBuffer::Contents name##_c = name->Buffer()->GetContents(); \
- const size_t name##_offset = name->ByteOffset(); \
- const size_t name##_length = name->ByteLength(); \
- char* const name##_data = \
- static_cast<char*>(name##_c.Data()) + name##_offset; \
- if (name##_length > 0) \
- CHECK_NE(name##_data, nullptr);
-
#define SLICE_START_END(start_arg, end_arg, end_max) \
size_t start; \
size_t end; \
@@ -448,7 +431,7 @@ void StringSlice(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = env->isolate();
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
- SPREAD_ARG(args.This(), ts_obj);
+ SPREAD_BUFFER_ARG(args.This(), ts_obj);
if (ts_obj_length == 0)
return args.GetReturnValue().SetEmptyString();
@@ -465,7 +448,7 @@ void StringSlice<UCS2>(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
- SPREAD_ARG(args.This(), ts_obj);
+ SPREAD_BUFFER_ARG(args.This(), ts_obj);
if (ts_obj_length == 0)
return args.GetReturnValue().SetEmptyString();
@@ -543,8 +526,8 @@ void Copy(const FunctionCallbackInfo<Value> &args) {
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
Local<Object> target_obj = args[0].As<Object>();
- SPREAD_ARG(args.This(), ts_obj);
- SPREAD_ARG(target_obj, target);
+ SPREAD_BUFFER_ARG(args.This(), ts_obj);
+ SPREAD_BUFFER_ARG(target_obj, target);
size_t target_start;
size_t source_start;
@@ -577,7 +560,7 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
- SPREAD_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
size_t start = args[2]->Uint32Value();
size_t end = args[3]->Uint32Value();
@@ -590,7 +573,7 @@ void Fill(const FunctionCallbackInfo<Value>& args) {
// First check if Buffer has been passed.
if (Buffer::HasInstance(args[1])) {
- SPREAD_ARG(args[1], fill_obj);
+ SPREAD_BUFFER_ARG(args[1], fill_obj);
str_length = fill_obj_length;
memcpy(ts_obj_data + start, fill_obj_data, MIN(str_length, fill_length));
goto start_fill;
@@ -669,7 +652,7 @@ void StringWrite(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_UNLESS_BUFFER(env, args.This());
- SPREAD_ARG(args.This(), ts_obj);
+ SPREAD_BUFFER_ARG(args.This(), ts_obj);
if (!args[0]->IsString())
return env->ThrowTypeError("Argument must be a string");
@@ -747,7 +730,7 @@ static inline void Swizzle(char* start, unsigned int len) {
template <typename T, enum Endianness endianness>
void ReadFloatGeneric(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
- SPREAD_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
uint32_t offset = args[1]->Uint32Value();
CHECK_LE(offset + sizeof(T), ts_obj_length);
@@ -881,8 +864,8 @@ void CompareOffset(const FunctionCallbackInfo<Value> &args) {
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
- SPREAD_ARG(args[0], ts_obj);
- SPREAD_ARG(args[1], target);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[1], target);
size_t target_start;
size_t source_start;
@@ -921,8 +904,8 @@ void Compare(const FunctionCallbackInfo<Value> &args) {
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[1]);
- SPREAD_ARG(args[0], obj_a);
- SPREAD_ARG(args[1], obj_b);
+ SPREAD_BUFFER_ARG(args[0], obj_a);
+ SPREAD_BUFFER_ARG(args[1], obj_b);
size_t cmp_length = MIN(obj_a_length, obj_b_length);
@@ -977,7 +960,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
UTF8);
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
- SPREAD_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
Local<String> needle = args[1].As<String>();
int64_t offset_i64 = args[2]->IntegerValue();
@@ -1084,8 +1067,8 @@ void IndexOfBuffer(const FunctionCallbackInfo<Value>& args) {
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[1]);
- SPREAD_ARG(args[0], ts_obj);
- SPREAD_ARG(args[1], buf);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[1], buf);
int64_t offset_i64 = args[2]->IntegerValue();
bool is_forward = args[4]->IsTrue();
@@ -1143,7 +1126,7 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
ASSERT(args[3]->IsBoolean());
THROW_AND_RETURN_UNLESS_BUFFER(Environment::GetCurrent(args), args[0]);
- SPREAD_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
uint32_t needle = args[1]->Uint32Value();
int64_t offset_i64 = args[2]->IntegerValue();
@@ -1171,7 +1154,7 @@ void IndexOfNumber(const FunctionCallbackInfo<Value>& args) {
void Swap16(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
- SPREAD_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
SwapBytes16(ts_obj_data, ts_obj_length);
args.GetReturnValue().Set(args[0]);
}
@@ -1180,7 +1163,7 @@ void Swap16(const FunctionCallbackInfo<Value>& args) {
void Swap32(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
- SPREAD_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
SwapBytes32(ts_obj_data, ts_obj_length);
args.GetReturnValue().Set(args[0]);
}
@@ -1189,7 +1172,7 @@ void Swap32(const FunctionCallbackInfo<Value>& args) {
void Swap64(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
THROW_AND_RETURN_UNLESS_BUFFER(env, args[0]);
- SPREAD_ARG(args[0], ts_obj);
+ SPREAD_BUFFER_ARG(args[0], ts_obj);
SwapBytes64(ts_obj_data, ts_obj_length);
args.GetReturnValue().Set(args[0]);
}