From bb852bf59fa2320d2de16f66644c916f3da8818c Mon Sep 17 00:00:00 2001 From: Adwait Kumar Singh Date: Fri, 14 Aug 2026 21:29:47 +0530 Subject: [PATCH] Use compact strings when writing CBOR text --- .../smithy/java/cbor/CborSerializer.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/codecs/cbor-codec/src/main/java/software/amazon/smithy/java/cbor/CborSerializer.java b/codecs/cbor-codec/src/main/java/software/amazon/smithy/java/cbor/CborSerializer.java index 34367ee625..0d56b34516 100644 --- a/codecs/cbor-codec/src/main/java/software/amazon/smithy/java/cbor/CborSerializer.java +++ b/codecs/cbor-codec/src/main/java/software/amazon/smithy/java/cbor/CborSerializer.java @@ -37,6 +37,7 @@ import java.time.Instant; import java.util.Arrays; import java.util.function.BiConsumer; +import software.amazon.smithy.java.codecs.commons.CompactStringAccess; import software.amazon.smithy.java.codecs.commons.StripedPool; import software.amazon.smithy.java.core.schema.Schema; import software.amazon.smithy.java.core.schema.SerializableStruct; @@ -369,6 +370,19 @@ private void writeStringValue(String value) { } ensureCapacity(5 + charLen * 3); int headerStart = pos; + byte[] latin1 = CompactStringAccess.latin1Bytes(value); + if (latin1 != null) { + for (byte current : latin1) { + if (current < 0) { + encodeLatin1TextStringRewind(latin1, headerStart); + return; + } + } + tagAndLengthUnchecked(TYPE_TEXTSTRING, charLen); + System.arraycopy(latin1, 0, buf, pos, charLen); + pos += charLen; + return; + } //Don't scan if the string is too long. if (charLen < 1000) { int orAccum = 0; @@ -385,6 +399,21 @@ private void writeStringValue(String value) { encodeUtf8TextStringRewind(value, charLen, headerStart); } + private void encodeLatin1TextStringRewind(byte[] value, int headerStart) { + int writeStart = headerStart + 5; + int p = writeStart; + for (byte current : value) { + int c = current & 0xff; + if (c < 0x80) { + buf[p++] = current; + } else { + buf[p++] = (byte) (0xC0 | (c >> 6)); + buf[p++] = (byte) (0x80 | (c & 0x3F)); + } + } + finishTextStringRewind(headerStart, p - writeStart); + } + /** * Encodes {@code value} as a CBOR text string starting at {@code headerStart}. Caller must have * reserved {@code 5 + charLen * 3} bytes from {@code headerStart}. Writes data into a 5-byte-header @@ -426,7 +455,11 @@ private void encodeUtf8TextStringRewind(String value, int charLen, int headerSta buf[p++] = (byte) (0x80 | (c & 0x3F)); } } - int byteLen = p - writeStart; + finishTextStringRewind(headerStart, p - writeStart); + } + + private void finishTextStringRewind(int headerStart, int byteLen) { + int writeStart = headerStart + 5; pos = headerStart; tagAndLengthUnchecked(TYPE_TEXTSTRING, byteLen); int actualHeaderLen = pos - headerStart;