Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.2k
buffer: add swap16() and swap32() methods#5724
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Conversation
mscdex commented Mar 15, 2016
I think Just how common are these anyway? |
jasnell commented Mar 15, 2016
I can live with The |
jasnell commented Mar 15, 2016
Methods renamed to swap16/swap32 |
src/node_buffer.cc Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While case differs, generally the names are the same between c++ and js. Would Swap{16,32} work?
jasnell commented Mar 15, 2016
@trevnorris ... ok, updated! PTAL |
jasnell commented Mar 15, 2016
Fishrock123 commented Mar 15, 2016
Does this belong in core? |
src/node_buffer.cc Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: wrap multi-line statements in conditionals with {}, and double indent with multi-line statements. another thing lint should be catching.
trevnorris commented Mar 15, 2016
@Fishrock123 Asked myself the same thing. I believe it may just fit within the parameters of what functionality belongs in core. For example: // Read in utf16be fileconstfile=fs.readFileSync(path).swap16().toString('utf16le');// Write it back to diskfs.writeFileSync(path,Buffer(file,'utf16le').swap16());Though additional input is welcome. @jasnell have a nit, but LGTM otherwise. Let's leave this open though for at least a couple days for others to respond. |
jasnell commented Mar 15, 2016
@Fishrock123 ... it is certainly possible to do in userland but there's a bit of a performance penalty if it's done in pure javascript... I'll post some benchmark numbers in a couple of minutes that compares the performance of swap16/swap32 to equivalent pure javascript code. I went back and forth on this one also but I landed in the same @trevnorris did... that it likely fits just inside that boundary. |
jasnell commented Mar 15, 2016
Benchmarks ... the |
benchmark/buffers/buffer-swap.js Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe avoid using apply inside the bench start/end?
In buffer-iterate.js it just calls off the instance...
constname=conf.method;//...for(i=0;i<n;i+=1)method[name](buf);jasnell commented Mar 15, 2016
@trevnorris@williamkapke ... nits addressed. I also updated the implementation such that if Buffer length is below a certain threshold, a pure javascript version of the swap will be used rather than dropping down to the native layer. Based on the benchmarks, when the Buffer is below a certain size, it's far more efficient to swap in js. We may be able to further tweak the threshold but the current limits appear to be within the margin of error. |
lib/buffer.js Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you already have len above... you might as well use it here too! :D
(Same for swap32)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doh! missed that one. good catch :-)
williamkapke commented Mar 16, 2016
If we're doing this, what about (also) including a more generic I think it makes the JS side cleaner... Buffer.prototype.swap=functionswap(a,b){varx=this[a];this[a]=this[b];this[b]=x;returnthis;};Buffer.prototype.swap32=functionswap32(){for(vari=0;i<buf.length;i+=2){this.swap(i++,i+1);this.swap(i++,i+1);}returnthis;};Buffer.prototype.swap16=functionswap16(){for(vari=0;i<buf.length;i++){this.swap(i,++i);}returnthis;};constbuf=Buffer([0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8]);console.log(buf.swap(1,2));//orconsole.log(buf.swap16());//orconsole.log(buf.swap32()); |
jasnell commented Mar 16, 2016
Having a swap function makes sense but I wouldn't expose it as part of the Buffer API. Nits addressed! |
williamkapke commented Mar 16, 2016
heh- that's how I originally wrote it and then decided to put swap on the prototype ;) LGTM! |
benchmark/buffers/buffer-swap.js Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mind throwing these (the for loop) in their own function? when profiling it's easier to look for execution of a named function that only contains the code actually being profiled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will do
74769f0 to 26b4ffdComparejasnell commented Mar 17, 2016
@trevnorris ... done! also squashed the commits and rebased to pick up the buffer api changes also |
doc/api/buffer.markdown Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing closing period.
ofrobots commented Mar 22, 2016
What are the semantics when the size of the buffer is not a multiple of 2 / 4? EDIT: found the answer by looking at the test-case. |
jasnell commented Mar 22, 2016
It's also covered in the documentation addition. A |
lib/buffer.js Outdated
| binding.setupBufferJS(Buffer.prototype,bindingObj); | ||
| constswap16n=Buffer.prototype.swap16; | ||
| constswap32n=Buffer.prototype.swap32; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we doing this instead of attaching the native implementation to binding.swap*()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an artifact of how it was originally written. You're right, attaching directly to binding.swap*() is better.
trevnorris commented Mar 22, 2016
Nice tests. Left two comments. Other than that LGTM. |
jasnell commented Mar 22, 2016
@trevnorris .. thanks .. updated to address those nits! |
trevnorris commented Mar 23, 2016
@jasnell Thanks much. LGTM |
| // dropping down to the native code is faster. | ||
| constlen=this.length; | ||
| if(len%2!==0) | ||
| thrownewRangeError('Buffer length must be a multiple of 16-bits'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incredible nitpicking, but nonetheless I would opt for one of these:
Buffer size must be a multiple of 16 bits
or:
Buffer length must be a multiple of 2
I hope you understand the nuance difference I'm getting at.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change to Buffer size must be a multiple of 16 bits when I land.
Adds Buffer.prototype.swap16() and Buffer.prototype.swap32() methods that mutate the Buffer instance in-place by swapping the 16-bit and 32-bit byte-order. Example: ```js const buf = Buffer([0x1, 0x2, 0x3, 0x4]); buf.swap16(); console.log(buf); // prints Buffer(0x2, 0x1, 0x4, 0x3); buf.swap32(); console.log(buf); // prints Buffer(0x3, 0x4, 0x1, 0x2); ``` PR-URL: #5724 Reviewed-By: Trevor Norris <[email protected]>
jasnell commented Mar 23, 2016
Landed in 7d73e60. Thanks all! |
Adds Buffer.prototype.swap16() and Buffer.prototype.swap32() methods that mutate the Buffer instance in-place by swapping the 16-bit and 32-bit byte-order. Example: ```js const buf = Buffer([0x1, 0x2, 0x3, 0x4]); buf.swap16(); console.log(buf); // prints Buffer(0x2, 0x1, 0x4, 0x3); buf.swap32(); console.log(buf); // prints Buffer(0x3, 0x4, 0x1, 0x2); ``` PR-URL: #5724 Reviewed-By: Trevor Norris <[email protected]>
Notable changes: * buffer: * make byteLength work with ArrayBuffer & DataView (Jackson Tian) [#5255](#5255) * backport --zero-fill-buffers command line option (James M Snell) [#5744](#5744) * backport new buffer constructor APIs (James M Snell) [#5763](#5763) * add swap16() and swap32() methods (James M Snell) [#5724](#5724) * fs: add the fs.mkdtemp() function. (Florian MARGAINE) [#5333](#5333) * net: emit host in lookup event (HUANG Wei) [#5598](#5598) * node: --no-browser-globals configure flag (Fedor Indutny) [#5853](#5853) * npm: Upgrade to v3.8.3. (Forrest L Norvell) * repl: support standalone blocks (Prince J Wesley) [#5581](#5581) * src: override v8 thread defaults using cli options (Tom Gallacher) [#4344](#4344)
Notable changes: * buffer: * make byteLength work with ArrayBuffer & DataView (Jackson Tian) [#5255](#5255) * backport --zero-fill-buffers command line option (James M Snell) [#5744](#5744) * backport new buffer constructor APIs (James M Snell) [#5763](#5763) * add swap16() and swap32() methods (James M Snell) [#5724](#5724) * fs: add the fs.mkdtemp() function. (Florian MARGAINE) [#5333](#5333) * net: emit host in lookup event (HUANG Wei) [#5598](#5598) * node: --no-browser-globals configure flag (Fedor Indutny) [#5853](#5853) * npm: Upgrade to v3.8.3. Fixes a security flaw in the use of authentication tokens in HTTP requests that would allow an attacker to set up a server that could collect tokens from users of the command-line interface. Authentication tokens have previously been sent with every request made by the CLI for logged-in users, regardless of the destination of the request. This update fixes this by only including those tokens for requests made against the registry or registries used for the current install. (Forrest L Norvell) [npm#6](npm#6) * repl: support standalone blocks (Prince J Wesley) [#5581](#5581) * src: override v8 thread defaults using cli options (Tom Gallacher) [#4344](#4344)
Notable changes: * buffer: * make byteLength work with ArrayBuffer & DataView (Jackson Tian) [#5255](#5255) * backport --zero-fill-buffers command line option (James M Snell) [#5744](#5744) * backport new buffer constructor APIs (James M Snell) [#5763](#5763) * add swap16() and swap32() methods (James M Snell) [#5724](#5724) * fs: add the fs.mkdtemp() function. (Florian MARGAINE) [#5333](#5333) * net: emit host in lookup event (HUANG Wei) [#5598](#5598) * node: --no-browser-globals configure flag (Fedor Indutny) [#5853](#5853) * npm: Upgrade to v3.8.3. Fixes a security flaw in the use of authentication tokens in HTTP requests that would allow an attacker to set up a server that could collect tokens from users of the command-line interface. Authentication tokens have previously been sent with every request made by the CLI for logged-in users, regardless of the destination of the request. This update fixes this by only including those tokens for requests made against the registry or registries used for the current install. (Forrest L Norvell) [npm#6](npm#6) * repl: support standalone blocks (Prince J Wesley) [#5581](#5581) * src: override v8 thread defaults using cli options (Tom Gallacher) [#4344](#4344)
Notable changes: * buffer: * make byteLength work with ArrayBuffer & DataView (Jackson Tian) [#5255](#5255) * backport --zero-fill-buffers command line option (James M Snell) [#5744](#5744) * backport new buffer constructor APIs (James M Snell) [#5763](#5763) * add swap16() and swap32() methods (James M Snell) [#5724](#5724) * fs: add the fs.mkdtemp() function. (Florian MARGAINE) [#5333](#5333) * net: emit host in lookup event (HUANG Wei) [#5598](#5598) * node: --no-browser-globals configure flag (Fedor Indutny) [#5853](#5853) * npm: Upgrade to v3.8.3. Fixes a security flaw in the use of authentication tokens in HTTP requests that would allow an attacker to set up a server that could collect tokens from users of the command-line interface. Authentication tokens have previously been sent with every request made by the CLI for logged-in users, regardless of the destination of the request. This update fixes this by only including those tokens for requests made against the registry or registries used for the current install. (Forrest L Norvell) [npm#6](npm#6) * repl: support standalone blocks (Prince J Wesley) [#5581](#5581) * src: override v8 thread defaults using cli options (Tom Gallacher) [#4344](#4344) PR-URL: #5970
Pull Request check-list
make -j8 test(UNIX) orvcbuild test nosign(Windows) pass withthis change (including linting)?
test (or a benchmark) included?
existing APIs, or introduces new ones)?
Affected core subsystem(s)
buffer
Description of change
Adds
Buffer.prototype.swapShort()Buffer.prototype.swap16() andBuffer.prototype.swapLong()Buffer.prototype.swap32() methods thatmutate the Buffer instance in-place by swapping the 16-bit and 32-bit
byte-order.
Example:
Was looking at a number of use cases recently around reading in UTF16BE data and converting that to UTF8 and realized that we really didn't expose an efficient mechanism for doing a byte-swap in Buffer. This seemed like a useful API addition.
/cc @trevnorris@srl295