From d355fda9f907c163244e316a9bbff050a6173a1e Mon Sep 17 00:00:00 2001 From: Evan Saulpaugh Date: Fri, 28 Feb 2025 08:06:20 -0600 Subject: [PATCH] add optimize(List) and encode(List) to ABIJSON --- .../com/esaulpaugh/headlong/abi/ABIJSON.java | 55 +++++++++++++------ .../esaulpaugh/headlong/abi/ABIJSONTest.java | 13 +++++ 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/esaulpaugh/headlong/abi/ABIJSON.java b/src/main/java/com/esaulpaugh/headlong/abi/ABIJSON.java index 0eeeeab8..5d2535d2 100644 --- a/src/main/java/com/esaulpaugh/headlong/abi/ABIJSON.java +++ b/src/main/java/com/esaulpaugh/headlong/abi/ABIJSON.java @@ -134,7 +134,7 @@ public static List parseABIField(int flags, String obje } /** - * Returns a minified version of the argument, optimized for parsing by this class. Accepts JSON array or JSON object. + * Returns a minified version of the argument which is optimized for parsing. Accepts JSON array or JSON object. * * @param json Contract ABI JSON array or Function/Event/ContractError JSON object * @return optimized JSON @@ -145,14 +145,51 @@ public static String optimize(String json) { if (token == JsonToken.BEGIN_OBJECT) { return toJson(ABIObject.fromJson(json), false, true); } else if (token == JsonToken.BEGIN_ARRAY) { - return minifyArray(reader); + return encode(true, parseArray(reader, ABIJSON.ALL, ABIType.FLAGS_NONE, Function.newDefaultDigest())); } throw new IllegalArgumentException("unexpected token: " + token); } catch (IOException io) { throw new IllegalStateException(io); } } + + /** + * Returns a minified JSON array containing the given elements' encodings which is optimized for parsing. + * + * @param elements the objects to be put into the array + * @return the JSON array + * @param the common supertype of the elements + */ + public static String optimize(List elements) { + return encode(true, elements); + } + + /** + * Returns a JSON array string containing the given elements' encodings. + * + * @param elements the objects to be put into the array + * @return the JSON array + * @param common supertype of the elements + */ + public static String encode(List elements) { + return encode(false, elements); + } //---------------------------------------------------------------------------------------------------------------------- + private static String encode(boolean minify, List elements) { + final Writer stringOut = new NonSyncWriter(2048); + try (JsonWriter out = new JsonWriter(stringOut)) { + out.setIndent(minify ? "" : " "); + out.beginArray(); + for (ABIObject e : elements) { + writeObject(e, out, minify); + } + out.endArray(); + } catch (IOException io) { + throw new IllegalStateException(io); + } + return stringOut.toString(); + } + static List parseArray(final JsonReader reader, Set types, int flags, MessageDigest digest) { final List list = new ArrayList<>(); try (JsonReader ignored = reader) { @@ -183,20 +220,6 @@ static String toJson(ABIObject o, boolean pretty, boolean minify) { return stringOut.toString(); } - private static String minifyArray(JsonReader reader) throws IOException { - final List elements = parseArray(reader, ABIJSON.ALL, ABIType.FLAGS_NONE, Function.newDefaultDigest()); - final Writer stringOut = new NonSyncWriter(2048); - try (JsonWriter out = new JsonWriter(stringOut)) { - out.setIndent(""); - out.beginArray(); - for (ABIObject e : elements) { - writeObject(e, out, true); - } - out.endArray(); - } - return stringOut.toString(); - } - private static void writeObject(ABIObject o, JsonWriter out, boolean minify) throws IOException { out.beginObject(); if (o.isFunction()) { diff --git a/src/test/java/com/esaulpaugh/headlong/abi/ABIJSONTest.java b/src/test/java/com/esaulpaugh/headlong/abi/ABIJSONTest.java index 6b7e2883..cbc5125e 100644 --- a/src/test/java/com/esaulpaugh/headlong/abi/ABIJSONTest.java +++ b/src/test/java/com/esaulpaugh/headlong/abi/ABIJSONTest.java @@ -1058,6 +1058,19 @@ public void optimizeJson() { assertEquals(normIter.next(), optIter.next()); } } + + final ABIParser p = new ABIParser(); + assertEquals(optimized, ABIJSON.optimize(p.parse(CONTRACT_JSON))); + assertEquals(optimized, ABIJSON.optimize(p.parse(optimized))); + assertEquals(optimized, ABIJSON.optimize(optimized)); + assertEquals(ABIJSON.optimize(FALLBACK_CONSTRUCTOR_RECEIVE), ABIJSON.optimize(p.parse(FALLBACK_CONSTRUCTOR_RECEIVE))); + assertEquals(ABIJSON.optimize(FALLBACK_CONSTRUCTOR_RECEIVE), ABIJSON.optimize(ABIJSON.optimize(FALLBACK_CONSTRUCTOR_RECEIVE))); + assertEquals(ABIJSON.optimize("[]"), ABIJSON.optimize(p.parse("[]"))); + assertEquals(ABIJSON.optimize("[]"), ABIJSON.optimize(ABIJSON.optimize("[]"))); + + assertEquals(CONTRACT_JSON, ABIJSON.encode(p.parse(CONTRACT_JSON))); + assertEquals(FALLBACK_CONSTRUCTOR_RECEIVE, ABIJSON.encode(p.parse(FALLBACK_CONSTRUCTOR_RECEIVE))); + assertEquals("[]", ABIJSON.encode(p.parse("[]"))); } @Test