26
26
import convex .core .data .util .BlobBuilder ;
27
27
import convex .core .json .JSONReader ;
28
28
import convex .core .lang .RT ;
29
+ import convex .core .text .Text ;
29
30
30
31
public class JSONUtils {
31
32
@@ -100,7 +101,7 @@ public static String jsonKey(Object o) {
100
101
101
102
if (o instanceof String s ) return s ;
102
103
103
- throw new IllegalArgumentException ("Invalid yupe for JSON key: " +Utils .getClassName (o ));
104
+ throw new IllegalArgumentException ("Invalid type for JSON key: " +Utils .getClassName (o ));
104
105
}
105
106
106
107
/**
@@ -126,10 +127,10 @@ public static HashMap<String, Object> jsonMap(AMap<?, ?> m) {
126
127
* Convert any object to JSON
127
128
*
128
129
* @param value Value to convert to JSON, may be Java or CVM structure
129
- * @return JSON String
130
+ * @return Java String containing valid JSON String
130
131
*/
131
132
public static String toString (Object value ) {
132
- return toCVMString (value ).toString ();
133
+ return toJSONString (value ).toString ();
133
134
}
134
135
135
136
/**
@@ -147,20 +148,20 @@ public static ACell parse(String jsonString) {
147
148
* @param value Value to convert to JSON, may be Java or CVM structure
148
149
* @return CVM String containing valid JSON
149
150
*/
150
- public static AString toCVMString (Object value ) {
151
+ public static AString toJSONString (Object value ) {
151
152
BlobBuilder bb = new BlobBuilder ();
152
- appendCVMString (bb , value );
153
+ appendJSON (bb , value );
153
154
return Strings .create (bb .toBlob ());
154
155
}
155
156
156
- private static void appendCVMString (BlobBuilder bb , Object value ) {
157
+ private static void appendJSON (BlobBuilder bb , Object value ) {
157
158
if (value == null ) {
158
159
bb .append (Strings .NULL );
159
160
return ;
160
161
}
161
162
162
163
if (value instanceof ACell cell ) {
163
- appendCVMString (bb ,cell );
164
+ appendJSON (bb ,cell );
164
165
return ;
165
166
}
166
167
@@ -172,11 +173,11 @@ private static void appendCVMString(BlobBuilder bb, Object value) {
172
173
Iterator <Map .Entry <Object ,Object >> it = mv .entrySet ().iterator ();
173
174
while (it .hasNext ()) {
174
175
Entry <Object , Object > me = it .next ();
175
- if (i >0 ) bb .append ("\n " );
176
- appendCVMString (bb , jsonKey (me .getKey ()));
176
+ if (i >0 ) bb .append (", " );
177
+ appendJSON (bb , jsonKey (me .getKey ()));
177
178
bb .append (':' );
178
179
bb .append (' ' );
179
- appendCVMString (bb , me .getValue ());
180
+ appendJSON (bb , me .getValue ());
180
181
181
182
i += 1 ;
182
183
}
@@ -190,52 +191,52 @@ private static void appendCVMString(BlobBuilder bb, Object value) {
190
191
bb .append ('[' );
191
192
int n = lv .size ();
192
193
for (int i = 0 ; i < n ; i ++) {
193
- if (i >0 ) bb .append (' ' );
194
- appendCVMString (bb , lv .get (i ));
194
+ if (i >0 ) bb .append (', ' );
195
+ appendJSON (bb , lv .get (i ));
195
196
}
196
197
bb .append (']' );
197
198
return ;
198
199
}
199
200
200
- if (value instanceof Boolean bv ) {
201
- bb .append (bv ? Strings .TRUE : Strings .FALSE );
202
- return ;
203
- }
204
-
205
- if (value instanceof String cs ) {
206
- bb .append ('\"' );
207
- appendCVMStringQuoted (bb , cs );
208
- bb .append ('\"' );
209
- return ;
210
- }
211
-
212
- if (value instanceof Number nv ) {
213
- if (value instanceof Double dv ) {
214
- if (Double .isFinite (dv )) {
215
- bb .append (nv .toString ());
216
- return ;
201
+ if (value instanceof Boolean bv ) {
202
+ bb .append (bv ? Strings .TRUE : Strings .FALSE );
203
+ return ;
204
+ }
205
+
206
+ if (value instanceof String cs ) {
207
+ bb .append ('\"' );
208
+ appendCVMStringQuoted (bb , cs );
209
+ bb .append ('\"' );
210
+ return ;
211
+ }
212
+
213
+ if (value instanceof Number nv ) {
214
+ if (value instanceof Double dv ) {
215
+ if (Double .isFinite (dv )) {
216
+ bb .append (nv .toString ());
217
+ return ;
218
+ } else {
219
+ if (Double .isNaN (dv )) {
220
+ bb .append (JS_NAN );
217
221
} else {
218
- if (Double .isNaN (dv )) {
219
- bb .append (JS_NAN );
220
- } else {
221
- if (dv <0 ) {
222
- bb .append ('-' );
223
- }
224
- bb .append ("Infinity" );
222
+ if (dv <0 ) {
223
+ bb .append ('-' );
225
224
}
225
+ bb .append ("Infinity" );
226
226
}
227
- return ;
228
227
}
229
-
230
- bb .append (nv .toString ());
231
- return ;
228
+ return ;
232
229
}
230
+
231
+ bb .append (nv .toString ());
232
+ return ;
233
+ }
233
234
234
235
throw new IllegalArgumentException ("Can't print type as JSON: " +Utils .getClassName (value ));
235
236
}
236
237
237
238
// Specialised writing for CVM types
238
- private static void appendCVMString (BlobBuilder bb , ACell value ) {
239
+ private static void appendJSON (BlobBuilder bb , ACell value ) {
239
240
if (value == null ) {
240
241
bb .append (Strings .NULL );
241
242
return ;
@@ -250,7 +251,7 @@ private static void appendCVMString(BlobBuilder bb, ACell value) {
250
251
251
252
if (value instanceof ASymbolic cs ) {
252
253
// Print as the symbolic name string
253
- appendCVMString (bb , cs .getName ());
254
+ appendJSON (bb , cs .getName ());
254
255
return ;
255
256
}
256
257
@@ -259,12 +260,12 @@ private static void appendCVMString(BlobBuilder bb, ACell value) {
259
260
bb .append ('{' );
260
261
long n = mv .size ();
261
262
for (long i = 0 ; i < n ; i ++) {
262
- if (i >0 ) bb .append (' ' );
263
+ if (i >0 ) bb .append (', ' );
263
264
MapEntry <?,?> me =mv .entryAt (i );
264
- appendCVMString (bb , jsonKey (me .getKey ()));
265
+ appendJSON (bb , jsonKey (me .getKey ()));
265
266
bb .append (':' );
266
267
bb .append (' ' );
267
- appendCVMString (bb , me .getValue ());
268
+ appendJSON (bb , me .getValue ());
268
269
}
269
270
bb .append ('}' );
270
271
return ;
@@ -275,21 +276,21 @@ private static void appendCVMString(BlobBuilder bb, ACell value) {
275
276
bb .append ('[' );
276
277
long n = lv .count ();
277
278
for (long i = 0 ; i < n ; i ++) {
278
- if (i >0 ) bb .append (' ' );
279
- appendCVMString (bb , lv .get (i ));
279
+ if (i >0 ) bb .append (', ' );
280
+ appendJSON (bb , lv .get (i ));
280
281
}
281
282
bb .append (']' );
282
283
return ;
283
284
}
284
285
285
286
286
287
if (value instanceof CVMLong nv ) {
287
- appendCVMString (bb ,nv .longValue ());
288
+ appendJSON (bb ,nv .longValue ());
288
289
return ;
289
290
}
290
291
291
292
if (value instanceof CVMDouble nv ) {
292
- appendCVMString (bb ,nv .doubleValue ());
293
+ appendJSON (bb ,nv .doubleValue ());
293
294
return ;
294
295
}
295
296
@@ -350,4 +351,20 @@ private static AString getReplacementString(char c) {
350
351
return StringShort .create (Blob .wrap (new byte [] { '\\' , 'u' , '0' , '0' , (byte ) Utils .toHexChar ((c >> 4 ) & 0x000f ), (byte ) Utils .toHexChar (c & 0x000f ) }));
351
352
}
352
353
354
+ /**
355
+ * Escape a string for inclusion in JSON
356
+ * @param content
357
+ * @return
358
+ */
359
+ public static AString escape (String content ) {
360
+ BlobBuilder bb =new BlobBuilder ();
361
+ appendCVMStringQuoted (bb ,content );
362
+ return Strings .create (bb .toBlob ());
363
+ }
364
+
365
+ public static ACell unescape (String content ) {
366
+ String unes =Text .unescapeJava (content );
367
+ return Strings .create (unes );
368
+ }
369
+
353
370
}
0 commit comments