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

Adds support for all scalar types to IonRawBinaryWriter_1_1 #667

Merged
merged 1 commit into from
Dec 11, 2023

Conversation

popematt
Copy link
Contributor

@popematt popematt commented Dec 9, 2023

Issue #, if available:

None

Description of changes:

Adds support for ints, floats, decimals, timestamps, symbols, strings, blobs, and clobs.
See 🗺️ comments for some specific details.

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

Copy link

codecov bot commented Dec 9, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

❗ No coverage uploaded for pull request base (ion-11-encoding@b92edd7). Click here to learn what that means.

Additional details and impacted files
@@                Coverage Diff                 @@
##             ion-11-encoding     #667   +/-   ##
==================================================
  Coverage                   ?   64.77%           
  Complexity                 ?     5732           
==================================================
  Files                      ?      199           
  Lines                      ?    24720           
  Branches                   ?     4392           
==================================================
  Hits                       ?    16013           
  Misses                     ?     7408           
  Partials                   ?     1299           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Comment on lines -152 to -153
fun writeInt(value: Byte)
fun writeInt(value: Int)
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 implementations of these ended up just casting value to a Long and then calling the existing implementation for writing a Long. If we want to have optimized implementations for smaller integer sizes, we can add that later.

fun writeInt(value: Long)
fun writeInt(value: BigInteger)

fun writeFloat(value: Float)
fun writeFloat(value: Double)

fun writeDecimal(value: BigDecimal)
fun writeDecimal(value: Decimal)
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 realized that this is redundant because Decimal extends BigDecimal.

@@ -129,7 +128,7 @@ public static int writeIntValue(WriteBuffer buffer, final BigInteger value) {
* Writes a float to the given WriteBuffer using the Ion 1.1 encoding for Ion Floats.
* @return the number of bytes written
*/
public static int writeFloat(WriteBuffer buffer, final float value) {
public static int writeFloatValue(WriteBuffer buffer, final float value) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ This was renamed to write___Value to be consistent with the other methods in this class.

Comment on lines -202 to -205
} else if (numCoefficientBytes == 1){
buffer.writeByte((byte) 0);
} else {
throw new IllegalStateException("Unreachable! coefficientBytes should not be null when numCoefficientBytes > 1");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ So, this is kind of interesting. I had already determined that this should be unreachable (hence the message in the exception), but IntelliJ deduced that it is unreachable, which means it must be provably unreachable... so I removed it.

*/
public static int writeSymbolValue(WriteBuffer buffer, long value) {
public static int writeSymbolValue(WriteBuffer buffer, int value) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ Since Java standard library collections track their size using an int, SIDs are effectively limited to those that can be represented in an int.


currentContainer.length += buffer.writeFlexSym(utf8StringEncoder.encode(text.toString()))
hasFieldName = true
}

private fun switchToFlexSym() {
private fun switchCurrentStructToFlexSym() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ Now that I've had a bit of time from writing this function, when I came back here and saw it, I thought the name was a bit too vague.

override fun writeTimestamp(value: Timestamp) {
TODO("Not yet implemented")
}
override fun writeTimestamp(value: Timestamp) = writeScalar { writeTimestampValue(buffer, value) }

override fun writeTimestamp(value: Instant) {
TODO("Not yet implemented")
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 started to implement this, but I realized how expensive it is to convert an Instant into its year, month, day, etc., and so I don't think it offers much benefit over just converting the Instant to a Timestamp. As long as there's no objection, I think I'll just remove it.

It might be useful to have streamlined function for LocalDate and it's ilk at some point in the future.

@@ -32,6 +32,7 @@ class FlexIntTest {
" 1048576, 00001000 00000000 00000000 00000001",
" 134217727, 11111000 11111111 11111111 01111111",
" 134217728, 00010000 00000000 00000000 00000000 00000001",
" ${Int.MAX_VALUE}, 11110000 11111111 11111111 11111111 00001111",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ This got added just because I was asking myself what is the FlexInt representation of Int.MAX_VALUE, so now it's here for reference.

Comment on lines +38 to +46
val commentRegex = Regex("\\|.*$")
val excessWhitespaceRegex = Regex("\\s+")
val cleanedHexBytes: String = hexBytes.lines()
.map { it.replace(commentRegex, "").trim() }
.filter { it.isNotBlank() }
.joinToString(" ")
.replace(excessWhitespaceRegex, " ")
.uppercase()
.trim()
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 had to fix this up a bit so that it could correctly handle lines that have comments but no hex pairs. E.g.

C2          | {
03 5E       |    $1: true
            | }

@@ -798,4 +808,212 @@ class IonRawBinaryWriterTest_1_1 {
writeBool(false)
}
}

@Test
fun `write int`() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

🗺️ For all of these scalar types, I'm relying on the tests for IonEncoder_1_1 to ensure edge cases are covered since the implementations in IonRawBinaryWriter_1_1 are basically pass through methods.

@popematt popematt requested a review from tgregg December 11, 2023 18:07
@tgregg tgregg changed the title Adds support for all scalar types to IonRawBinaryTextWriter_1_1 Adds support for all scalar types to IonRawBinaryWriter_1_1 Dec 11, 2023
@popematt popematt merged commit f74e7e0 into amazon-ion:ion-11-encoding Dec 11, 2023
8 of 32 checks passed
@popematt popematt deleted the ion11-scalars branch December 11, 2023 23:32
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