@@ -213,7 +213,6 @@ public T deserialize(JsonParser p, DeserializationContext ctxt, T existing) thro
213
213
@ SuppressWarnings ("unchecked" )
214
214
protected T handleNonArray (JsonParser p , DeserializationContext ctxt ) throws IOException
215
215
{
216
-
217
216
final boolean canWrap = (_unwrapSingle == Boolean .TRUE ) ||
218
217
((_unwrapSingle == null ) &&
219
218
ctxt .isEnabled (DeserializationFeature .ACCEPT_SINGLE_VALUE_AS_ARRAY ));
@@ -269,10 +268,8 @@ protected char[] _constructEmpty() {
269
268
@ Override
270
269
public char [] deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
271
270
{
272
- /* Won't take arrays, must get a String (could also
273
- * convert other tokens to Strings... but let's not bother
274
- * yet, doesn't seem to make sense)
275
- */
271
+ // Won't take arrays, must get a String (could also convert other tokens to Strings...
272
+ // but let's not bother yet, doesn't seem to make sense)
276
273
if (p .hasToken (JsonToken .VALUE_STRING )) {
277
274
// note: can NOT return shared internal buffer, must copy:
278
275
char [] buffer = p .getTextCharacters ();
@@ -483,6 +480,7 @@ public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
483
480
return (byte []) ctxt .handleWeirdStringValue (byte [].class ,
484
481
p .getText (), msg );
485
482
}
483
+ throw e ;
486
484
}
487
485
}
488
486
// 31-Dec-2009, tatu: Also may be hidden as embedded Object
@@ -821,6 +819,10 @@ protected float[] _constructEmpty() {
821
819
public float [] deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
822
820
{
823
821
if (!p .isExpectedStartArrayToken ()) {
822
+ float [] decoded = _deserializeBinaryVector (p , ctxt );
823
+ if (decoded != null ) {
824
+ return decoded ;
825
+ }
824
826
return handleNonArray (p , ctxt );
825
827
}
826
828
ArrayBuilders .FloatBuilder builder = ctxt .getArrayBuilders ().getFloatBuilder ();
@@ -864,6 +866,61 @@ protected float[] _concat(float[] oldValue, float[] newValue) {
864
866
System .arraycopy (newValue , 0 , result , len1 , len2 );
865
867
return result ;
866
868
}
869
+
870
+ private float [] _deserializeBinaryVector (JsonParser p , DeserializationContext ctxt )
871
+ throws IOException
872
+ {
873
+ JsonToken t = p .currentToken ();
874
+ byte [] packed = null ;
875
+
876
+ // Typical textual format case: base64 encoded String (for Packed Binary Vector)
877
+ if (t == JsonToken .VALUE_STRING ) {
878
+ try {
879
+ packed = p .getBinaryValue (ctxt .getBase64Variant ());
880
+ } catch (StreamReadException | DatabindException e ) {
881
+ // [databind#1425], try to convert to a more usable one, as it's not really
882
+ // a JSON-level parse exception, but rather binding from JSON String into
883
+ // base64 decoded binary data
884
+ String msg = e .getOriginalMessage ();
885
+ if (msg .contains ("base64" )) {
886
+ return (float []) ctxt .handleWeirdStringValue (float [].class ,
887
+ p .getText (), msg );
888
+ }
889
+ throw e ;
890
+ }
891
+ } else if (t == JsonToken .VALUE_EMBEDDED_OBJECT ) {
892
+ // Typical for binary formats
893
+ Object ob = p .getEmbeddedObject ();
894
+ if (ob instanceof byte []) {
895
+ packed = (byte []) ob ;
896
+ } else if (ob == null || (ob instanceof float [])) {
897
+ return (float []) ob ;
898
+ }
899
+ }
900
+ // Packed Binary Vector case
901
+ if (packed != null ) {
902
+ return _unpack (ctxt , packed );
903
+ }
904
+ return null ;
905
+ }
906
+
907
+ private float [] _unpack (DeserializationContext ctxt , byte [] bytes ) throws IOException {
908
+ final int bytesLen = bytes .length ;
909
+ if ((bytesLen & 3 ) != 0 ) {
910
+ return (float []) ctxt .reportInputMismatch (handledType (),
911
+ "Vector length for Packed Binary Float Vector (%d) not a multiple of 4 bytes" , bytesLen );
912
+ }
913
+ final int vectorLen = bytesLen >> 2 ;
914
+ final float [] floats = new float [vectorLen ];
915
+ for (int in = 0 , out = 0 ; in < bytesLen ; ) {
916
+ int packed = (bytes [in ++] << 24 )
917
+ | ((bytes [in ++] & 0xFF ) << 16 )
918
+ | ((bytes [in ++] & 0xFF ) << 8 )
919
+ | (bytes [in ++] & 0xFF );
920
+ floats [out ++] = Float .intBitsToFloat (packed );
921
+ }
922
+ return floats ;
923
+ }
867
924
}
868
925
869
926
@ JacksonStdImpl
@@ -892,6 +949,10 @@ protected double[] _constructEmpty() {
892
949
public double [] deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
893
950
{
894
951
if (!p .isExpectedStartArrayToken ()) {
952
+ double [] decoded = _deserializeBinaryVector (p , ctxt );
953
+ if (decoded != null ) {
954
+ return decoded ;
955
+ }
895
956
return handleNonArray (p , ctxt );
896
957
}
897
958
ArrayBuilders .DoubleBuilder builder = ctxt .getArrayBuilders ().getDoubleBuilder ();
@@ -934,5 +995,65 @@ protected double[] _concat(double[] oldValue, double[] newValue) {
934
995
System .arraycopy (newValue , 0 , result , len1 , len2 );
935
996
return result ;
936
997
}
998
+
999
+ private double [] _deserializeBinaryVector (JsonParser p , DeserializationContext ctxt )
1000
+ throws IOException
1001
+ {
1002
+ JsonToken t = p .currentToken ();
1003
+ byte [] packed = null ;
1004
+
1005
+ // Typical textual format case: base64 encoded String (for Packed Binary Vector)
1006
+ if (t == JsonToken .VALUE_STRING ) {
1007
+ try {
1008
+ packed = p .getBinaryValue (ctxt .getBase64Variant ());
1009
+ } catch (StreamReadException | DatabindException e ) {
1010
+ // [databind#1425], try to convert to a more usable one, as it's not really
1011
+ // a JSON-level parse exception, but rather binding from JSON String into
1012
+ // base64 decoded binary data
1013
+ String msg = e .getOriginalMessage ();
1014
+ if (msg .contains ("base64" )) {
1015
+ return (double []) ctxt .handleWeirdStringValue (double [].class ,
1016
+ p .getText (), msg );
1017
+ }
1018
+ throw e ;
1019
+ }
1020
+ } else if (t == JsonToken .VALUE_EMBEDDED_OBJECT ) {
1021
+ // Typical for binary formats
1022
+ Object ob = p .getEmbeddedObject ();
1023
+ if (ob instanceof byte []) {
1024
+ packed = (byte []) ob ;
1025
+ } else if (ob == null || (ob instanceof double [])) {
1026
+ return (double []) ob ;
1027
+ }
1028
+ }
1029
+ // Packed Binary Vector case
1030
+ if (packed != null ) {
1031
+ return _unpack (ctxt , packed );
1032
+ }
1033
+ return null ;
1034
+ }
1035
+
1036
+ private double [] _unpack (DeserializationContext ctxt , byte [] bytes ) throws IOException {
1037
+ final int bytesLen = bytes .length ;
1038
+ if ((bytesLen & 7 ) != 0 ) {
1039
+ return (double []) ctxt .reportInputMismatch (handledType (),
1040
+ "Vector length for Packed Binary Double Vector (%d) not a multiple of 8 bytes" , bytesLen );
1041
+ }
1042
+ final int vectorLen = bytesLen >> 3 ;
1043
+ final double [] doubles = new double [vectorLen ];
1044
+ for (int in = 0 , out = 0 ; in < bytesLen ; ) {
1045
+ int packed1 = (bytes [in ++] << 24 )
1046
+ | ((bytes [in ++] & 0xFF ) << 16 )
1047
+ | ((bytes [in ++] & 0xFF ) << 8 )
1048
+ | (bytes [in ++] & 0xFF );
1049
+ int packed2 = (bytes [in ++] << 24 )
1050
+ | ((bytes [in ++] & 0xFF ) << 16 )
1051
+ | ((bytes [in ++] & 0xFF ) << 8 )
1052
+ | (bytes [in ++] & 0xFF );
1053
+ long packed = ((long ) packed1 << 32 ) | (packed2 & 0xFFFFFFFFL );
1054
+ doubles [out ++] = Double .longBitsToDouble (packed );
1055
+ }
1056
+ return doubles ;
1057
+ }
937
1058
}
938
1059
}
0 commit comments