Skip to content
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

Binary primitive parsers. #264

Merged
merged 10 commits into from
Jul 11, 2018
Merged

Binary primitive parsers. #264

merged 10 commits into from
Jul 11, 2018

Conversation

theqabalist
Copy link
Collaborator

This adds a useful array of primitive buffer parsers. Reference #261.

@theqabalist
Copy link
Collaborator Author

@wavebeem I need to write all the documentation, but feel free to start perusing the changes.

"use strict";

describe("doubleLE", function() {
it("reads a double, big-endian", function() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

should say little-endian

Copy link
Collaborator

@wavebeem wavebeem left a comment

Choose a reason for hiding this comment

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

Looks good so far, just a few thoughts. Thanks for taking a look at this so quickly.

src/parsimmon.js Outdated
function uintBE(length) {
if (length < 0 || length > 6) {
throw new Error("uintBE requires length in range [0, 6].");
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Might be worth checking the number is an integer also. And then putting the logic into a helper function for reuse.

typeof length === "number" && Math.floor(length) === length is probably the clearest integer check in JS?

it("reads a float, big-endian", function() {
var b = Buffer.from([1, 2, 3, 4]);
var p = Parsimmon.Binary.floatBE;
assert.deepEqual(p.tryParse(b), 2.387939260590663e-38);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Believe it or not, this is my lucky number!!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Lol, I got this directly from the node buffer page. I figured if it's good enough for their example, it's good enough for a test case.

src/parsimmon.js Outdated
if (length < 0 || length > 6) {
throw new Error("uintBE requires length in range [0, 6].");
if ((isInteger(length) && length < 0) || length > 6) {
throw new Error("uintBE requires integer length in range [0, 6].");
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the parentheses are in the wrong spot on this line. Also it might be nice to put this entire if condition into a helper function since it's the same in several locations

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'll put this into a helper function. The parens were inserted by the style fixer I think, probably to emphasize the actual associativity, which is wrong, and I am going to fix.

Copy link
Collaborator

@wavebeem wavebeem left a comment

Choose a reason for hiding this comment

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

Left a couple suggestions on testing


function isInteger(value) {
return typeof value === "number" && Math.floor(value) === value;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Fun fact: I just checked the MDN polyfill for isInteger and it also checks isFinite but we won't need that since we're also checking the range

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger

var p = Parsimmon.Binary.encodedString("ascii", 11);
assert.deepEqual(p.tryParse(b), "hello world");
});
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it would be good to have examples of utf16le, latin1, and utf8 strings with non-ASCII characters also

Maybe a test with , , , and some alphabet characters?

https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings

uintBE: uintBE,
uint8BE: uintBE(1),
uint16BE: uintBE(2),
uint32BE: uintBE(4),
Copy link
Collaborator

Choose a reason for hiding this comment

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

So the error message for uint32BE will say uintBE(4), right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, that is true. Do you think that's too far removed? I was trying to save some boilerplate.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Honestly it's probably not a big deal. I think just for error messages we can change that later anyway.

@wavebeem
Copy link
Collaborator

Hah, it looks like Node 4 and Node 5 don't have latin-1 encoding support! Which is why the tests are failing

Given those are both EOL versions I suppose we could just remove them from the travis.yml 🤔

@theqabalist
Copy link
Collaborator Author

Do you want to do that or just remove the latin-1 example? I am thinking that if you can show that multiple encoding/decoding works, then it's relatively safe to assume the rest of the pattern will work under other encoders.

@theqabalist
Copy link
Collaborator Author

@wavebeem please double check my documentation copy. I tried to look through it myself, but the signed/unsigned le/be 8/16/32 variants make my eyes go crazy. I think I got them all right.

@wavebeem
Copy link
Collaborator

Hah, I know how that is with docs. I'll try and look at this as soon as I can.

As for Latin-1... I dunno we could remove it but with Node 4/5 no longer supported I think it's fine to drop it from the CI pipeline 🤷‍♂️

Copy link
Collaborator

@wavebeem wavebeem left a comment

Choose a reason for hiding this comment

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

I think this looks good all around. I'll try to get this merged and released soon.

Would you mind dropping Node 4/5 from the travis.yml too so we can keep the CI golden?

uintBE: uintBE,
uint8BE: uintBE(1),
uint16BE: uintBE(2),
uint32BE: uintBE(4),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Honestly it's probably not a big deal. I think just for error messages we can change that later anyway.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling 69b1a72 on theqabalist:master into f3699ec on jneen:master.

1 similar comment
@coveralls
Copy link

coveralls commented Jul 10, 2018

Coverage Status

Coverage remained the same at 100.0% when pulling 69b1a72 on theqabalist:master into f3699ec on jneen:master.

@wavebeem
Copy link
Collaborator

Thanks! I'm gonna get back to making a binary parser example after merging this and may tag you in that PR if you don't mind.

@theqabalist
Copy link
Collaborator Author

Works for me. I'll stay on the lookout.

Copy link
Collaborator

@wavebeem wavebeem left a comment

Choose a reason for hiding this comment

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

As I was sitting down to make my binary example I noticed that intLE says uintLE. Would you mind fixing that when you get a chance?

function intLE(length) {
assertValidIntegerByteLengthFor("intLE", length);

return parseBufferFor("uintLE(" + length + ")", length).map(function(buff) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I just noticed that this says uintLE on the second string by mistake.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'll just fix this myself idk why I even bothered you about this lol

@wavebeem
Copy link
Collaborator

Also this is what I've got going for a binary parser example right now: https://gist.github.com/wavebeem/68081d43f1bae5b1c8e1e64abbd03437

@wavebeem wavebeem merged commit 5b81df1 into jneen:master Jul 11, 2018
@wavebeem
Copy link
Collaborator

Thanks again for your work on this! I just released 1.12.0 and announced it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants