43
43
*/
44
44
class ArrayCodec <T > extends AbstractCodec <Object []> {
45
45
46
- private static final byte CLOSE_CURLY = '}' ;
46
+ static final byte CLOSE_CURLY = '}' ;
47
47
48
- private static final byte COMMA = ',' ;
48
+ static final byte COMMA = ',' ;
49
49
50
- private static final String NULL = "NULL" ;
50
+ static final String NULL = "NULL" ;
51
51
52
- private static final byte OPEN_CURLY = '{' ;
52
+ static final byte OPEN_CURLY = '{' ;
53
53
54
54
private final ArrayCodecDelegate <T > delegate ;
55
55
@@ -159,9 +159,9 @@ Object[] doDecode(ByteBuf buffer, PostgresTypeIdentifier dataType, Format format
159
159
Assert .requireNonNull (type , "type must not be null" );
160
160
161
161
if (FORMAT_BINARY == format ) {
162
- return decodeBinary (buffer , this .dataType , type );
162
+ return decodeBinary (buffer , this .dataType , this . delegate , this . componentType , type );
163
163
} else {
164
- return decodeText (buffer , this .dataType , type );
164
+ return decodeText (buffer , this .dataType , this . delimiter , this . delegate , this . componentType , type );
165
165
}
166
166
}
167
167
@@ -257,14 +257,15 @@ private static int getDimensions(List<?> list) {
257
257
return dims ;
258
258
}
259
259
260
- Object [] decodeBinary (ByteBuf buffer , PostgresTypeIdentifier dataType , Class <?> returnType ) {
260
+ @ SuppressWarnings ("unchecked" )
261
+ static <T > T [] decodeBinary (ByteBuf buffer , PostgresTypeIdentifier dataType , Decoder <T > decoder , Class <T > componentType , Class <?> returnType ) {
261
262
if (!buffer .isReadable ()) {
262
- return new Object [ 0 ] ;
263
+ return ( T []) Array . newInstance ( componentType , 0 ) ;
263
264
}
264
265
265
266
int dimensions = buffer .readInt ();
266
267
if (dimensions == 0 ) {
267
- return (Object []) Array .newInstance (this . componentType , 0 );
268
+ return (T []) Array .newInstance (componentType , 0 );
268
269
}
269
270
270
271
if (returnType != Object .class ) {
@@ -280,18 +281,19 @@ Object[] decodeBinary(ByteBuf buffer, PostgresTypeIdentifier dataType, Class<?>
280
281
buffer .skipBytes (4 ); // lower bound ignored
281
282
}
282
283
283
- Object [] array = (Object []) Array .newInstance (this . componentType , dims );
284
+ T [] array = (T []) Array .newInstance (componentType , dims );
284
285
285
- readArrayAsBinary (buffer , dataType , array , dims , 0 );
286
+ readArrayAsBinary (buffer , dataType , array , dims , decoder , componentType , 0 );
286
287
287
288
return array ;
288
289
}
289
290
290
- Object [] decodeText (ByteBuf buffer , PostgresTypeIdentifier dataType , Class <?> returnType ) {
291
- List <?> elements = decodeText (buffer , dataType );
291
+ @ SuppressWarnings ("unchecked" )
292
+ static <T > T [] decodeText (ByteBuf buffer , PostgresTypeIdentifier dataType , byte delimiter , Decoder <T > decoder , Class <T > componentType , Class <?> returnType ) {
293
+ List <T > elements = (List <T >) decodeText (buffer , delimiter , dataType , decoder , componentType );
292
294
293
295
if (elements .isEmpty ()) {
294
- return (Object []) Array .newInstance (this . componentType , 0 );
296
+ return (T []) Array .newInstance (componentType , 0 );
295
297
}
296
298
297
299
int dimensions = getDimensions (elements );
@@ -300,27 +302,29 @@ Object[] decodeText(ByteBuf buffer, PostgresTypeIdentifier dataType, Class<?> re
300
302
Assert .requireArrayDimension (returnType , dimensions , "Dimensions mismatch: %s expected, but %s returned from DB" );
301
303
}
302
304
303
- return toArray (elements , createArrayType (dimensions ).getComponentType ());
305
+ return toArray (elements , ( Class < T >) createArrayType (componentType , dimensions ).getComponentType ());
304
306
}
305
307
306
- private Class <?> createArrayType (int dims ) {
308
+ @ SuppressWarnings ("unchecked" )
309
+ private static <T > Class <T > createArrayType (Class <T > componentType , int dims ) {
307
310
int [] size = new int [dims ];
308
311
Arrays .fill (size , 1 );
309
- return Array .newInstance (this . componentType , size ).getClass ();
312
+ return ( Class < T >) Array .newInstance (componentType , size ).getClass ();
310
313
}
311
314
312
- private static Object [] toArray (List <?> list , Class <?> returnType ) {
315
+ @ SuppressWarnings ("unchecked" )
316
+ private static <T > T [] toArray (List <T > list , Class <T > returnType ) {
313
317
List <Object > result = new ArrayList <>(list .size ());
314
318
315
319
for (Object e : list ) {
316
- Object o = (e instanceof List ? toArray ((List <? >) e , returnType .getComponentType ()) : e );
320
+ Object o = (e instanceof List ? toArray ((List <Object >) e , ( Class < Object >) returnType .getComponentType ()) : e );
317
321
result .add (o );
318
322
}
319
323
320
- return result .toArray ((Object []) Array .newInstance (returnType , list .size ()));
324
+ return result .toArray ((T []) Array .newInstance (returnType , list .size ()));
321
325
}
322
326
323
- private List <Object > decodeText (ByteBuf buf , PostgresTypeIdentifier dataType ) {
327
+ private static < T > List <Object > decodeText (ByteBuf buf , byte delimiter , PostgresTypeIdentifier dataType , Decoder < T > decoder , Class < T > componentType ) {
324
328
List <Object > arrayList = new ArrayList <>();
325
329
326
330
boolean insideString = false ;
@@ -416,7 +420,7 @@ private List<Object> decodeText(ByteBuf buf, PostgresTypeIdentifier dataType) {
416
420
if (!wasInsideString && slice .readableBytes () == 4 && slice .getByte (0 ) == 'N' && "NULL" .equals (slice .toString (StandardCharsets .US_ASCII ))) {
417
421
currentArray .add (null );
418
422
} else {
419
- currentArray .add (this . delegate . decode (slice , dataType , FORMAT_TEXT , this . componentType ));
423
+ currentArray .add (decoder . decode (slice , dataType , FORMAT_TEXT , componentType ));
420
424
}
421
425
}
422
426
} finally {
@@ -463,18 +467,18 @@ private void encodeAsText(ByteBuf byteBuf, Object[] value, Function<T, String> e
463
467
byteBuf .writeByte (CLOSE_CURLY );
464
468
}
465
469
466
- private void readArrayAsBinary (ByteBuf buffer , PostgresTypeIdentifier dataType , Object [] array , int [] dims , int thisDimension ) {
470
+ private static < T > void readArrayAsBinary (ByteBuf buffer , PostgresTypeIdentifier dataType , Object [] array , int [] dims , Decoder < T > decoder , Class < T > componentType , int thisDimension ) {
467
471
if (thisDimension == dims .length - 1 ) {
468
472
for (int i = 0 ; i < dims [thisDimension ]; ++i ) {
469
473
int len = buffer .readInt ();
470
474
if (len == -1 ) {
471
475
continue ;
472
476
}
473
- array [i ] = this . delegate . decode (buffer .readSlice (len ), dataType , FORMAT_BINARY , this . componentType );
477
+ array [i ] = decoder . decode (buffer .readSlice (len ), dataType , FORMAT_BINARY , componentType );
474
478
}
475
479
} else {
476
480
for (int i = 0 ; i < dims [thisDimension ]; ++i ) {
477
- readArrayAsBinary (buffer , dataType , (Object []) array [i ], dims , thisDimension + 1 );
481
+ readArrayAsBinary (buffer , dataType , (Object []) array [i ], dims , decoder , componentType , thisDimension + 1 );
478
482
}
479
483
}
480
484
}
0 commit comments