Browse Source

Implement buffer.toString('base64')

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
528015e0d8
  1. 3
      lib/buffer.js
  2. 77
      src/node_buffer.cc
  3. 1
      src/node_buffer.h
  4. 14
      test/simple/test-buffer.js

3
lib/buffer.js

@ -42,6 +42,9 @@ Buffer.prototype.toString = function (encoding, start, stop) {
case 'binary':
return this.binarySlice(start, stop);
case 'base64':
return this.base64Slice(start, stop);
default:
throw new Error('Unknown encoding');
}

77
src/node_buffer.cc

@ -272,6 +272,82 @@ Handle<Value> Buffer::Utf8Slice(const Arguments &args) {
return scope.Close(string);
}
static char* base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
Handle<Value> Buffer::Base64Slice(const Arguments &args) {
HandleScope scope;
Buffer *parent = ObjectWrap::Unwrap<Buffer>(args.This());
SLICE_ARGS(args[0], args[1])
int n = end - start;
int out_len = (n + 2 - ((n + 2) % 3)) / 3 * 4;
char *out = new char[out_len];
char bitbuf[3];
int i = start; // data() index
int j = 0; // out index
char c;
bool b1_oob, b2_oob;
while (i < end) {
bitbuf[0] = parent->data()[i++];
if (i < end) {
bitbuf[1] = parent->data()[i];
b1_oob = false;
} else {
bitbuf[1] = 0;
b1_oob = true;
}
i++;
if (i < end) {
bitbuf[2] = parent->data()[i];
b2_oob = false;
} else {
bitbuf[2] = 0;
b2_oob = true;
}
i++;
c = bitbuf[0] >> 2;
assert(c < 64);
out[j++] = base64_table[c];
assert(j < out_len);
c = ((bitbuf[0] & 0x03) << 4) | (bitbuf[1] >> 4);
assert(c < 64);
out[j++] = base64_table[c];
assert(j < out_len);
if (b1_oob) {
out[j++] = '=';
} else {
c = ((bitbuf[1] & 0x0F) << 2) | (bitbuf[2] >> 6);
assert(c < 64);
out[j++] = base64_table[c];
}
assert(j < out_len);
if (b2_oob) {
out[j++] = '=';
} else {
c = bitbuf[2] & 0x3F;
assert(c < 64);
out[j++] = base64_table[c];
}
assert(j <= out_len);
}
Local<String> string = String::New(out, out_len);
delete [] out;
return scope.Close(string);
}
Handle<Value> Buffer::Slice(const Arguments &args) {
HandleScope scope;
@ -534,6 +610,7 @@ void Buffer::Initialize(Handle<Object> target) {
// copy free
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, "slice", Buffer::Slice);
// TODO NODE_SET_PROTOTYPE_METHOD(t, "utf16Slice", Utf16Slice);
// copy

1
src/node_buffer.h

@ -54,6 +54,7 @@ class Buffer : public ObjectWrap {
static v8::Handle<v8::Value> Slice(const v8::Arguments &args);
static v8::Handle<v8::Value> BinarySlice(const v8::Arguments &args);
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> BinaryWrite(const v8::Arguments &args);
static v8::Handle<v8::Value> AsciiWrite(const v8::Arguments &args);

14
test/simple/test-buffer.js

@ -229,3 +229,17 @@ assert.deepEqual(e, new Buffer([195, 188, 98, 101, 114]));
var f = new Buffer('über', 'ascii');
assert.deepEqual(f, new Buffer([252, 98, 101, 114]));
//
// Test toString('base64')
//
assert.equal('TWFu', (new Buffer('Man')).toString('base64'));
// big example
quote = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
expected = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=";
assert.equal(expected, (new Buffer(quote)).toString('base64'));

Loading…
Cancel
Save