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

Parsing from binary (Python encoding via avro) #231

Open
tlindener opened this issue Jan 18, 2024 · 1 comment
Open

Parsing from binary (Python encoding via avro) #231

tlindener opened this issue Jan 18, 2024 · 1 comment

Comments

@tlindener
Copy link

tlindener commented Jan 18, 2024

Hi,

first of thanks a lot for the library! It's a real lifesaver in the node world :-)

In one of my projects I'm trying to read avro encoded messages (originally encoded in python) in nodejs.
In avro the decimal is converted to bytes and provided a logical type with precision 38 and scale 20. Since this goes beyond 64 bits the existing solutions like this do not work.
https://github.com/ovotech/castle/blob/main/packages/avro-decimal/src/index.ts

We also tried it with your extension functions
https://github.com/MikeMcl/decimal.js-extensions/tree/master/serialize
But the binary representations don't seem to be compatible. May be you have some ideas to solve this?

@MikeMcl
Copy link
Owner

MikeMcl commented Jan 23, 2024

I have no experience with avro but I read that it stores decimals using the two’s-complement representation of the unscaled integer value in big-endian byte order, so the following function should work.

It assumes that the decimals will be positive values. If not, then test the highest bit of the first byte and if it is set then invert all the bits by subtracting each byte from 256 before convertion to hex, then add one to the BigInt result.

// Must be greater or equal to 38 if you are decoding values with a precision of 38.
Decimal.precision = 40;

const bufferToDecimal = (buf, scale) => new Decimal(
  BigInt(buf.reduce((hex, byte) => hex + byte.toString(16).
  padStart(2, '0'), '0x')).toString()
).div(10 ** scale);

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

No branches or pull requests

2 participants