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

Commit

Permalink
buffer: change output of Buffer.prototype.toJSON()
Browse files Browse the repository at this point in the history
Expand the JSON representation of Buffer to include type information
so that it can be deserialized in JSON.parse() without context.

Fixes #5110.
Fixes #5143.
  • Loading branch information
David Braun authored and TooTallNate committed Mar 30, 2013
1 parent 9b8dd39 commit 840a29f
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
13 changes: 8 additions & 5 deletions doc/api/buffer.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,22 @@ See `buffer.write()` example, above.

### buf.toJSON()

Returns a JSON-representation of the Buffer instance, which is identical to the
output for JSON Arrays. `JSON.stringify` implicitly calls this function when
stringifying a Buffer instance.
Returns a JSON-representation of the Buffer instance. `JSON.stringify`
implicitly calls this function when stringifying a Buffer instance.

Example:

var buf = new Buffer('test');
var json = JSON.stringify(buf);

console.log(json);
// '[116,101,115,116]'
// '{"type":"Buffer","data":[116,101,115,116]}'

var copy = new Buffer(JSON.parse(json));
var copy = JSON.parse(json, function(key, value) {
return value && value.type === 'Buffer'
? new Buffer(value.data)
: value;
});

console.log(copy);
// <Buffer 74 65 73 74>
Expand Down
5 changes: 4 additions & 1 deletion lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,10 @@ Buffer.prototype.write = function(string, offset, length, encoding) {


Buffer.prototype.toJSON = function() {
return Array.prototype.slice.call(this, 0);
return {
type: 'Buffer',
data: Array.prototype.slice.call(this, 0)
};
};


Expand Down
15 changes: 13 additions & 2 deletions test/simple/test-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -833,8 +833,19 @@ Buffer(Buffer(0), 0, 0);
});


// GH-3905
assert.equal(JSON.stringify(Buffer('test')), '[116,101,115,116]');
// GH-5110
(function () {
var buffer = new Buffer('test'),
string = JSON.stringify(buffer);

assert.equal(string, '{"type":"Buffer","data":[116,101,115,116]}');

assert.deepEqual(buffer, JSON.parse(string, function(key, value) {
return value && value.type === 'Buffer'
? new Buffer(value.data)
: value;
}));
})();

// issue GH-4331
assert.throws(function() {
Expand Down

3 comments on commit 840a29f

@q2dg
Copy link

@q2dg q2dg commented on 840a29f Sep 7, 2014

Choose a reason for hiding this comment

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

Ei, the example code of buf.toJSON() in official doc (http://nodejs.org/docs/v0.11.13/api/buffer.html#buffer_buf_tojson) doesn't use buf.toJSON()!!!!!!!!!!

If I replace this line: var json = JSON.stringify(buf) by this line: var json=buf.toJSON(), running that example I get this output (node v0.11.13, Fedora 20):

{ type: 'Buffer', data: [ 116, 101, 115, 116 ] }
undefined:1
[object Object]
^
SyntaxError: Unexpected token o
at Object.parse (native)
at Object. (/home/q2dg/borrar:9:17)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:349:32)
at Function.Module._load (module.js:305:12)
at Function.Module.runMain (module.js:490:10)
at startup (node.js:124:16)
at node.js:807:3

instead of the expected:

{"type":"Buffer","data":[116,101,115,116]}
<Buffer 74 65 73 74>

@cjihrig
Copy link

@cjihrig cjihrig commented on 840a29f Sep 8, 2014

Choose a reason for hiding this comment

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

@q2dg - it might be helpful to have an example that actually calls toJSON(), but this function is typically called internally by JSON.stringify(). Taken from MDN:

If an object being stringified has a property named toJSON whose value is a function, then the toJSON method customizes JSON stringification behavior: instead of the object being serialized, the value returned by the toJSON method when called will be serialized.

In this particular case, toJSON() returns an object, not a string. So it makes sense that JSON.parse() would throw.

@q2dg
Copy link

@q2dg q2dg commented on 840a29f Sep 8, 2014

Choose a reason for hiding this comment

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

@cjihrig Ooh, I see!! Thanks a lot!!

Please sign in to comment.