summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/buffer.js17
-rw-r--r--src/node.cc5
-rw-r--r--src/node.h2
-rw-r--r--src/node_buffer.cc46
-rw-r--r--src/node_buffer.h2
-rw-r--r--test/simple/test-buffer.js10
6 files changed, 80 insertions, 2 deletions
diff --git a/lib/buffer.js b/lib/buffer.js
index 273394734..64caa7e97 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -41,6 +41,10 @@ SlowBuffer.prototype.toString = function(encoding, start, end) {
case 'base64':
return this.base64Slice(start, end);
+ case 'ucs2':
+ case 'ucs-2':
+ return this.ucs2Slice(start, end);
+
default:
throw new Error('Unknown encoding');
}
@@ -73,6 +77,10 @@ SlowBuffer.prototype.write = function(string, offset, encoding) {
case 'base64':
return this.base64Write(string, offset);
+ case 'ucs2':
+ case 'ucs-2':
+ return this.ucs2Write(start, end);
+
default:
throw new Error('Unknown encoding');
}
@@ -228,6 +236,11 @@ Buffer.prototype.write = function(string, offset, encoding) {
ret = this.parent.base64Write(string, this.offset + offset, maxLength);
break;
+ case 'ucs2':
+ case 'ucs-2':
+ ret = this.parent.ucs2Write(string, this.offset + offset, maxLength);
+ break;
+
default:
throw new Error('Unknown encoding');
}
@@ -271,6 +284,10 @@ Buffer.prototype.toString = function(encoding, start, end) {
case 'base64':
return this.parent.base64Slice(start, end);
+ case 'ucs2':
+ case 'ucs-2':
+ return this.parent.ucs2Slice(start, end);
+
default:
throw new Error('Unknown encoding');
}
diff --git a/src/node.cc b/src/node.cc
index 2e1e6b39b..a52d3e3f5 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1078,6 +1078,10 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
return ASCII;
} else if (strcasecmp(*encoding, "base64") == 0) {
return BASE64;
+ } else if (strcasecmp(*encoding, "ucs2") == 0) {
+ return UCS2;
+ } else if (strcasecmp(*encoding, "ucs-2") == 0) {
+ return UCS2;
} else if (strcasecmp(*encoding, "binary") == 0) {
return BINARY;
} else if (strcasecmp(*encoding, "raw") == 0) {
@@ -1129,6 +1133,7 @@ ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {
Local<String> str = val->ToString();
if (encoding == UTF8) return str->Utf8Length();
+ else if (encoding == UCS2) return str->Length() * 2;
return str->Length();
}
diff --git a/src/node.h b/src/node.h
index 580a9c12e..e2c58d344 100644
--- a/src/node.h
+++ b/src/node.h
@@ -44,7 +44,7 @@ do { \
__callback##_TEM); \
} while (0)
-enum encoding {ASCII, UTF8, BASE64, BINARY};
+enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY};
enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v,
enum encoding _default = BINARY);
void FatalException(v8::TryCatch &try_catch);
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index 2c1966212..8b48f2a2e 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -84,6 +84,8 @@ static size_t ByteLength (Handle<String> string, enum encoding enc) {
} else if (enc == BASE64) {
String::Utf8Value v(string);
return base64_decoded_size(*v, v.length());
+ } else if (enc == UCS2) {
+ return string->Length() * 2;
} else {
return string->Length();
}
@@ -245,6 +247,15 @@ Handle<Value> Buffer::Utf8Slice(const Arguments &args) {
return scope.Close(string);
}
+Handle<Value> Buffer::Ucs2Slice(const Arguments &args) {
+ HandleScope scope;
+ Buffer *parent = ObjectWrap::Unwrap<Buffer>(args.This());
+ SLICE_ARGS(args[0], args[1])
+ uint16_t *data = (uint16_t*)(parent->data_ + start);
+ Local<String> string = String::New(data, (end - start) / 2);
+ return scope.Close(string);
+}
+
static const char *base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
@@ -441,6 +452,39 @@ Handle<Value> Buffer::Utf8Write(const Arguments &args) {
}
+// var charsWritten = buffer.ucs2Write(string, offset, [maxLength]);
+Handle<Value> Buffer::Ucs2Write(const Arguments &args) {
+ HandleScope scope;
+ Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args.This());
+
+ if (!args[0]->IsString()) {
+ return ThrowException(Exception::TypeError(String::New(
+ "Argument must be a string")));
+ }
+
+ Local<String> s = args[0]->ToString();
+
+ size_t offset = args[1]->Uint32Value();
+
+ if (s->Length() > 0 && offset >= buffer->length_) {
+ return ThrowException(Exception::TypeError(String::New(
+ "Offset is out of bounds")));
+ }
+
+ size_t max_length = args[2]->IsUndefined() ? buffer->length_ - offset
+ : args[2]->Uint32Value();
+ max_length = MIN(buffer->length_ - offset, max_length);
+
+ uint16_t* p = (uint16_t*)(buffer->data_ + offset);
+
+ int written = s->Write(p,
+ 0,
+ max_length,
+ String::HINT_MANY_WRITES_EXPECTED);
+ return scope.Close(Integer::New(written * 2));
+}
+
+
// var charsWritten = buffer.asciiWrite(string, offset);
Handle<Value> Buffer::AsciiWrite(const Arguments &args) {
HandleScope scope;
@@ -652,6 +696,7 @@ void Buffer::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor_template, "binarySlice", Buffer::BinarySlice);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "asciiSlice", Buffer::AsciiSlice);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "base64Slice", Buffer::Base64Slice);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "ucs2Slice", Buffer::Ucs2Slice);
// TODO NODE_SET_PROTOTYPE_METHOD(t, "utf16Slice", Utf16Slice);
// copy
NODE_SET_PROTOTYPE_METHOD(constructor_template, "utf8Slice", Buffer::Utf8Slice);
@@ -660,6 +705,7 @@ void Buffer::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor_template, "asciiWrite", Buffer::AsciiWrite);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "binaryWrite", Buffer::BinaryWrite);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "base64Write", Buffer::Base64Write);
+ NODE_SET_PROTOTYPE_METHOD(constructor_template, "ucs2Write", Buffer::Ucs2Write);
NODE_SET_PROTOTYPE_METHOD(constructor_template, "copy", Buffer::Copy);
NODE_SET_METHOD(constructor_template->GetFunction(),
diff --git a/src/node_buffer.h b/src/node_buffer.h
index d87038b3e..9a0e1d240 100644
--- a/src/node_buffer.h
+++ b/src/node_buffer.h
@@ -88,10 +88,12 @@ class Buffer : public ObjectWrap {
static v8::Handle<v8::Value> AsciiSlice(const v8::Arguments &args);
static v8::Handle<v8::Value> Base64Slice(const v8::Arguments &args);
static v8::Handle<v8::Value> Utf8Slice(const v8::Arguments &args);
+ static v8::Handle<v8::Value> Ucs2Slice(const v8::Arguments &args);
static v8::Handle<v8::Value> BinaryWrite(const v8::Arguments &args);
static v8::Handle<v8::Value> Base64Write(const v8::Arguments &args);
static v8::Handle<v8::Value> AsciiWrite(const v8::Arguments &args);
static v8::Handle<v8::Value> Utf8Write(const v8::Arguments &args);
+ static v8::Handle<v8::Value> Ucs2Write(const v8::Arguments &args);
static v8::Handle<v8::Value> ByteLength(const v8::Arguments &args);
static v8::Handle<v8::Value> MakeFastBuffer(const v8::Arguments &args);
static v8::Handle<v8::Value> Copy(const v8::Arguments &args);
diff --git a/test/simple/test-buffer.js b/test/simple/test-buffer.js
index e8756a7db..176e5a463 100644
--- a/test/simple/test-buffer.js
+++ b/test/simple/test-buffer.js
@@ -225,6 +225,14 @@ var f = new Buffer('über', 'ascii');
console.error('f.length: %d (should be 4)', f.length);
assert.deepEqual(f, new Buffer([252, 98, 101, 114]));
+var f = new Buffer('über', 'ucs2');
+console.error('f.length: %d (should be 8)', f.length);
+assert.deepEqual(f, new Buffer([252, 0, 98, 0, 101, 0, 114, 0]));
+
+var f = new Buffer('привет', 'ucs2');
+console.error('f.length: %d (should be 12)', f.length);
+assert.deepEqual(f, new Buffer([63, 4, 64, 4, 56, 4, 50, 4, 53, 4, 66, 4]));
+assert.equal(f.toString('ucs2'), 'привет');
//
// Test toString('base64')
@@ -386,9 +394,9 @@ assert.equal('bcde', b.slice(1).toString());
// byte length
assert.equal(14, Buffer.byteLength('Il était tué'));
assert.equal(14, Buffer.byteLength('Il était tué', 'utf8'));
+assert.equal(24, Buffer.byteLength('Il était tué', 'ucs2'));
assert.equal(12, Buffer.byteLength('Il était tué', 'ascii'));
assert.equal(12, Buffer.byteLength('Il était tué', 'binary'));
-
// slice(0,0).length === 0
assert.equal(0, Buffer('hello').slice(0, 0).length);