@@ -2690,6 +2690,46 @@ public void copyCurrentStructure(JsonParser p) throws IOException
26902690 }
26912691 }
26922692
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+
26932733 // @since 2.10
26942734 protected void _copyCurrentContents (JsonParser p ) throws IOException
26952735 {
@@ -2753,6 +2793,69 @@ protected void _copyCurrentContents(JsonParser p) throws IOException
27532793 }
27542794 }
27552795
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+
27562859 /**
27572860 * Method for copying current {@link JsonToken#VALUE_NUMBER_FLOAT} value;
27582861 * overridable by format backend implementations.
0 commit comments