Skip to content

Commit 5b803bd

Browse files
speedstorm1copybara-github
authored andcommitted
chore: chore
PiperOrigin-RevId: 897263266
1 parent 8e8146a commit 5b803bd

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

src/main/java/com/google/genai/JsonSerializable.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,40 @@ public java.time.Duration deserialize(JsonParser p, DeserializationContext ctxt)
9494
}
9595
}
9696

97+
/** Custom Jackson serializer for {@code byte[]} to output standard base64 without linefeeds. */
98+
static class CustomByteArraySerializer extends JsonSerializer<byte[]> {
99+
@Override
100+
public void serialize(byte[] value, JsonGenerator gen, SerializerProvider serializers)
101+
throws java.io.IOException {
102+
if (value == null) {
103+
gen.writeNull();
104+
} else {
105+
gen.writeString(java.util.Base64.getEncoder().encodeToString(value));
106+
}
107+
}
108+
}
109+
110+
/** Custom Jackson deserializer for {@code byte[]} to support URL-safe base64 strings. */
111+
static class CustomByteArrayDeserializer extends JsonDeserializer<byte[]> {
112+
@Override
113+
public byte[] deserialize(JsonParser p, DeserializationContext ctxt)
114+
throws java.io.IOException, JsonProcessingException {
115+
String value = p.getValueAsString();
116+
if (value == null) {
117+
return null;
118+
}
119+
try {
120+
if (value.contains("-") || value.contains("_")) {
121+
return java.util.Base64.getUrlDecoder().decode(value);
122+
} else {
123+
return java.util.Base64.getDecoder().decode(value);
124+
}
125+
} catch (IllegalArgumentException e) {
126+
throw ctxt.weirdStringException(value, byte[].class, "Failed to decode base64 string");
127+
}
128+
}
129+
}
130+
97131
/** Configures the stream read constraints for the JSON parser. */
98132
private static void configureStreamReadConstraints(int maxReadLength) {
99133
if (maxReadLength <= 0) {
@@ -116,6 +150,8 @@ private static void configureStreamReadConstraints(int maxReadLength) {
116150
SimpleModule customModule = new SimpleModule();
117151
customModule.addSerializer(java.time.Duration.class, new CustomDurationSerializer());
118152
customModule.addDeserializer(java.time.Duration.class, new CustomDurationDeserializer());
153+
customModule.addSerializer(byte[].class, new CustomByteArraySerializer());
154+
customModule.addDeserializer(byte[].class, new CustomByteArrayDeserializer());
119155

120156
// Register JavaTimeModule for other java.time types *before* the custom module
121157
// This ensures our custom Duration handling takes precedence over the default one

src/test/java/com/google/genai/TableTest.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,7 @@ private static Collection<DynamicTest> createTestCases(
200200
String msg = " => Test skipped: replay tests are not supported for edit_image";
201201
return Collections.singletonList(DynamicTest.dynamicTest(testName + msg, () -> {}));
202202
}
203-
if (testName.contains("models.embed_content.test_new_api_inline_pdf")) {
204-
String msg = " => Test skipped: inline byte deserialization fails";
205-
return Collections.singletonList(DynamicTest.dynamicTest(testName + msg, () -> {}));
206-
}
203+
207204
// TODO(b/457846189): Support models.list filter parameter
208205
if (testName.contains("models.list.test_tuned_models_with_filter")
209206
|| testName.contains("models.list.test_tuned_models.vertex")) {

0 commit comments

Comments
 (0)