@@ -103,12 +103,11 @@ public ByteBuffer encode(
103103 if (valueBuff == null ) {
104104 throw new NullPointerException ("Vector elements cannot encode to CQL NULL" );
105105 }
106+ int elementSize = valueBuff .limit ();
106107 if (isVarSized ) {
107- int elementSize = valueBuff .limit ();
108- allValueBuffsSize += elementSize + VIntCoding .computeVIntSize (elementSize );
109- } else {
110- allValueBuffsSize += valueBuff .limit ();
108+ allValueBuffsSize += VIntCoding .computeVIntSize (elementSize );
111109 }
110+ allValueBuffsSize += elementSize ;
112111 valueBuff .rewind ();
113112 valueBuffs [i ] = valueBuff ;
114113 }
@@ -139,56 +138,52 @@ public CqlVector<SubtypeT> decode(
139138 if (bytes == null || bytes .remaining () == 0 ) {
140139 return null ;
141140 }
142- boolean isVarSized = !subtypeCodec .serializedSize ().isPresent ();
143- if (isVarSized ) {
144- ByteBuffer input = bytes .duplicate ();
145- List <SubtypeT > rv = new ArrayList <SubtypeT >(cqlType .getDimensions ());
146- for (int i = 0 ; i < cqlType .getDimensions (); ++i ) {
147- int size = VIntCoding .getUnsignedVInt32 (input , input .position ());
148- input .position (input .position () + VIntCoding .computeUnsignedVIntSize (size ));
149-
150- ByteBuffer value ;
151- if (size < 0 ) {
152- value = null ;
153- } else {
154- value = input .duplicate ();
155- value .limit (value .position () + size );
156- input .position (input .position () + size );
157- }
158- rv .add (subtypeCodec .decode (value , protocolVersion ));
159- }
160- // if too many elements, throw
161- if (input .hasRemaining ()) {
162- throw new IllegalArgumentException (
163- String .format (
164- "Too many elements; must provide elements for %d dimensions" ,
165- cqlType .getDimensions ()));
166- }
167141
168- return CqlVector .newInstance (rv );
169- } else {
170- int elementSize = subtypeCodec .serializedSize ().get ();
171- if (bytes .remaining () != cqlType .getDimensions () * elementSize ) {
172- throw new IllegalArgumentException (
173- String .format (
174- "Expected elements of uniform size, observed %d elements with total bytes %d" ,
175- cqlType .getDimensions (), bytes .remaining ()));
176- }
142+ // Upfront check for fixed-size types only
143+ subtypeCodec
144+ .serializedSize ()
145+ .ifPresent (
146+ (fixed_size ) -> {
147+ if (bytes .remaining () != cqlType .getDimensions () * fixed_size ) {
148+ throw new IllegalArgumentException (
149+ String .format (
150+ "Expected elements of uniform size, observed %d elements with total bytes %d" ,
151+ cqlType .getDimensions (), bytes .remaining ()));
152+ }
153+ });
154+ ;
155+ ByteBuffer slice = bytes .slice ();
156+ List <SubtypeT > rv = new ArrayList <SubtypeT >(cqlType .getDimensions ());
157+ for (int i = 0 ; i < cqlType .getDimensions (); ++i ) {
177158
178- ByteBuffer slice = bytes .slice ();
179- List <SubtypeT > rv = new ArrayList <SubtypeT >(cqlType .getDimensions ());
180- for (int i = 0 ; i < cqlType .getDimensions (); ++i ) {
181- // Set the limit for the current element
182- int originalPosition = slice .position ();
183- slice .limit (originalPosition + elementSize );
184- rv .add (this .subtypeCodec .decode (slice , protocolVersion ));
185- // Move to the start of the next element
186- slice .position (originalPosition + elementSize );
187- // Reset the limit to the end of the buffer
188- slice .limit (slice .capacity ());
189- }
190- return CqlVector .newInstance (rv );
159+ int size =
160+ subtypeCodec
161+ .serializedSize ()
162+ .orElseGet (() -> VIntCoding .getUnsignedVInt32 (slice , slice .position ()));
163+ // If we aren't dealing with a fixed-size type we need to move the current slice position
164+ // beyond the vint-encoded size of the current element. Ideally this would be
165+ // serializedSize().ifNotPresent(Consumer) but the Optional API isn't doing us any favors
166+ // there.
167+ if (!subtypeCodec .serializedSize ().isPresent ())
168+ slice .position (slice .position () + VIntCoding .computeUnsignedVIntSize (size ));
169+ int originalPosition = slice .position ();
170+ slice .limit (originalPosition + size );
171+ rv .add (this .subtypeCodec .decode (slice , protocolVersion ));
172+ // Move to the start of the next element
173+ slice .position (originalPosition + size );
174+ // Reset the limit to the end of the buffer
175+ slice .limit (slice .capacity ());
191176 }
177+
178+ // if too many elements, throw
179+ if (slice .hasRemaining ()) {
180+ throw new IllegalArgumentException (
181+ String .format (
182+ "Too many elements; must provide elements for %d dimensions" ,
183+ cqlType .getDimensions ()));
184+ }
185+
186+ return CqlVector .newInstance (rv );
192187 }
193188
194189 @ NonNull
0 commit comments