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

Add support for writing 32-bit floats #232

Merged
merged 1 commit into from
Apr 20, 2021

Conversation

jobarr-amzn
Copy link
Contributor

Issue #, if available: #139

Description of changes: Adds support for writing 32-bit floats via a new method exposed in ion_writer.h:

ION_API_EXPORT iERR ion_writer_write_float          (hWRITER hwriter, float value);

Also adds unit tests for the same values used to verify 32-bit float read support, and amends the assertBytesEqual helper method to yield more useful feedback during failures.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

almann
almann previously approved these changes Apr 15, 2021
Copy link
Contributor

@almann almann left a comment

Choose a reason for hiding this comment

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

Overall, the copy-paste makes me sad, but I am not sure macros are the right solution (...now you have two problems...). Minor comments below around tests and naming.

ionc/ion_binary.c Show resolved Hide resolved
Comment on lines 550 to 581
iERR ion_binary_write_float_32_value(ION_STREAM *pstream, float value )
{
iENTER;
uint32_t intvalue = 0;
BYTE image[ UINT_32_IMAGE_LENGTH ];
BYTE *pb = &image[UINT_32_IMAGE_LENGTH - 1];
int len;

ASSERT( UINT_32_IMAGE_LENGTH == 4 ); // we do depend on this here
ASSERT( UINT_32_IMAGE_LENGTH == sizeof(value) ); // we also depend on this here
ASSERT( pstream != NULL );

// this copy allows us to make endian issues just int issues
intvalue = *((uint32_t *)&value);

// write 8 bits at a time into the temp buffer
// from least to most significant, backwards
// that is starting from the back of the temp
// buffer (image) - and here we always write all 8 bytes
for (len = 4; len; len--) {
*pb-- = (BYTE)(intvalue & 0xff);
intvalue >>= 8;
}

// now write the bytes out from most to least significant
// to the output stream
ASSERT((pb + 1) == image);

IONCHECK(ion_binary_write_byte_array(pstream, image, 0, UINT_32_IMAGE_LENGTH));

iRETURN;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The copy-paste here might be worth the macro...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was going to say that I disagreed because of the number of parameters it would have to have:

  • type of intvalue
  • size of image
  • expected size of image

Actually that's not so many, after all. Huh...

Comment on lines +334 to 335
iERR _ion_writer_binary_write_float(ION_WRITER *pwriter, float value);
iERR _ion_writer_binary_write_double(ION_WRITER *pwriter, double value);
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a weird asymmetry between these APIs and the _float32 and _float64 names. I don't feel super strong about it, but I am curious as to your thoughts about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The public interface corresponds to the C types, but the machinery is written in terms of the type of float that's written to the Ion stream. These methods are between the two.

Comment on lines +443 to +445
// See https://amzn.github.io/ion-docs/docs/binary.html#4-float
// "If L is 0, then the the value is 0e0 and representation is empty."
test_ion_binary_reader_supports_32_bit_floats((BYTE *) "\xE0\x01\x00\xEA\x40", 5, 0.);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the zero case is good, but has nothing to do with 32-bit-ness per se...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I copied the test values from the reader tests, figured that the same set of values was valuable for both. And a zero test for writing was valuable because I learned that we represent that in 1 byte instead of 5 (total length 5 instead of 9).

test/test_ion_binary.cpp Show resolved Hide resolved
Copy link
Contributor

@almann almann left a comment

Choose a reason for hiding this comment

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

🚀 LGTM.

Side note, you may not want to rebase/squash during iterations of a PR as it makes it hard for reviewers to do inter-diff changes from last review. You can always squash at the end via the UI or manually after the PR is approved.

@jobarr-amzn jobarr-amzn merged commit a541a81 into amazon-ion:master Apr 20, 2021
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.

2 participants