@@ -2690,6 +2690,46 @@ public void copyCurrentStructure(JsonParser p) throws IOException
2690
2690
}
2691
2691
}
2692
2692
2693
+ /**
2694
+ * Same as {@link #copyCurrentStructure} with the exception that copying of numeric
2695
+ * values tries to avoid any conversion losses; in particular for floating-point
2696
+ * numbers. This usually matters when transcoding from textual format like JSON
2697
+ * to a binary format.
2698
+ * See {@link #_copyCurrentFloatValueExact} for details.
2699
+ *
2700
+ * @param p Parser that points to the value to copy
2701
+ *
2702
+ * @throws IOException if there is either an underlying I/O problem or encoding
2703
+ * issue at format layer
2704
+ *
2705
+ * @since 2.21
2706
+ */
2707
+ public void copyCurrentStructureExact (JsonParser p ) throws IOException
2708
+ {
2709
+ JsonToken t = p .currentToken ();
2710
+ // Let's handle field-name separately first
2711
+ int id = (t == null ) ? ID_NOT_AVAILABLE : t .id ();
2712
+ if (id == ID_FIELD_NAME ) {
2713
+ writeFieldName (p .currentName ());
2714
+ t = p .nextToken ();
2715
+ id = (t == null ) ? ID_NOT_AVAILABLE : t .id ();
2716
+ // fall-through to copy the associated value
2717
+ }
2718
+ switch (id ) {
2719
+ case ID_START_OBJECT :
2720
+ writeStartObject ();
2721
+ _copyCurrentContentsExact (p );
2722
+ return ;
2723
+ case ID_START_ARRAY :
2724
+ writeStartArray ();
2725
+ _copyCurrentContentsExact (p );
2726
+ return ;
2727
+
2728
+ default :
2729
+ copyCurrentEventExact (p );
2730
+ }
2731
+ }
2732
+
2693
2733
// @since 2.10
2694
2734
protected void _copyCurrentContents (JsonParser p ) throws IOException
2695
2735
{
@@ -2753,6 +2793,69 @@ protected void _copyCurrentContents(JsonParser p) throws IOException
2753
2793
}
2754
2794
}
2755
2795
2796
+ // @since 2.21
2797
+ protected void _copyCurrentContentsExact (JsonParser p ) throws IOException
2798
+ {
2799
+ int depth = 1 ;
2800
+ JsonToken t ;
2801
+
2802
+ // Mostly copied from `copyCurrentEventExact()`, but with added nesting counts
2803
+ while ((t = p .nextToken ()) != null ) {
2804
+ switch (t .id ()) {
2805
+ case ID_FIELD_NAME :
2806
+ writeFieldName (p .currentName ());
2807
+ break ;
2808
+
2809
+ case ID_START_ARRAY :
2810
+ writeStartArray ();
2811
+ ++depth ;
2812
+ break ;
2813
+
2814
+ case ID_START_OBJECT :
2815
+ writeStartObject ();
2816
+ ++depth ;
2817
+ break ;
2818
+
2819
+ case ID_END_ARRAY :
2820
+ writeEndArray ();
2821
+ if (--depth == 0 ) {
2822
+ return ;
2823
+ }
2824
+ break ;
2825
+ case ID_END_OBJECT :
2826
+ writeEndObject ();
2827
+ if (--depth == 0 ) {
2828
+ return ;
2829
+ }
2830
+ break ;
2831
+
2832
+ case ID_STRING :
2833
+ _copyCurrentStringValue (p );
2834
+ break ;
2835
+ case ID_NUMBER_INT :
2836
+ _copyCurrentIntValue (p );
2837
+ break ;
2838
+ case ID_NUMBER_FLOAT :
2839
+ _copyCurrentFloatValueExact (p );
2840
+ break ;
2841
+ case ID_TRUE :
2842
+ writeBoolean (true );
2843
+ break ;
2844
+ case ID_FALSE :
2845
+ writeBoolean (false );
2846
+ break ;
2847
+ case ID_NULL :
2848
+ writeNull ();
2849
+ break ;
2850
+ case ID_EMBEDDED_OBJECT :
2851
+ writeObject (p .getEmbeddedObject ());
2852
+ break ;
2853
+ default :
2854
+ throw new IllegalStateException ("Internal error: unknown current token, " +t );
2855
+ }
2856
+ }
2857
+ }
2858
+
2756
2859
/**
2757
2860
* Method for copying current {@link JsonToken#VALUE_NUMBER_FLOAT} value;
2758
2861
* overridable by format backend implementations.
0 commit comments