@@ -213,7 +213,6 @@ public T deserialize(JsonParser p, DeserializationContext ctxt, T existing) thro
213213 @ SuppressWarnings ("unchecked" )
214214 protected T handleNonArray (JsonParser p , DeserializationContext ctxt ) throws IOException
215215 {
216-
217216 final boolean canWrap = (_unwrapSingle == Boolean .TRUE ) ||
218217 ((_unwrapSingle == null ) &&
219218 ctxt .isEnabled (DeserializationFeature .ACCEPT_SINGLE_VALUE_AS_ARRAY ));
@@ -269,10 +268,8 @@ protected char[] _constructEmpty() {
269268 @ Override
270269 public char [] deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
271270 {
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)
276273 if (p .hasToken (JsonToken .VALUE_STRING )) {
277274 // note: can NOT return shared internal buffer, must copy:
278275 char [] buffer = p .getTextCharacters ();
@@ -483,6 +480,7 @@ public byte[] deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
483480 return (byte []) ctxt .handleWeirdStringValue (byte [].class ,
484481 p .getText (), msg );
485482 }
483+ throw e ;
486484 }
487485 }
488486 // 31-Dec-2009, tatu: Also may be hidden as embedded Object
@@ -821,6 +819,10 @@ protected float[] _constructEmpty() {
821819 public float [] deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
822820 {
823821 if (!p .isExpectedStartArrayToken ()) {
822+ float [] decoded = _deserializeBinaryVector (p , ctxt );
823+ if (decoded != null ) {
824+ return decoded ;
825+ }
824826 return handleNonArray (p , ctxt );
825827 }
826828 ArrayBuilders .FloatBuilder builder = ctxt .getArrayBuilders ().getFloatBuilder ();
@@ -864,6 +866,61 @@ protected float[] _concat(float[] oldValue, float[] newValue) {
864866 System .arraycopy (newValue , 0 , result , len1 , len2 );
865867 return result ;
866868 }
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+ }
867924 }
868925
869926 @ JacksonStdImpl
@@ -892,6 +949,10 @@ protected double[] _constructEmpty() {
892949 public double [] deserialize (JsonParser p , DeserializationContext ctxt ) throws IOException
893950 {
894951 if (!p .isExpectedStartArrayToken ()) {
952+ double [] decoded = _deserializeBinaryVector (p , ctxt );
953+ if (decoded != null ) {
954+ return decoded ;
955+ }
895956 return handleNonArray (p , ctxt );
896957 }
897958 ArrayBuilders .DoubleBuilder builder = ctxt .getArrayBuilders ().getDoubleBuilder ();
@@ -934,5 +995,65 @@ protected double[] _concat(double[] oldValue, double[] newValue) {
934995 System .arraycopy (newValue , 0 , result , len1 , len2 );
935996 return result ;
936997 }
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+ }
9371058 }
9381059}
0 commit comments