1+ package net .roxymc .jserialize .adapter .array ;
2+
3+ import net .roxymc .jserialize .Reader ;
4+ import net .roxymc .jserialize .Writer ;
5+ import net .roxymc .jserialize .adapter .ReadContext ;
6+ import net .roxymc .jserialize .adapter .TypeAdapter ;
7+ import net .roxymc .jserialize .adapter .WriteContext ;
8+ import net .roxymc .jserialize .token .TokenTypes ;
9+ import net .roxymc .jserialize .type .TypeRef ;
10+ import org .jspecify .annotations .Nullable ;
11+
12+ import java .io .IOException ;
13+ import java .lang .reflect .AnnotatedArrayType ;
14+ import java .lang .reflect .AnnotatedType ;
15+ import java .lang .reflect .Array ;
16+ import java .util .ArrayList ;
17+ import java .util .List ;
18+
19+ import static net .roxymc .jserialize .adapter .TypeAdapter .Factory .predicate ;
20+
21+ public final class ArrayAdapter implements TypeAdapter <Object > {
22+ private static final TypeAdapter .Factory FACTORY = predicate (type -> type .getRawType ().isArray (), new ArrayAdapter ());
23+
24+ public static TypeAdapter .Factory factory () {
25+ return FACTORY ;
26+ }
27+
28+ @ Override
29+ public @ Nullable Object read (Reader reader , TypeRef <? extends Object > type , ReadContext ctx ) throws IOException {
30+ if (!type .getRawType ().isArray ()) {
31+ throw new IllegalStateException (type .getRawType () + " is not an array" );
32+ }
33+
34+ if (reader .peek () == TokenTypes .NULL ) {
35+ reader .readNull ();
36+ return null ;
37+ }
38+
39+ TypeRef <Object > componentType = resolveComponentType (type );
40+
41+ reader .readArrayStart ();
42+
43+ List <@ Nullable Object > buffer = new ArrayList <>();
44+
45+ while (reader .peek () != TokenTypes .ARRAY_END ) {
46+ buffer .add (ctx .read (reader , componentType ));
47+ }
48+
49+ reader .readArrayEnd ();
50+
51+ Object array = Array .newInstance (componentType .getRawType (), buffer .size ());
52+
53+ for (int i = 0 ; i < buffer .size (); i ++) {
54+ Array .set (array , i , buffer .get (i ));
55+ }
56+
57+ return array ;
58+ }
59+
60+ @ Override
61+ public void write (Writer writer , TypeRef <? extends Object > type , @ Nullable Object value , WriteContext context ) throws IOException {
62+ if (!type .getRawType ().isArray ()) {
63+ throw new IllegalStateException (type .getRawType () + " is not an array" );
64+ }
65+
66+ if (value == null ) {
67+ writer .writeNull ();
68+ return ;
69+ }
70+
71+ TypeRef <Object > componentType = resolveComponentType (type );
72+
73+ writer .writeArrayStart ();
74+
75+ int length = Array .getLength (value );
76+
77+ for (int i = 0 ; i < length ; i ++) {
78+ context .write (writer , componentType , Array .get (value , i ));
79+ }
80+
81+ writer .writeArrayEnd ();
82+ }
83+
84+ private TypeRef <Object > resolveComponentType (TypeRef <?> arrayType ) {
85+ AnnotatedType type = arrayType .getAnnotatedType ();
86+ if (!(type instanceof AnnotatedArrayType )) {
87+ throw new IllegalStateException (arrayType .getType () + " is not an array type" );
88+ }
89+
90+ AnnotatedArrayType atype = (AnnotatedArrayType ) type ;
91+
92+ return TypeRef .of (atype .getAnnotatedGenericComponentType ());
93+ }
94+ }
0 commit comments