Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
Closes GH-695 Add 'hex' encoding to Buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
isaacs authored and ry committed Feb 20, 2011
1 parent 9851574 commit 0aa1a8a
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 1 deletion.
2 changes: 2 additions & 0 deletions doc/api/buffers.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ the first 8 bits of each character. This encoding method is depreciated and
should be avoided in favor of `Buffer` objects where possible. This encoding
will be removed in future versions of Node.

* `'hex'` - Encode each byte as two hexidecimal characters.


### new Buffer(size)

Expand Down
45 changes: 45 additions & 0 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ SlowBuffer.prototype.inspect = function() {
};


SlowBuffer.prototype.hexSlice = function(start, end) {
var len = this.length;

if (!start || start < 0) start = 0;
if (end < 0 || start + end > len) end = len - start;

var out = '';
for (var i = start; i < end; i ++) {
out += toHex(this[i]);
}
return out;
};



SlowBuffer.prototype.toString = function(encoding, start, end) {
encoding = String(encoding || 'utf8').toLowerCase();
start = +start || 0;
Expand All @@ -28,6 +43,9 @@ SlowBuffer.prototype.toString = function(encoding, start, end) {
}

switch (encoding) {
case 'hex':
return this.hexSlice(start, end);

case 'utf8':
case 'utf-8':
return this.utf8Slice(start, end);
Expand All @@ -51,6 +69,23 @@ SlowBuffer.prototype.toString = function(encoding, start, end) {
};


SlowBuffer.prototype.hexWrite = function(string, offset) {
var len = string.length;
offset = +offset || 0;

// must be an even number of digits
if (len % 2) {
throw new Error('Invalid hex string');
}
for (var i = 0; i < len / 2; i ++) {
var byte = parseInt(string.substr(i * 2, 2), 16);
if (isNaN(byte)) throw new Error('Invalid hex string');
this[offset + i] = byte;
}
return i;
}


SlowBuffer.prototype.write = function(string, offset, encoding) {
// Support both (string, offset, encoding)
// and the legacy (string, encoding, offset)
Expand All @@ -64,6 +99,9 @@ SlowBuffer.prototype.write = function(string, offset, encoding) {
encoding = String(encoding || 'utf8').toLowerCase();

switch (encoding) {
case 'hex':
return this.hexWrite(string, offset);

case 'utf8':
case 'utf-8':
return this.utf8Write(string, offset);
Expand Down Expand Up @@ -224,6 +262,10 @@ Buffer.prototype.write = function(string, offset, encoding) {

var ret;
switch (encoding) {
case 'hex':
ret = this.parent.hexWrite(string, this.offset + offset, maxLength);
break;

case 'utf8':
case 'utf-8':
ret = this.parent.utf8Write(string, this.offset + offset, maxLength);
Expand Down Expand Up @@ -277,6 +319,9 @@ Buffer.prototype.toString = function(encoding, start, end) {
end = end + this.offset;

switch (encoding) {
case 'hex':
return this.parent.hexSlice(start, end);

case 'utf8':
case 'utf-8':
return this.parent.utf8Slice(start, end);
Expand Down
3 changes: 3 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,8 @@ enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
return UCS2;
} else if (strcasecmp(*encoding, "binary") == 0) {
return BINARY;
} else if (strcasecmp(*encoding, "hex") == 0) {
return HEX;
} else if (strcasecmp(*encoding, "raw") == 0) {
fprintf(stderr, "'raw' (array of integers) has been removed. "
"Use 'binary'.\n");
Expand Down Expand Up @@ -1134,6 +1136,7 @@ ssize_t DecodeBytes(v8::Handle<v8::Value> val, enum encoding encoding) {

if (encoding == UTF8) return str->Utf8Length();
else if (encoding == UCS2) return str->Length() * 2;
else if (encoding == HEX) return str->Length() / 2;

return str->Length();
}
Expand Down
2 changes: 1 addition & 1 deletion src/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ do { \
__callback##_TEM); \
} while (0)

enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY};
enum encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX};
enum encoding ParseEncoding(v8::Handle<v8::Value> encoding_v,
enum encoding _default = BINARY);
void FatalException(v8::TryCatch &try_catch);
Expand Down
2 changes: 2 additions & 0 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ static size_t ByteLength (Handle<String> string, enum encoding enc) {
return base64_decoded_size(*v, v.length());
} else if (enc == UCS2) {
return string->Length() * 2;
} else if (enc == HEX) {
return string->Length() / 2;
} else {
return string->Length();
}
Expand Down
31 changes: 31 additions & 0 deletions test/simple/test-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,34 @@ assert.equal(12, Buffer.byteLength('Il était tué', 'binary'));

// slice(0,0).length === 0
assert.equal(0, Buffer('hello').slice(0, 0).length);

// test hex toString
console.log('Create hex string from buffer');
var hexb = new Buffer(256);
for (var i = 0; i < 256; i ++) {
hexb[i] = i;
}
var hexStr = hexb.toString('hex');
assert.equal(hexStr,
'000102030405060708090a0b0c0d0e0f'+
'101112131415161718191a1b1c1d1e1f'+
'202122232425262728292a2b2c2d2e2f'+
'303132333435363738393a3b3c3d3e3f'+
'404142434445464748494a4b4c4d4e4f'+
'505152535455565758595a5b5c5d5e5f'+
'606162636465666768696a6b6c6d6e6f'+
'707172737475767778797a7b7c7d7e7f'+
'808182838485868788898a8b8c8d8e8f'+
'909192939495969798999a9b9c9d9e9f'+
'a0a1a2a3a4a5a6a7a8a9aaabacadaeaf'+
'b0b1b2b3b4b5b6b7b8b9babbbcbdbebf'+
'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf'+
'd0d1d2d3d4d5d6d7d8d9dadbdcdddedf'+
'e0e1e2e3e4e5e6e7e8e9eaebecedeeef'+
'f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff');

console.log('Create buffer from hex string');
var hexb2 = new Buffer(hexStr, 'hex');
for (var i = 0; i < 256; i ++) {
assert.equal(hexb2[i], hexb[i]);
}

3 comments on commit 0aa1a8a

@bkw
Copy link

@bkw bkw commented on 0aa1a8a Jul 13, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any chance of also getting this back into v0.4 ?

@bnoordhuis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please open an issue if you feel strongly about it, it's unfortunately not as trivial as simply applying the patch. Some of the internals have changed so it doesn't do quite the right thing without some work.

@bkw
Copy link

@bkw bkw commented on 0aa1a8a Jul 13, 2011

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case, I'll let it rest and use a wrapper instead. Thanks for responding so quickly.

Please sign in to comment.