1 /* Jackson JSON-processor.
2 *
3 * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
4 */
5 package com.fasterxml.jackson.core;
6
7 import java.io.*;
8 import java.math.BigDecimal;
9 import java.math.BigInteger;
10 import java.util.concurrent.atomic.AtomicBoolean;
11 import java.util.concurrent.atomic.AtomicInteger;
12 import java.util.concurrent.atomic.AtomicLong;
13
14 import com.fasterxml.jackson.core.JsonParser.NumberType;
15 import com.fasterxml.jackson.core.io.CharacterEscapes;
16 import com.fasterxml.jackson.core.type.WritableTypeId;
17 import com.fasterxml.jackson.core.type.WritableTypeId.Inclusion;
18 import com.fasterxml.jackson.core.util.VersionUtil;
19
20 import static com.fasterxml.jackson.core.JsonTokenId.*;
21
22 /**
23 * Base class that defines public API for writing JSON content.
24 * Instances are created using factory methods of
25 * a {@link JsonFactory} instance.
26 *
27 * @author Tatu Saloranta
28 */
29 public abstract class JsonGenerator
30 implements Closeable, Flushable, Versioned
31 {
32 /**
33 * Enumeration that defines all togglable features for generators.
34 */
35 public enum Feature {
36 // // Low-level I/O / content features
37
38 /**
39 * Feature that determines whether generator will automatically
40 * close underlying output target that is NOT owned by the
41 * generator.
42 * If disabled, calling application has to separately
43 * close the underlying {@link OutputStream} and {@link Writer}
44 * instances used to create the generator. If enabled, generator
45 * will handle closing, as long as generator itself gets closed:
46 * this happens when end-of-input is encountered, or generator
47 * is closed by a call to {@link JsonGenerator#close}.
48 *<p>
49 * Feature is enabled by default.
50 */
51 AUTO_CLOSE_TARGET(true),
52
53 /**
54 * Feature that determines what happens when the generator is
55 * closed while there are still unmatched
56 * {@link JsonToken#START_ARRAY} or {@link JsonToken#START_OBJECT}
57 * entries in output content. If enabled, such Array(s) and/or
58 * Object(s) are automatically closed; if disabled, nothing
59 * specific is done.
60 *<p>
61 * Feature is enabled by default.
62 */
63 AUTO_CLOSE_JSON_CONTENT(true),
64
65 /**
66 * Feature that specifies that calls to {@link #flush} will cause
67 * matching <code>flush()</code> to underlying {@link OutputStream}
68 * or {@link Writer}; if disabled this will not be done.
69 * Main reason to disable this feature is to prevent flushing at
70 * generator level, if it is not possible to prevent method being
71 * called by other code (like <code>ObjectMapper</code> or third
72 * party libraries).
73 *<p>
74 * Feature is enabled by default.
75 */
76 FLUSH_PASSED_TO_STREAM(true),
77
78 // // Quoting-related features
79
80 /**
81 * Feature that determines whether JSON Object field names are
82 * quoted using double-quotes, as specified by JSON specification
83 * or not. Ability to disable quoting was added to support use
84 * cases where they are not usually expected, which most commonly
85 * occurs when used straight from Javascript.
86 *<p>
87 * Feature is enabled by default (since it is required by JSON specification).
88 *
89 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#QUOTE_FIELD_NAMES} instead
90 */
91 @Deprecated
92 QUOTE_FIELD_NAMES(true),
93
94 /**
95 * Feature that determines whether "exceptional" (not real number)
96 * float/double values are output as quoted strings.
97 * The values checked are Double.Nan,
98 * Double.POSITIVE_INFINITY and Double.NEGATIVE_INIFINTY (and
99 * associated Float values).
100 * If feature is disabled, these numbers are still output using
101 * associated literal values, resulting in non-conformant
102 * output.
103 *<p>
104 * Feature is enabled by default.
105 *
106 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#WRITE_NAN_AS_STRINGS} instead
107 */
108 @Deprecated
109 QUOTE_NON_NUMERIC_NUMBERS(true),
110
111 // // Character escaping features
112
113 /**
114 * Feature that specifies that all characters beyond 7-bit ASCII
115 * range (i.e. code points of 128 and above) need to be output
116 * using format-specific escapes (for JSON, backslash escapes),
117 * if format uses escaping mechanisms (which is generally true
118 * for textual formats but not for binary formats).
119 *<p>
120 * Note that this setting may not necessarily make sense for all
121 * data formats (for example, binary formats typically do not use
122 * any escaping mechanisms; and some textual formats do not have
123 * general-purpose escaping); if so, settings is simply ignored.
124 * Put another way, effects of this feature are data-format specific.
125 *<p>
126 * Feature is disabled by default.
127 *
128 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#ESCAPE_NON_ASCII} instead
129 */
130 @Deprecated
131 ESCAPE_NON_ASCII(false),
132
133 // // Datatype coercion features
134
135 /**
136 * Feature that forces all Java numbers to be written as Strings,
137 * even if the underlying data format has non-textual representation
138 * (which is the case for JSON as well as all binary formats).
139 * Default state is 'false', meaning that Java numbers are to
140 * be serialized using basic numeric serialization (as JSON
141 * numbers, integral or floating point, for example).
142 * If enabled, all such numeric values are instead written out as
143 * textual values (which for JSON means quoted in double-quotes).
144 *<p>
145 * One use case is to avoid problems with Javascript limitations:
146 * since Javascript standard specifies that all number handling
147 * should be done using 64-bit IEEE 754 floating point values,
148 * result being that some 64-bit integer values can not be
149 * accurately represent (as mantissa is only 51 bit wide).
150 *<p>
151 * Feature is disabled by default.
152 *
153 * @deprecated Since 2.10 use {@link com.fasterxml.jackson.core.json.JsonWriteFeature#WRITE_NUMBERS_AS_STRINGS} instead
154 */
155 @Deprecated
156 WRITE_NUMBERS_AS_STRINGS(false),
157
158 /**
159 * Feature that determines whether {@link java.math.BigDecimal} entries are
160 * serialized using {@link java.math.BigDecimal#toPlainString()} to prevent
161 * values to be written using scientific notation.
162 *<p>
163 * NOTE: only affects generators that serialize {@link java.math.BigDecimal}s
164 * using textual representation (textual formats but potentially some binary
165 * formats).
166 *<p>
167 * Feature is disabled by default, so default output mode is used; this generally
168 * depends on how {@link BigDecimal} has been created.
169 *
170 * @since 2.3
171 */
172 WRITE_BIGDECIMAL_AS_PLAIN(false),
173
174 // // Schema/Validity support features
175
176 /**
177 * Feature that determines whether {@link JsonGenerator} will explicitly
178 * check that no duplicate JSON Object field names are written.
179 * If enabled, generator will check all names within context and report
180 * duplicates by throwing a {@link JsonGenerationException}; if disabled,
181 * no such checking will be done. Assumption in latter case is
182 * that caller takes care of not trying to write duplicate names.
183 *<p>
184 * Note that enabling this feature will incur performance overhead
185 * due to having to store and check additional information.
186 *<p>
187 * Feature is disabled by default.
188 *
189 * @since 2.3
190 */
191 STRICT_DUPLICATE_DETECTION(false),
192
193 /**
194 * Feature that determines what to do if the underlying data format requires knowledge
195 * of all properties to output, and if no definition is found for a property that
196 * caller tries to write. If enabled, such properties will be quietly ignored;
197 * if disabled, a {@link JsonProcessingException} will be thrown to indicate the
198 * problem.
199 * Typically most textual data formats do NOT require schema information (although
200 * some do, such as CSV), whereas many binary data formats do require definitions
201 * (such as Avro, protobuf), although not all (Smile, CBOR, BSON and MessagePack do not).
202 *<p>
203 * Note that support for this feature is implemented by individual data format
204 * module, if (and only if) it makes sense for the format in question. For JSON,
205 * for example, this feature has no effect as properties need not be pre-defined.
206 *<p>
207 * Feature is disabled by default, meaning that if the underlying data format
208 * requires knowledge of all properties to output, attempts to write an unknown
209 * property will result in a {@link JsonProcessingException}
210 *
211 * @since 2.5
212 */
213 IGNORE_UNKNOWN(false),
214 ;
215
216 private final boolean _defaultState;
217 private final int _mask;
218
219 /**
220 * Method that calculates bit set (flags) of all features that
221 * are enabled by default.
222 */
223 public static int collectDefaults()
224 {
225 int flags = 0;
226 for (Feature f : values()) {
227 if (f.enabledByDefault()) {
228 flags |= f.getMask();
229 }
230 }
231 return flags;
232 }
233
234 private Feature(boolean defaultState) {
235 _defaultState = defaultState;
236 _mask = (1 << ordinal());
237 }
238
239 public boolean enabledByDefault() { return _defaultState; }
240
241 /**
242 * @since 2.3
243 */
244 public boolean enabledIn(int flags) { return (flags & _mask) != 0; }
245
246 public int getMask() { return _mask; }
247 }
248
249 /*
250 /**********************************************************
251 /* Configuration
252 /**********************************************************
253 */
254
255 /**
256 * Object that handles pretty-printing (usually additional
257 * white space to make results more human-readable) during
258 * output. If null, no pretty-printing is done.
259 */
260 protected PrettyPrinter _cfgPrettyPrinter;
261
262 /*
263 /**********************************************************
264 /* Construction, initialization
265 /**********************************************************
266 */
267
268 protected JsonGenerator() { }
269
270 /**
271 * Method that can be called to set or reset the object to
272 * use for writing Java objects as JsonContent
273 * (using method {@link #writeObject}).
274 *
275 * @return Generator itself (this), to allow chaining
276 */
277 public abstract JsonGenerator setCodec(ObjectCodec oc);
278
279 /**
280 * Method for accessing the object used for writing Java
281 * object as JSON content
282 * (using method {@link #writeObject}).
283 */
284 public abstract ObjectCodec getCodec();
285
286 /**
287 * Accessor for finding out version of the bundle that provided this generator instance.
288 */
289 @Override
290 public abstract Version version();
291
292 /*
293 /**********************************************************
294 /* Public API, Feature configuration
295 /**********************************************************
296 */
297
298 /**
299 * Method for enabling specified parser features:
300 * check {@link Feature} for list of available features.
301 *
302 * @return Generator itself (this), to allow chaining
303 */
304 public abstract JsonGenerator enable(Feature f);
305
306 /**
307 * Method for disabling specified features
308 * (check {@link Feature} for list of features)
309 *
310 * @return Generator itself (this), to allow chaining
311 */
312 public abstract JsonGenerator disable(Feature f);
313
314 /**
315 * Method for enabling or disabling specified feature:
316 * check {@link Feature} for list of available features.
317 *
318 * @return Generator itself (this), to allow chaining
319 */
320 public final JsonGenerator configure(Feature f, boolean state) {
321 if (state) enable(f); else disable(f);
322 return this;
323 }
324
325 /**
326 * Method for checking whether given feature is enabled.
327 * Check {@link Feature} for list of available features.
328 */
329 public abstract boolean isEnabled(Feature f);
330
331 /**
332 * @since 2.10
333 */
334 public boolean isEnabled(StreamWriteFeature f) {
335 return isEnabled(f.mappedFeature());
336 }
337
338 /**
339 * Bulk access method for getting state of all standard (non-dataformat-specific)
340 * {@link JsonGenerator.Feature}s.
341 *
342 * @return Bit mask that defines current states of all standard {@link JsonGenerator.Feature}s.
343 *
344 * @since 2.3
345 */
346 public abstract int getFeatureMask();
347
348 /**
349 * Bulk set method for (re)setting states of all standard {@link Feature}s
350 *
351 * @since 2.3
352 *
353 * @param values Bitmask that defines which {@link Feature}s are enabled
354 * and which disabled
355 *
356 * @return This parser object, to allow chaining of calls
357 *
358 * @deprecated Since 2.7, use {@link #overrideStdFeatures(int, int)} instead -- remove from 2.9
359 */
360 @Deprecated
361 public abstract JsonGenerator setFeatureMask(int values);
362
363 /**
364 * Bulk set method for (re)setting states of features specified by <code>mask</code>.
365 * Functionally equivalent to
366 *<code>
367 * int oldState = getFeatureMask();
368 * int newState = (oldState & ~mask) | (values & mask);
369 * setFeatureMask(newState);
370 *</code>
371 * but preferred as this lets caller more efficiently specify actual changes made.
372 *
373 * @param values Bit mask of set/clear state for features to change
374 * @param mask Bit mask of features to change
375 *
376 * @since 2.6
377 */
378 public JsonGenerator overrideStdFeatures(int values, int mask) {
379 int oldState = getFeatureMask();
380 int newState = (oldState & ~mask) | (values & mask);
381 return setFeatureMask(newState);
382 }
383
384 /**
385 * Bulk access method for getting state of all {@link FormatFeature}s, format-specific
386 * on/off configuration settings.
387 *
388 * @return Bit mask that defines current states of all standard {@link FormatFeature}s.
389 *
390 * @since 2.6
391 */
392 public int getFormatFeatures() {
393 return 0;
394 }
395
396 /**
397 * Bulk set method for (re)setting states of {@link FormatFeature}s,
398 * by specifying values (set / clear) along with a mask, to determine
399 * which features to change, if any.
400 *<p>
401 * Default implementation will simply throw an exception to indicate that
402 * the generator implementation does not support any {@link FormatFeature}s.
403 *
404 * @param values Bit mask of set/clear state for features to change
405 * @param mask Bit mask of features to change
406 *
407 * @since 2.6
408 */
409 public JsonGenerator overrideFormatFeatures(int values, int mask) {
410 // 08-Oct-2018, tatu: For 2.10 we actually do get `JsonWriteFeature`s, although they
411 // are (for 2.x only, not for 3.x) mapper to legacy settings. So do not freak out:
412 // throw new IllegalArgumentException("No FormatFeatures defined for generator of type "+getClass().getName());
413 return this;
414 }
415
416 /*
417 /**********************************************************
418 /* Public API, Schema configuration
419 /**********************************************************
420 */
421
422 /**
423 * Method to call to make this generator use specified schema.
424 * Method must be called before generating any content, right after instance
425 * has been created.
426 * Note that not all generators support schemas; and those that do usually only
427 * accept specific types of schemas: ones defined for data format this generator
428 * produces.
429 *<p>
430 * If generator does not support specified schema, {@link UnsupportedOperationException}
431 * is thrown.
432 *
433 * @param schema Schema to use
434 *
435 * @throws UnsupportedOperationException if generator does not support schema
436 */
437 public void setSchema(FormatSchema schema) {
438 throw new UnsupportedOperationException(String.format(
439 "Generator of type %s does not support schema of type '%s'",
440 getClass().getName(), schema.getSchemaType()));
441 }
442
443 /**
444 * Method for accessing Schema that this parser uses, if any.
445 * Default implementation returns null.
446 *
447 * @since 2.1
448 */
449 public FormatSchema getSchema() { return null; }
450
451 /*
452 /**********************************************************
453 /* Public API, other configuration
454 /**********************************************************
455 */
456
457 /**
458 * Method for setting a custom pretty printer, which is usually
459 * used to add indentation for improved human readability.
460 * By default, generator does not do pretty printing.
461 *<p>
462 * To use the default pretty printer that comes with core
463 * Jackson distribution, call {@link #useDefaultPrettyPrinter}
464 * instead.
465 *
466 * @return Generator itself (this), to allow chaining
467 */
468 public JsonGenerator setPrettyPrinter(PrettyPrinter pp) {
469 _cfgPrettyPrinter = pp;
470 return this;
471 }
472
473 /**
474 * Accessor for checking whether this generator has a configured
475 * {@link PrettyPrinter}; returns it if so, null if none configured.
476 *
477 * @since 2.1
478 */
479 public PrettyPrinter getPrettyPrinter() {
480 return _cfgPrettyPrinter;
481 }
482
483 /**
484 * Convenience method for enabling pretty-printing using
485 * the default pretty printer
486 * ({@link com.fasterxml.jackson.core.util.DefaultPrettyPrinter}).
487 *
488 * @return Generator itself (this), to allow chaining
489 */
490 public abstract JsonGenerator useDefaultPrettyPrinter();
491
492 /**
493 * Method that can be called to request that generator escapes
494 * all character codes above specified code point (if positive value);
495 * or, to not escape any characters except for ones that must be
496 * escaped for the data format (if -1).
497 * To force escaping of all non-ASCII characters, for example,
498 * this method would be called with value of 127.
499 *<p>
500 * Note that generators are NOT required to support setting of value
501 * higher than 127, because there are other ways to affect quoting
502 * (or lack thereof) of character codes between 0 and 127.
503 * Not all generators support concept of escaping, either; if so,
504 * calling this method will have no effect.
505 *<p>
506 * Default implementation does nothing; sub-classes need to redefine
507 * it according to rules of supported data format.
508 *
509 * @param charCode Either -1 to indicate that no additional escaping
510 * is to be done; or highest code point not to escape (meaning higher
511 * ones will be), if positive value.
512 */
513 public JsonGenerator setHighestNonEscapedChar(int charCode) { return this; }
514
515 /**
516 * Accessor method for testing what is the highest unescaped character
517 * configured for this generator. This may be either positive value
518 * (when escaping configuration has been set and is in effect), or
519 * 0 to indicate that no additional escaping is in effect.
520 * Some generators may not support additional escaping: for example,
521 * generators for binary formats that do not use escaping should
522 * simply return 0.
523 *
524 * @return Currently active limitation for highest non-escaped character,
525 * if defined; or 0 to indicate no additional escaping is performed.
526 */
527 public int getHighestEscapedChar() { return 0; }
528
529 /**
530 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
531 * it creates.
532 */
533 public CharacterEscapes getCharacterEscapes() { return null; }
534
535 /**
536 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
537 * it creates.
538 *<p>
539 * Default implementation does nothing and simply returns this instance.
540 */
541 public JsonGenerator setCharacterEscapes(CharacterEscapes esc) { return this; }
542
543 /**
544 * Method that allows overriding String used for separating root-level
545 * JSON values (default is single space character)
546 *<p>
547 * Default implementation throws {@link UnsupportedOperationException}.
548 *
549 * @param sep Separator to use, if any; null means that no separator is
550 * automatically added
551 *
552 * @since 2.1
553 */
554 public JsonGenerator setRootValueSeparator(SerializableString sep) {
555 throw new UnsupportedOperationException();
556 }
557
558 /*
559 /**********************************************************
560 /* Public API, output state access
561 /**********************************************************
562 */
563
564 /**
565 * Method that can be used to get access to object that is used
566 * as target for generated output; this is usually either
567 * {@link OutputStream} or {@link Writer}, depending on what
568 * generator was constructed with.
569 * Note that returned value may be null in some cases; including
570 * case where implementation does not want to exposed raw
571 * source to caller.
572 * In cases where output has been decorated, object returned here
573 * is the decorated version; this allows some level of interaction
574 * between users of generator and decorator object.
575 *<p>
576 * In general use of this accessor should be considered as
577 * "last effort", i.e. only used if no other mechanism is applicable.
578 */
579 public Object getOutputTarget() {
580 return null;
581 }
582
583 /**
584 * Method for verifying amount of content that is buffered by generator
585 * but not yet flushed to the underlying target (stream, writer),
586 * in units (byte, char) that the generator implementation uses for buffering;
587 * or -1 if this information is not available.
588 * Unit used is often the same as the unit of underlying target (that is,
589 * `byte` for {@link java.io.OutputStream}, `char` for {@link java.io.Writer}),
590 * but may differ if buffering is done before encoding.
591 * Default JSON-backed implementations do use matching units.
592 *<p>
593 * Note: non-JSON implementations will be retrofitted for 2.6 and beyond;
594 * please report if you see -1 (missing override)
595 *
596 * @return Amount of content buffered in internal units, if amount known and
597 * accessible; -1 if not accessible.
598 *
599 * @since 2.6
600 */
601 public int getOutputBuffered() {
602 return -1;
603 }
604
605 /**
606 * Helper method, usually equivalent to:
607 *<code>
608 * getOutputContext().getCurrentValue();
609 *</code>
610 *<p>
611 * Note that "current value" is NOT populated (or used) by Streaming parser;
612 * it is only used by higher-level data-binding functionality.
613 * The reason it is included here is that it can be stored and accessed hierarchically,
614 * and gets passed through data-binding.
615 *
616 * @since 2.5
617 */
618 public Object getCurrentValue() {
619 JsonStreamContext ctxt = getOutputContext();
620 return (ctxt == null) ? null : ctxt.getCurrentValue();
621 }
622
623 /**
624 * Helper method, usually equivalent to:
625 *<code>
626 * getOutputContext().setCurrentValue(v);
627 *</code>
628 *
629 * @since 2.5
630 */
631 public void setCurrentValue(Object v) {
632 JsonStreamContext ctxt = getOutputContext();
633 if (ctxt != null) {
634 ctxt.setCurrentValue(v);
635 }
636 }
637
638 /*
639 /**********************************************************
640 /* Public API, capability introspection methods
641 /**********************************************************
642 */
643
644 /**
645 * Method that can be used to verify that given schema can be used with
646 * this generator (using {@link #setSchema}).
647 *
648 * @param schema Schema to check
649 *
650 * @return True if this generator can use given schema; false if not
651 */
652 public boolean canUseSchema(FormatSchema schema) { return false; }
653
654 /**
655 * Introspection method that may be called to see if the underlying
656 * data format supports some kind of Object Ids natively (many do not;
657 * for example, JSON doesn't).
658 * This method <b>must</b> be called prior to calling
659 * {@link #writeObjectId} or {@link #writeObjectRef}.
660 *<p>
661 * Default implementation returns false; overridden by data formats
662 * that do support native Object Ids. Caller is expected to either
663 * use a non-native notation (explicit property or such), or fail,
664 * in case it can not use native object ids.
665 *
666 * @since 2.3
667 */
668 public boolean canWriteObjectId() { return false; }
669
670 /**
671 * Introspection method that may be called to see if the underlying
672 * data format supports some kind of Type Ids natively (many do not;
673 * for example, JSON doesn't).
674 * This method <b>must</b> be called prior to calling
675 * {@link #writeTypeId}.
676 *<p>
677 * Default implementation returns false; overridden by data formats
678 * that do support native Type Ids. Caller is expected to either
679 * use a non-native notation (explicit property or such), or fail,
680 * in case it can not use native type ids.
681 *
682 * @since 2.3
683 */
684 public boolean canWriteTypeId() { return false; }
685
686 /**
687 * Introspection method that may be called to see if the underlying
688 * data format supports "native" binary data; that is, an efficient
689 * output of binary content without encoding.
690 *<p>
691 * Default implementation returns false; overridden by data formats
692 * that do support native binary content.
693 *
694 * @since 2.3
695 */
696 public boolean canWriteBinaryNatively() { return false; }
697
698 /**
699 * Introspection method to call to check whether it is ok to omit
700 * writing of Object fields or not. Most formats do allow omission,
701 * but certain positional formats (such as CSV) require output of
702 * placeholders, even if no real values are to be emitted.
703 *
704 * @since 2.3
705 */
706 public boolean canOmitFields() { return true; }
707
708 /**
709 * Introspection method to call to check whether it is possible
710 * to write numbers using {@link #writeNumber(java.lang.String)}
711 * using possible custom format, or not. Typically textual formats
712 * allow this (and JSON specifically does), whereas binary formats
713 * do not allow this (except by writing them as Strings).
714 * Usual reason for calling this method is to check whether custom
715 * formatting of numbers may be applied by higher-level code (databinding)
716 * or not.
717 *
718 * @since 2.8
719 */
720 public boolean canWriteFormattedNumbers() { return false; }
721
722 /*
723 /**********************************************************
724 /* Public API, write methods, structural
725 /**********************************************************
726 */
727
728 /**
729 * Method for writing starting marker of a Array value
730 * (for JSON this is character '['; plus possible white space decoration
731 * if pretty-printing is enabled).
732 *<p>
733 * Array values can be written in any context where values
734 * are allowed: meaning everywhere except for when
735 * a field name is expected.
736 */
737 public abstract void writeStartArray() throws IOException;
738
739 // TODO: deprecate in 2.11 (remove from 3.0)
740 /**
741 * Method for writing start marker of an Array value, similar
742 * to {@link #writeStartArray()}, but also specifying how many
743 * elements will be written for the array before calling
744 * {@link #writeEndArray()}.
745 *<p>
746 * Default implementation simply calls {@link #writeStartArray()}.
747 *
748 * @param size Number of elements this array will have: actual
749 * number of values written (before matching call to
750 * {@link #writeEndArray()} MUST match; generator MAY verify
751 * this is the case.
752 *
753 * @since 2.4
754 */
755 public void writeStartArray(int size) throws IOException {
756 writeStartArray();
757 }
758
759 /**
760 * @since 2.10
761 */
762 public void writeStartArray(Object forValue) throws IOException {
763 writeStartArray();
764 setCurrentValue(forValue);
765 }
766
767 /**
768 * @since 2.10
769 */
770 public void writeStartArray(Object forValue, int size) throws IOException {
771 writeStartArray(size);
772 setCurrentValue(forValue);
773 }
774
775 /**
776 * Method for writing closing marker of a JSON Array value
777 * (character ']'; plus possible white space decoration
778 * if pretty-printing is enabled).
779 *<p>
780 * Marker can be written if the innermost structured type
781 * is Array.
782 */
783 public abstract void writeEndArray() throws IOException;
784
785 /**
786 * Method for writing starting marker of an Object value
787 * (character '{'; plus possible white space decoration
788 * if pretty-printing is enabled).
789 *<p>
790 * Object values can be written in any context where values
791 * are allowed: meaning everywhere except for when
792 * a field name is expected.
793 */
794 public abstract void writeStartObject() throws IOException;
795
796 /**
797 * Method for writing starting marker of an Object value
798 * to represent the given Java Object value.
799 * Argument is offered as metadata, but more
800 * importantly it should be assigned as the "current value"
801 * for the Object content that gets constructed and initialized.
802 *<p>
803 * Object values can be written in any context where values
804 * are allowed: meaning everywhere except for when
805 * a field name is expected.
806 *
807 * @since 2.8
808 */
809 public void writeStartObject(Object forValue) throws IOException
810 {
811 writeStartObject();
812 setCurrentValue(forValue);
813 }
814
815 /**
816 * Method for writing starting marker of an Object value
817 * to represent the given Java Object value.
818 * Argument is offered as metadata, but more
819 * importantly it should be assigned as the "current value"
820 * for the Object content that gets constructed and initialized.
821 * In addition, caller knows number of key/value pairs ("properties")
822 * that will get written for the Object value: this is relevant for
823 * some format backends (but not, as an example, for JSON).
824 *<p>
825 * Object values can be written in any context where values
826 * are allowed: meaning everywhere except for when
827 * a field name is expected.
828 *
829 * @since 2.10
830 */
831 public void writeStartObject(Object forValue, int size) throws IOException
832 {
833 writeStartObject();
834 setCurrentValue(forValue);
835 }
836
837 /**
838 * Method for writing closing marker of an Object value
839 * (character '}'; plus possible white space decoration
840 * if pretty-printing is enabled).
841 *<p>
842 * Marker can be written if the innermost structured type
843 * is Object, and the last written event was either a
844 * complete value, or START-OBJECT marker (see JSON specification
845 * for more details).
846 */
847 public abstract void writeEndObject() throws IOException;
848
849 /**
850 * Method for writing a field name (JSON String surrounded by
851 * double quotes: syntactically identical to a JSON String value),
852 * possibly decorated by white space if pretty-printing is enabled.
853 *<p>
854 * Field names can only be written in Object context (check out
855 * JSON specification for details), when field name is expected
856 * (field names alternate with values).
857 */
858 public abstract void writeFieldName(String name) throws IOException;
859
860 /**
861 * Method similar to {@link #writeFieldName(String)}, main difference
862 * being that it may perform better as some of processing (such as
863 * quoting of certain characters, or encoding into external encoding
864 * if supported by generator) can be done just once and reused for
865 * later calls.
866 *<p>
867 * Default implementation simple uses unprocessed name container in
868 * serialized String; implementations are strongly encouraged to make
869 * use of more efficient methods argument object has.
870 */
871 public abstract void writeFieldName(SerializableString name) throws IOException;
872
873 /**
874 * Alternative to {@link #writeFieldName(String)} that may be used
875 * in cases where property key is of numeric type; either where
876 * underlying format supports such notion (some binary formats do,
877 * unlike JSON), or for convenient conversion into String presentation.
878 * Default implementation will simply convert id into <code>String</code>
879 * and call {@link #writeFieldName(String)}.
880 *
881 * @since 2.8
882 */
883 public void writeFieldId(long id) throws IOException {
884 writeFieldName(Long.toString(id));
885 }
886
887 /*
888 /**********************************************************
889 /* Public API, write methods, scalar arrays (2.8)
890 /**********************************************************
891 */
892
893 /**
894 * Value write method that can be called to write a single
895 * array (sequence of {@link JsonToken#START_ARRAY}, zero or
896 * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY})
897 *
898 * @since 2.8
899 *
900 * @param array Array that contains values to write
901 * @param offset Offset of the first element to write, within array
902 * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
903 */
904 public void writeArray(int[] array, int offset, int length) throws IOException
905 {
906 if (array == null) {
907 throw new IllegalArgumentException("null array");
908 }
909 _verifyOffsets(array.length, offset, length);
910 writeStartArray(array, length);
911 for (int i = offset, end = offset+length; i < end; ++i) {
912 writeNumber(array[i]);
913 }
914 writeEndArray();
915 }
916
917 /**
918 * Value write method that can be called to write a single
919 * array (sequence of {@link JsonToken#START_ARRAY}, zero or
920 * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY})
921 *
922 * @since 2.8
923 *
924 * @param array Array that contains values to write
925 * @param offset Offset of the first element to write, within array
926 * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
927 */
928 public void writeArray(long[] array, int offset, int length) throws IOException
929 {
930 if (array == null) {
931 throw new IllegalArgumentException("null array");
932 }
933 _verifyOffsets(array.length, offset, length);
934 writeStartArray(array, length);
935 for (int i = offset, end = offset+length; i < end; ++i) {
936 writeNumber(array[i]);
937 }
938 writeEndArray();
939 }
940
941 /**
942 * Value write method that can be called to write a single
943 * array (sequence of {@link JsonToken#START_ARRAY}, zero or
944 * more {@link JsonToken#VALUE_NUMBER_FLOAT}, {@link JsonToken#END_ARRAY})
945 *
946 * @since 2.8
947 *
948 * @param array Array that contains values to write
949 * @param offset Offset of the first element to write, within array
950 * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
951 */
952 public void writeArray(double[] array, int offset, int length) throws IOException
953 {
954 if (array == null) {
955 throw new IllegalArgumentException("null array");
956 }
957 _verifyOffsets(array.length, offset, length);
958 writeStartArray(array, length);
959 for (int i = offset, end = offset+length; i < end; ++i) {
960 writeNumber(array[i]);
961 }
962 writeEndArray();
963 }
964
965 /**
966 * Value write method that can be called to write a single
967 * array (sequence of {@link JsonToken#START_ARRAY}, zero or
968 * more {@link JsonToken#VALUE_STRING}, {@link JsonToken#END_ARRAY})
969 *
970 * @since 2.11
971 *
972 * @param array Array that contains values to write
973 * @param offset Offset of the first element to write, within array
974 * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
975 */
976 public void writeArray(String[] array, int offset, int length) throws IOException
977 {
978 if (array == null) {
979 throw new IllegalArgumentException("null array");
980 }
981 _verifyOffsets(array.length, offset, length);
982 writeStartArray(array, length);
983 for (int i = offset, end = offset+length; i < end; ++i) {
984 writeString(array[i]);
985 }
986 writeEndArray();
987 }
988
989 /*
990 /**********************************************************
991 /* Public API, write methods, text/String values
992 /**********************************************************
993 */
994
995 /**
996 * Method for outputting a String value. Depending on context
997 * this means either array element, (object) field value or
998 * a stand alone String; but in all cases, String will be
999 * surrounded in double quotes, and contents will be properly
1000 * escaped as required by JSON specification.
1001 */
1002 public abstract void writeString(String text) throws IOException;
1003
1004 /**
1005 * Method for outputting a String value. Depending on context
1006 * this means either array element, (object) field value or
1007 * a stand alone String; but in all cases, String will be
1008 * surrounded in double quotes, and contents will be properly
1009 * escaped as required by JSON specification.
1010 * If the reader is null, then write a null.
1011 * If len is < 0, then write all contents of the reader.
1012 * Otherwise, write only len characters.
1013 *
1014 * @since 2.9
1015 */
1016 public void writeString(Reader reader, int len) throws IOException {
1017 // Let's implement this as "unsupported" to make it easier to add new parser impls
1018 _reportUnsupportedOperation();
1019 }
1020
1021 /**
1022 * Method for outputting a String value. Depending on context
1023 * this means either array element, (object) field value or
1024 * a stand alone String; but in all cases, String will be
1025 * surrounded in double quotes, and contents will be properly
1026 * escaped as required by JSON specification.
1027 */
1028 public abstract void writeString(char[] text, int offset, int len) throws IOException;
1029
1030 /**
1031 * Method similar to {@link #writeString(String)}, but that takes
1032 * {@link SerializableString} which can make this potentially
1033 * more efficient to call as generator may be able to reuse
1034 * quoted and/or encoded representation.
1035 *<p>
1036 * Default implementation just calls {@link #writeString(String)};
1037 * sub-classes should override it with more efficient implementation
1038 * if possible.
1039 */
1040 public abstract void writeString(SerializableString text) throws IOException;
1041
1042 /**
1043 * Method similar to {@link #writeString(String)} but that takes as
1044 * its input a UTF-8 encoded String that is to be output as-is, without additional
1045 * escaping (type of which depends on data format; backslashes for JSON).
1046 * However, quoting that data format requires (like double-quotes for JSON) will be added
1047 * around the value if and as necessary.
1048 *<p>
1049 * Note that some backends may choose not to support this method: for
1050 * example, if underlying destination is a {@link java.io.Writer}
1051 * using this method would require UTF-8 decoding.
1052 * If so, implementation may instead choose to throw a
1053 * {@link UnsupportedOperationException} due to ineffectiveness
1054 * of having to decode input.
1055 */
1056 public abstract void writeRawUTF8String(byte[] text, int offset, int length)
1057 throws IOException;
1058
1059 /**
1060 * Method similar to {@link #writeString(String)} but that takes as its input
1061 * a UTF-8 encoded String which has <b>not</b> been escaped using whatever
1062 * escaping scheme data format requires (for JSON that is backslash-escaping
1063 * for control characters and double-quotes; for other formats something else).
1064 * This means that textual JSON backends need to check if value needs
1065 * JSON escaping, but otherwise can just be copied as is to output.
1066 * Also, quoting that data format requires (like double-quotes for JSON) will be added
1067 * around the value if and as necessary.
1068 *<p>
1069 * Note that some backends may choose not to support this method: for
1070 * example, if underlying destination is a {@link java.io.Writer}
1071 * using this method would require UTF-8 decoding.
1072 * In this case
1073 * generator implementation may instead choose to throw a
1074 * {@link UnsupportedOperationException} due to ineffectiveness
1075 * of having to decode input.
1076 */
1077 public abstract void writeUTF8String(byte[] text, int offset, int length)
1078 throws IOException;
1079
1080 /*
1081 /**********************************************************
1082 /* Public API, write methods, binary/raw content
1083 /**********************************************************
1084 */
1085
1086 /**
1087 * Method that will force generator to copy
1088 * input text verbatim with <b>no</b> modifications (including
1089 * that no escaping is done and no separators are added even
1090 * if context [array, object] would otherwise require such).
1091 * If such separators are desired, use
1092 * {@link #writeRawValue(String)} instead.
1093 *<p>
1094 * Note that not all generator implementations necessarily support
1095 * such by-pass methods: those that do not will throw
1096 * {@link UnsupportedOperationException}.
1097 */
1098 public abstract void writeRaw(String text) throws IOException;
1099
1100 /**
1101 * Method that will force generator to copy
1102 * input text verbatim with <b>no</b> modifications (including
1103 * that no escaping is done and no separators are added even
1104 * if context [array, object] would otherwise require such).
1105 * If such separators are desired, use
1106 * {@link #writeRawValue(String)} instead.
1107 *<p>
1108 * Note that not all generator implementations necessarily support
1109 * such by-pass methods: those that do not will throw
1110 * {@link UnsupportedOperationException}.
1111 */
1112 public abstract void writeRaw(String text, int offset, int len) throws IOException;
1113
1114 /**
1115 * Method that will force generator to copy
1116 * input text verbatim with <b>no</b> modifications (including
1117 * that no escaping is done and no separators are added even
1118 * if context [array, object] would otherwise require such).
1119 * If such separators are desired, use
1120 * {@link #writeRawValue(String)} instead.
1121 *<p>
1122 * Note that not all generator implementations necessarily support
1123 * such by-pass methods: those that do not will throw
1124 * {@link UnsupportedOperationException}.
1125 */
1126 public abstract void writeRaw(char[] text, int offset, int len) throws IOException;
1127
1128 /**
1129 * Method that will force generator to copy
1130 * input text verbatim with <b>no</b> modifications (including
1131 * that no escaping is done and no separators are added even
1132 * if context [array, object] would otherwise require such).
1133 * If such separators are desired, use
1134 * {@link #writeRawValue(String)} instead.
1135 *<p>
1136 * Note that not all generator implementations necessarily support
1137 * such by-pass methods: those that do not will throw
1138 * {@link UnsupportedOperationException}.
1139 */
1140 public abstract void writeRaw(char c) throws IOException;
1141
1142 /**
1143 * Method that will force generator to copy
1144 * input text verbatim with <b>no</b> modifications (including
1145 * that no escaping is done and no separators are added even
1146 * if context [array, object] would otherwise require such).
1147 * If such separators are desired, use
1148 * {@link #writeRawValue(String)} instead.
1149 *<p>
1150 * Note that not all generator implementations necessarily support
1151 * such by-pass methods: those that do not will throw
1152 * {@link UnsupportedOperationException}.
1153 *<p>
1154 * The default implementation delegates to {@link #writeRaw(String)};
1155 * other backends that support raw inclusion of text are encouraged
1156 * to implement it in more efficient manner (especially if they
1157 * use UTF-8 encoding).
1158 *
1159 * @since 2.1
1160 */
1161 // public abstract void writeRaw(SerializableString raw) throws IOException;
1162 public void writeRaw(SerializableString raw) throws IOException {
1163 writeRaw(raw.getValue());
1164 }
1165
1166 /**
1167 * Method that will force generator to copy
1168 * input text verbatim without any modifications, but assuming
1169 * it must constitute a single legal JSON value (number, string,
1170 * boolean, null, Array or List). Assuming this, proper separators
1171 * are added if and as needed (comma or colon), and generator
1172 * state updated to reflect this.
1173 */
1174 public abstract void writeRawValue(String text) throws IOException;
1175
1176 public abstract void writeRawValue(String text, int offset, int len) throws IOException;
1177
1178 public abstract void writeRawValue(char[] text, int offset, int len) throws IOException;
1179
1180 /**
1181 * Method similar to {@link #writeRawValue(String)}, but potentially more
1182 * efficient as it may be able to use pre-encoded content (similar to
1183 * {@link #writeRaw(SerializableString)}.
1184 *
1185 * @since 2.5
1186 */
1187 public void writeRawValue(SerializableString raw) throws IOException {
1188 writeRawValue(raw.getValue());
1189 }
1190
1191 /**
1192 * Method that will output given chunk of binary data as base64
1193 * encoded, as a complete String value (surrounded by double quotes).
1194 * This method defaults
1195 *<p>
1196 * Note: because JSON Strings can not contain unescaped linefeeds,
1197 * if linefeeds are included (as per last argument), they must be
1198 * escaped. This adds overhead for decoding without improving
1199 * readability.
1200 * Alternatively if linefeeds are not included,
1201 * resulting String value may violate the requirement of base64
1202 * RFC which mandates line-length of 76 characters and use of
1203 * linefeeds. However, all {@link JsonParser} implementations
1204 * are required to accept such "long line base64"; as do
1205 * typical production-level base64 decoders.
1206 *
1207 * @param bv Base64 variant to use: defines details such as
1208 * whether padding is used (and if so, using which character);
1209 * what is the maximum line length before adding linefeed,
1210 * and also the underlying alphabet to use.
1211 */
1212 public abstract void writeBinary(Base64Variant bv,
1213 byte[] data, int offset, int len) throws IOException;
1214
1215 /**
1216 * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1217 * but default to using the Jackson default Base64 variant
1218 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).
1219 */
1220 public void writeBinary(byte[] data, int offset, int len) throws IOException {
1221 writeBinary(Base64Variants.getDefaultVariant(), data, offset, len);
1222 }
1223
1224 /**
1225 * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1226 * but assumes default to using the Jackson default Base64 variant
1227 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). Also
1228 * assumes that whole byte array is to be output.
1229 */
1230 public void writeBinary(byte[] data) throws IOException {
1231 writeBinary(Base64Variants.getDefaultVariant(), data, 0, data.length);
1232 }
1233
1234 /**
1235 * Similar to {@link #writeBinary(Base64Variant,InputStream,int)},
1236 * but assumes default to using the Jackson default Base64 variant
1237 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).
1238 *
1239 * @param data InputStream to use for reading binary data to write.
1240 * Will not be closed after successful write operation
1241 * @param dataLength (optional) number of bytes that will be available;
1242 * or -1 to be indicate it is not known. Note that implementations
1243 * need not support cases where length is not known in advance; this
1244 * depends on underlying data format: JSON output does NOT require length,
1245 * other formats may
1246 */
1247 public int writeBinary(InputStream data, int dataLength)
1248 throws IOException {
1249 return writeBinary(Base64Variants.getDefaultVariant(), data, dataLength);
1250 }
1251
1252 /**
1253 * Method similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1254 * but where input is provided through a stream, allowing for incremental
1255 * writes without holding the whole input in memory.
1256 *
1257 * @param bv Base64 variant to use
1258 * @param data InputStream to use for reading binary data to write.
1259 * Will not be closed after successful write operation
1260 * @param dataLength (optional) number of bytes that will be available;
1261 * or -1 to be indicate it is not known.
1262 * If a positive length is given, <code>data</code> MUST provide at least
1263 * that many bytes: if not, an exception will be thrown.
1264 * Note that implementations
1265 * need not support cases where length is not known in advance; this
1266 * depends on underlying data format: JSON output does NOT require length,
1267 * other formats may.
1268 *
1269 * @return Number of bytes read from <code>data</code> and written as binary payload
1270 *
1271 * @since 2.1
1272 */
1273 public abstract int writeBinary(Base64Variant bv,
1274 InputStream data, int dataLength) throws IOException;
1275
1276 /*
1277 /**********************************************************
1278 /* Public API, write methods, numeric
1279 /**********************************************************
1280 */
1281
1282 /**
1283 * Method for outputting given value as JSON number.
1284 * Can be called in any context where a value is expected
1285 * (Array value, Object field value, root-level value).
1286 * Additional white space may be added around the value
1287 * if pretty-printing is enabled.
1288 *
1289 * @param v Number value to write
1290 *
1291 * @since 2.2
1292 */
1293 public void writeNumber(short v) throws IOException { writeNumber((int) v); }
1294
1295 /**
1296 * Method for outputting given value as JSON number.
1297 * Can be called in any context where a value is expected
1298 * (Array value, Object field value, root-level value).
1299 * Additional white space may be added around the value
1300 * if pretty-printing is enabled.
1301 *
1302 * @param v Number value to write
1303 */
1304 public abstract void writeNumber(int v) throws IOException;
1305
1306 /**
1307 * Method for outputting given value as JSON number.
1308 * Can be called in any context where a value is expected
1309 * (Array value, Object field value, root-level value).
1310 * Additional white space may be added around the value
1311 * if pretty-printing is enabled.
1312 *
1313 * @param v Number value to write
1314 */
1315 public abstract void writeNumber(long v) throws IOException;
1316
1317 /**
1318 * Method for outputting given value as JSON number.
1319 * Can be called in any context where a value is expected
1320 * (Array value, Object field value, root-level value).
1321 * Additional white space may be added around the value
1322 * if pretty-printing is enabled.
1323 *
1324 * @param v Number value to write
1325 */
1326 public abstract void writeNumber(BigInteger v) throws IOException;
1327
1328 /**
1329 * Method for outputting indicate JSON numeric value.
1330 * Can be called in any context where a value is expected
1331 * (Array value, Object field value, root-level value).
1332 * Additional white space may be added around the value
1333 * if pretty-printing is enabled.
1334 *
1335 * @param v Number value to write
1336 */
1337 public abstract void writeNumber(double v) throws IOException;
1338
1339 /**
1340 * Method for outputting indicate JSON numeric value.
1341 * Can be called in any context where a value is expected
1342 * (Array value, Object field value, root-level value).
1343 * Additional white space may be added around the value
1344 * if pretty-printing is enabled.
1345 *
1346 * @param v Number value to write
1347 */
1348 public abstract void writeNumber(float v) throws IOException;
1349
1350 /**
1351 * Method for outputting indicate JSON numeric value.
1352 * Can be called in any context where a value is expected
1353 * (Array value, Object field value, root-level value).
1354 * Additional white space may be added around the value
1355 * if pretty-printing is enabled.
1356 *
1357 * @param v Number value to write
1358 */
1359 public abstract void writeNumber(BigDecimal v) throws IOException;
1360
1361 /**
1362 * Write method that can be used for custom numeric types that can
1363 * not be (easily?) converted to "standard" Java number types.
1364 * Because numbers are not surrounded by double quotes, regular
1365 * {@link #writeString} method can not be used; nor
1366 * {@link #writeRaw} because that does not properly handle
1367 * value separators needed in Array or Object contexts.
1368 *<p>
1369 * Note: because of lack of type safety, some generator
1370 * implementations may not be able to implement this
1371 * method. For example, if a binary JSON format is used,
1372 * it may require type information for encoding; similarly
1373 * for generator-wrappers around Java objects or JSON nodes.
1374 * If implementation does not implement this method,
1375 * it needs to throw {@link UnsupportedOperationException}.
1376 *
1377 * @throws UnsupportedOperationException If underlying data format does not
1378 * support numbers serialized textually AND if generator is not allowed
1379 * to just output a String instead (Schema-based formats may require actual
1380 * number, for example)
1381 */
1382 public abstract void writeNumber(String encodedValue) throws IOException;
1383
1384 /**
1385 * Overloaded version of {@link #writeNumber(String)} with same semantics
1386 * but possibly more efficient operation.
1387 *
1388 * @since 2.11
1389 */
1390 public void writeNumber(char[] encodedValueBuffer, int offset, int length) throws IOException {
1391 writeNumber(new String(encodedValueBuffer, offset, length));
1392 }
1393
1394 /*
1395 /**********************************************************
1396 /* Public API, write methods, other value types
1397 /**********************************************************
1398 */
1399
1400 /**
1401 * Method for outputting literal JSON boolean value (one of
1402 * Strings 'true' and 'false').
1403 * Can be called in any context where a value is expected
1404 * (Array value, Object field value, root-level value).
1405 * Additional white space may be added around the value
1406 * if pretty-printing is enabled.
1407 */
1408 public abstract void writeBoolean(boolean state) throws IOException;
1409
1410 /**
1411 * Method for outputting literal JSON null value.
1412 * Can be called in any context where a value is expected
1413 * (Array value, Object field value, root-level value).
1414 * Additional white space may be added around the value
1415 * if pretty-printing is enabled.
1416 */
1417 public abstract void writeNull() throws IOException;
1418
1419 /**
1420 * Method that can be called on backends that support passing opaque datatypes of
1421 * non-JSON formats
1422 *
1423 * @since 2.8
1424 */
1425 public void writeEmbeddedObject(Object object) throws IOException {
1426 // 01-Sep-2016, tatu: As per [core#318], handle small number of cases
1427 if (object == null) {
1428 writeNull();
1429 return;
1430 }
1431 if (object instanceof byte[]) {
1432 writeBinary((byte[]) object);
1433 return;
1434 }
1435 throw new JsonGenerationException("No native support for writing embedded objects of type "
1436 +object.getClass().getName(),
1437 this);
1438 }
1439
1440 /*
1441 /**********************************************************
1442 /* Public API, write methods, Native Ids (type, object)
1443 /**********************************************************
1444 */
1445
1446 /**
1447 * Method that can be called to output so-called native Object Id.
1448 * Note that it may only be called after ensuring this is legal
1449 * (with {@link #canWriteObjectId()}), as not all data formats
1450 * have native type id support; and some may only allow them in
1451 * certain positions or locations.
1452 * If output is not allowed by the data format in this position,
1453 * a {@link JsonGenerationException} will be thrown.
1454 *
1455 * @since 2.3
1456 */
1457 public void writeObjectId(Object id) throws IOException {
1458 throw new JsonGenerationException("No native support for writing Object Ids", this);
1459 }
1460
1461 /**
1462 * Method that can be called to output references to native Object Ids.
1463 * Note that it may only be called after ensuring this is legal
1464 * (with {@link #canWriteObjectId()}), as not all data formats
1465 * have native type id support; and some may only allow them in
1466 * certain positions or locations.
1467 * If output is not allowed by the data format in this position,
1468 * a {@link JsonGenerationException} will be thrown.
1469 */
1470 public void writeObjectRef(Object id) throws IOException {
1471 throw new JsonGenerationException("No native support for writing Object Ids", this);
1472 }
1473
1474 /**
1475 * Method that can be called to output so-called native Type Id.
1476 * Note that it may only be called after ensuring this is legal
1477 * (with {@link #canWriteTypeId()}), as not all data formats
1478 * have native type id support; and some may only allow them in
1479 * certain positions or locations.
1480 * If output is not allowed by the data format in this position,
1481 * a {@link JsonGenerationException} will be thrown.
1482 *
1483 * @since 2.3
1484 */
1485 public void writeTypeId(Object id) throws IOException {
1486 throw new JsonGenerationException("No native support for writing Type Ids", this);
1487 }
1488
1489 /*
1490 * Replacement method for {@link #writeTypeId(Object)} which is called
1491 * regardless of whether format has native type ids. If it does have native
1492 * type ids, those are to be used (if configuration allows this), if not,
1493 * structural type id inclusion is to be used. For JSON, for example, no
1494 * native type ids exist and structural inclusion is always used.
1495 *<p>
1496 * NOTE: databind may choose to skip calling this method for some special cases
1497 * (and instead included type id via regular write methods and/or {@link #writeTypeId}
1498 * -- this is discouraged, but not illegal, and may be necessary as a work-around
1499 * in some cases.
1500 *
1501 * @since 2.9
1502 */
1503 public WritableTypeId writeTypePrefix(WritableTypeId typeIdDef) throws IOException
1504 {
1505 Object id = typeIdDef.id;
1506
1507 final JsonToken valueShape = typeIdDef.valueShape;
1508 if (canWriteTypeId()) {
1509 typeIdDef.wrapperWritten = false;
1510 // just rely on native type output method (sub-classes likely to override)
1511 writeTypeId(id);
1512 } else {
1513 // No native type id; write wrappers
1514 // Normally we only support String type ids (non-String reserved for native type ids)
1515 String idStr = (id instanceof String) ? (String) id : String.valueOf(id);
1516 typeIdDef.wrapperWritten = true;
1517
1518 Inclusion incl = typeIdDef.include;
1519 // first: can not output "as property" if value not Object; if so, must do "as array"
1520 if ((valueShape != JsonToken.START_OBJECT)
1521 && incl.requiresObjectContext()) {
1522 typeIdDef.include = incl = WritableTypeId.Inclusion.WRAPPER_ARRAY;
1523 }
1524
1525 switch (incl) {
1526 case PARENT_PROPERTY:
1527 // nothing to do here, as it has to be written in suffix...
1528 break;
1529 case PAYLOAD_PROPERTY:
1530 // only output as native type id; otherwise caller must handle using some
1531 // other mechanism, so...
1532 break;
1533 case METADATA_PROPERTY:
1534 // must have Object context by now, so simply write as field name
1535 // Note, too, that it's bit tricky, since we must print START_OBJECT that is part
1536 // of value first -- and then NOT output it later on: hence return "early"
1537 writeStartObject(typeIdDef.forValue);
1538 writeStringField(typeIdDef.asProperty, idStr);
1539 return typeIdDef;
1540
1541 case WRAPPER_OBJECT:
1542 // NOTE: this is wrapper, not directly related to value to output, so don't pass
1543 writeStartObject();
1544 writeFieldName(idStr);
1545 break;
1546 case WRAPPER_ARRAY:
1547 default: // should never occur but translate as "as-array"
1548 writeStartArray(); // wrapper, not actual array object to write
1549 writeString(idStr);
1550 }
1551 }
1552 // and finally possible start marker for value itself:
1553 if (valueShape == JsonToken.START_OBJECT) {
1554 writeStartObject(typeIdDef.forValue);
1555 } else if (valueShape == JsonToken.START_ARRAY) {
1556 // should we now set the current object?
1557 writeStartArray();
1558 }
1559 return typeIdDef;
1560 }
1561
1562 /*
1563 * @since 2.9
1564 */
1565 public WritableTypeId writeTypeSuffix(WritableTypeId typeIdDef) throws IOException
1566 {
1567 final JsonToken valueShape = typeIdDef.valueShape;
1568 // First: does value need closing?
1569 if (valueShape == JsonToken.START_OBJECT) {
1570 writeEndObject();
1571 } else if (valueShape == JsonToken.START_ARRAY) {
1572 writeEndArray();
1573 }
1574
1575 if (typeIdDef.wrapperWritten) {
1576 switch (typeIdDef.include) {
1577 case WRAPPER_ARRAY:
1578 writeEndArray();
1579 break;
1580 case PARENT_PROPERTY:
1581 // unusually, need to output AFTER value. And no real wrapper...
1582 {
1583 Object id = typeIdDef.id;
1584 String idStr = (id instanceof String) ? (String) id : String.valueOf(id);
1585 writeStringField(typeIdDef.asProperty, idStr);
1586 }
1587 break;
1588 case METADATA_PROPERTY:
1589 case PAYLOAD_PROPERTY:
1590 // no actual wrapper; included within Object itself
1591 break;
1592 case WRAPPER_OBJECT:
1593 default: // should never occur but...
1594 writeEndObject();
1595 break;
1596 }
1597 }
1598 return typeIdDef;
1599 }
1600
1601 /*
1602 /**********************************************************
1603 /* Public API, write methods, serializing Java objects
1604 /**********************************************************
1605 */
1606
1607 /**
1608 * Method for writing given Java object (POJO) as Json.
1609 * Exactly how the object gets written depends on object
1610 * in question (ad on codec, its configuration); for most
1611 * beans it will result in JSON Object, but for others JSON
1612 * Array, or String or numeric value (and for nulls, JSON
1613 * null literal.
1614 * <b>NOTE</b>: generator must have its <b>object codec</b>
1615 * set to non-null value; for generators created by a mapping
1616 * factory this is the case, for others not.
1617 */
1618 public abstract void writeObject(Object pojo) throws IOException;
1619
1620 /**
1621 * Method for writing given JSON tree (expressed as a tree
1622 * where given JsonNode is the root) using this generator.
1623 * This will generally just call
1624 * {@link #writeObject} with given node, but is added
1625 * for convenience and to make code more explicit in cases
1626 * where it deals specifically with trees.
1627 */
1628 public abstract void writeTree(TreeNode rootNode) throws IOException;
1629
1630 /*
1631 /**********************************************************
1632 /* Public API, convenience field write methods
1633 /**********************************************************
1634 */
1635
1636 // 04-Oct-2019, tatu: Reminder: these could be defined final to
1637 // remember NOT to override in delegating sub-classes -- but
1638 // not final in 2.x to reduce compatibility issues
1639
1640 /**
1641 * Convenience method for outputting a field entry ("member")
1642 * that contains specified data in base64-encoded form.
1643 * Equivalent to:
1644 *<pre>
1645 * writeFieldName(fieldName);
1646 * writeBinary(value);
1647 *</pre>
1648 */
1649 public void writeBinaryField(String fieldName, byte[] data) throws IOException {
1650 writeFieldName(fieldName);
1651 writeBinary(data);
1652 }
1653
1654 /**
1655 * Convenience method for outputting a field entry ("member")
1656 * that has a boolean value. Equivalent to:
1657 *<pre>
1658 * writeFieldName(fieldName);
1659 * writeBoolean(value);
1660 *</pre>
1661 */
1662 public void writeBooleanField(String fieldName, boolean value) throws IOException {
1663 writeFieldName(fieldName);
1664 writeBoolean(value);
1665 }
1666
1667 /**
1668 * Convenience method for outputting a field entry ("member")
1669 * that has JSON literal value null. Equivalent to:
1670 *<pre>
1671 * writeFieldName(fieldName);
1672 * writeNull();
1673 *</pre>
1674 */
1675 public void writeNullField(String fieldName) throws IOException {
1676 writeFieldName(fieldName);
1677 writeNull();
1678 }
1679
1680 /**
1681 * Convenience method for outputting a field entry ("member")
1682 * that has a String value. Equivalent to:
1683 *<pre>
1684 * writeFieldName(fieldName);
1685 * writeString(value);
1686 *</pre>
1687 *<p>
1688 * Note: many performance-sensitive implementations override this method
1689 */
1690 public void writeStringField(String fieldName, String value) throws IOException {
1691 writeFieldName(fieldName);
1692 writeString(value);
1693 }
1694
1695 /**
1696 * Convenience method for outputting a field entry ("member")
1697 * that has the specified numeric value. Equivalent to:
1698 *<pre>
1699 * writeFieldName(fieldName);
1700 * writeNumber(value);
1701 *</pre>
1702 *
1703 * @since 2.11
1704 */
1705 public void writeNumberField(String fieldName, short value) throws IOException {
1706 writeFieldName(fieldName);
1707 writeNumber(value);
1708 }
1709
1710 /**
1711 * Convenience method for outputting a field entry ("member")
1712 * that has the specified numeric value. Equivalent to:
1713 *<pre>
1714 * writeFieldName(fieldName);
1715 * writeNumber(value);
1716 *</pre>
1717 */
1718 public void writeNumberField(String fieldName, int value) throws IOException {
1719 writeFieldName(fieldName);
1720 writeNumber(value);
1721 }
1722
1723 /**
1724 * Convenience method for outputting a field entry ("member")
1725 * that has the specified numeric value. Equivalent to:
1726 *<pre>
1727 * writeFieldName(fieldName);
1728 * writeNumber(value);
1729 *</pre>
1730 */
1731 public void writeNumberField(String fieldName, long value) throws IOException {
1732 writeFieldName(fieldName);
1733 writeNumber(value);
1734 }
1735
1736 /**
1737 * Convenience method for outputting a field entry ("member")
1738 * that has the specified numeric value. Equivalent to:
1739 *<pre>
1740 * writeFieldName(fieldName);
1741 * writeNumber(value);
1742 *</pre>
1743 *
1744 * @since 2.11
1745 */
1746 public void writeNumberField(String fieldName, BigInteger value) throws IOException {
1747 writeFieldName(fieldName);
1748 writeNumber(value);
1749 }
1750
1751 /**
1752 * Convenience method for outputting a field entry ("member")
1753 * that has the specified numeric value. Equivalent to:
1754 *<pre>
1755 * writeFieldName(fieldName);
1756 * writeNumber(value);
1757 *</pre>
1758 */
1759 public void writeNumberField(String fieldName, float value) throws IOException {
1760 writeFieldName(fieldName);
1761 writeNumber(value);
1762 }
1763
1764 /**
1765 * Convenience method for outputting a field entry ("member")
1766 * that has the specified numeric value. Equivalent to:
1767 *<pre>
1768 * writeFieldName(fieldName);
1769 * writeNumber(value);
1770 *</pre>
1771 */
1772 public void writeNumberField(String fieldName, double value) throws IOException {
1773 writeFieldName(fieldName);
1774 writeNumber(value);
1775 }
1776
1777 /**
1778 * Convenience method for outputting a field entry ("member")
1779 * that has the specified numeric value.
1780 * Equivalent to:
1781 *<pre>
1782 * writeFieldName(fieldName);
1783 * writeNumber(value);
1784 *</pre>
1785 */
1786 public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
1787 writeFieldName(fieldName);
1788 writeNumber(value);
1789 }
1790
1791 /**
1792 * Convenience method for outputting a field entry ("member")
1793 * (that will contain a JSON Array value), and the START_ARRAY marker.
1794 * Equivalent to:
1795 *<pre>
1796 * writeFieldName(fieldName);
1797 * writeStartArray();
1798 *</pre>
1799 *<p>
1800 * Note: caller still has to take care to close the array
1801 * (by calling {#link #writeEndArray}) after writing all values
1802 * of the value Array.
1803 */
1804 public void writeArrayFieldStart(String fieldName) throws IOException {
1805 writeFieldName(fieldName);
1806 writeStartArray();
1807 }
1808
1809 /**
1810 * Convenience method for outputting a field entry ("member")
1811 * (that will contain an Object value), and the START_OBJECT marker.
1812 * Equivalent to:
1813 *<pre>
1814 * writeFieldName(fieldName);
1815 * writeStartObject();
1816 *</pre>
1817 *<p>
1818 * Note: caller still has to take care to close the Object
1819 * (by calling {#link #writeEndObject}) after writing all
1820 * entries of the value Object.
1821 */
1822 public void writeObjectFieldStart(String fieldName) throws IOException {
1823 writeFieldName(fieldName);
1824 writeStartObject();
1825 }
1826
1827 /**
1828 * Convenience method for outputting a field entry ("member")
1829 * that has contents of specific Java object as its value.
1830 * Equivalent to:
1831 *<pre>
1832 * writeFieldName(fieldName);
1833 * writeObject(pojo);
1834 *</pre>
1835 */
1836 public void writeObjectField(String fieldName, Object pojo) throws IOException {
1837 writeFieldName(fieldName);
1838 writeObject(pojo);
1839 }
1840
1841 // // // But this method does need to be delegate so...
1842
1843 /**
1844 * Method called to indicate that a property in this position was
1845 * skipped. It is usually only called for generators that return
1846 * <code>false</code> from {@link #canOmitFields()}.
1847 *<p>
1848 * Default implementation does nothing.
1849 *
1850 * @since 2.3
1851 */
1852 public void writeOmittedField(String fieldName) throws IOException { }
1853
1854 /*
1855 /**********************************************************
1856 /* Public API, copy-through methods
1857 /**********************************************************
1858 */
1859
1860 /**
1861 * Method for copying contents of the current event that
1862 * the given parser instance points to.
1863 * Note that the method <b>will not</b> copy any other events,
1864 * such as events contained within JSON Array or Object structures.
1865 *<p>
1866 * Calling this method will not advance the given
1867 * parser, although it may cause parser to internally process
1868 * more data (if it lazy loads contents of value events, for example)
1869 */
1870 public void copyCurrentEvent(JsonParser p) throws IOException
1871 {
1872 JsonToken t = p.currentToken();
1873 final int token = (t == null) ? ID_NOT_AVAILABLE : t.id();
1874 switch (token) {
1875 case ID_NOT_AVAILABLE:
1876 _reportError("No current event to copy");
1877 break; // never gets here
1878 case ID_START_OBJECT:
1879 writeStartObject();
1880 break;
1881 case ID_END_OBJECT:
1882 writeEndObject();
1883 break;
1884 case ID_START_ARRAY:
1885 writeStartArray();
1886 break;
1887 case ID_END_ARRAY:
1888 writeEndArray();
1889 break;
1890 case ID_FIELD_NAME:
1891 writeFieldName(p.getCurrentName());
1892 break;
1893 case ID_STRING:
1894 if (p.hasTextCharacters()) {
1895 writeString(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
1896 } else {
1897 writeString(p.getText());
1898 }
1899 break;
1900 case ID_NUMBER_INT:
1901 {
1902 NumberType n = p.getNumberType();
1903 if (n == NumberType.INT) {
1904 writeNumber(p.getIntValue());
1905 } else if (n == NumberType.BIG_INTEGER) {
1906 writeNumber(p.getBigIntegerValue());
1907 } else {
1908 writeNumber(p.getLongValue());
1909 }
1910 break;
1911 }
1912 case ID_NUMBER_FLOAT:
1913 {
1914 NumberType n = p.getNumberType();
1915 if (n == NumberType.BIG_DECIMAL) {
1916 writeNumber(p.getDecimalValue());
1917 } else if (n == NumberType.FLOAT) {
1918 writeNumber(p.getFloatValue());
1919 } else {
1920 writeNumber(p.getDoubleValue());
1921 }
1922 break;
1923 }
1924 case ID_TRUE:
1925 writeBoolean(true);
1926 break;
1927 case ID_FALSE:
1928 writeBoolean(false);
1929 break;
1930 case ID_NULL:
1931 writeNull();
1932 break;
1933 case ID_EMBEDDED_OBJECT:
1934 writeObject(p.getEmbeddedObject());
1935 break;
1936 default:
1937 throw new IllegalStateException("Internal error: unknown current token, "+t);
1938 }
1939 }
1940
1941 /**
1942 * Method for copying contents of the current event
1943 * <b>and following events that it encloses</b>
1944 * the given parser instance points to.
1945 *<p>
1946 * So what constitutes enclosing? Here is the list of
1947 * events that have associated enclosed events that will
1948 * get copied:
1949 *<ul>
1950 * <li>{@link JsonToken#START_OBJECT}:
1951 * all events up to and including matching (closing)
1952 * {@link JsonToken#END_OBJECT} will be copied
1953 * </li>
1954 * <li>{@link JsonToken#START_ARRAY}
1955 * all events up to and including matching (closing)
1956 * {@link JsonToken#END_ARRAY} will be copied
1957 * </li>
1958 * <li>{@link JsonToken#FIELD_NAME} the logical value (which
1959 * can consist of a single scalar value; or a sequence of related
1960 * events for structured types (JSON Arrays, Objects)) will
1961 * be copied along with the name itself. So essentially the
1962 * whole <b>field entry</b> (name and value) will be copied.
1963 * </li>
1964 *</ul>
1965 *<p>
1966 * After calling this method, parser will point to the
1967 * <b>last event</b> that was copied. This will either be
1968 * the event parser already pointed to (if there were no
1969 * enclosed events), or the last enclosed event copied.
1970 */
1971 public void copyCurrentStructure(JsonParser p) throws IOException
1972 {
1973 JsonToken t = p.currentToken();
1974 // Let's handle field-name separately first
1975 int id = (t == null) ? ID_NOT_AVAILABLE : t.id();
1976 if (id == ID_FIELD_NAME) {
1977 writeFieldName(p.getCurrentName());
1978 t = p.nextToken();
1979 id = (t == null) ? ID_NOT_AVAILABLE : t.id();
1980 // fall-through to copy the associated value
1981 }
1982 switch (id) {
1983 case ID_START_OBJECT:
1984 writeStartObject();
1985 _copyCurrentContents(p);
1986 return;
1987 case ID_START_ARRAY:
1988 writeStartArray();
1989 _copyCurrentContents(p);
1990 return;
1991
1992 default:
1993 copyCurrentEvent(p);
1994 }
1995 }
1996
1997 /**
1998 * @since 2.10
1999 */
2000 protected void _copyCurrentContents(JsonParser p) throws IOException
2001 {
2002 int depth = 1;
2003 JsonToken t;
2004
2005 // Mostly copied from `copyCurrentEvent()`, but with added nesting counts
2006 while ((t = p.nextToken()) != null) {
2007 switch (t.id()) {
2008 case ID_FIELD_NAME:
2009 writeFieldName(p.getCurrentName());
2010 break;
2011
2012 case ID_START_ARRAY:
2013 writeStartArray();
2014 ++depth;
2015 break;
2016
2017 case ID_START_OBJECT:
2018 writeStartObject();
2019 ++depth;
2020 break;
2021
2022 case ID_END_ARRAY:
2023 writeEndArray();
2024 if (--depth == 0) {
2025 return;
2026 }
2027 break;
2028 case ID_END_OBJECT:
2029 writeEndObject();
2030 if (--depth == 0) {
2031 return;
2032 }
2033 break;
2034
2035 case ID_STRING:
2036 if (p.hasTextCharacters()) {
2037 writeString(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
2038 } else {
2039 writeString(p.getText());
2040 }
2041 break;
2042 case ID_NUMBER_INT:
2043 {
2044 NumberType n = p.getNumberType();
2045 if (n == NumberType.INT) {
2046 writeNumber(p.getIntValue());
2047 } else if (n == NumberType.BIG_INTEGER) {
2048 writeNumber(p.getBigIntegerValue());
2049 } else {
2050 writeNumber(p.getLongValue());
2051 }
2052 break;
2053 }
2054 case ID_NUMBER_FLOAT:
2055 {
2056 NumberType n = p.getNumberType();
2057 if (n == NumberType.BIG_DECIMAL) {
2058 writeNumber(p.getDecimalValue());
2059 } else if (n == NumberType.FLOAT) {
2060 writeNumber(p.getFloatValue());
2061 } else {
2062 writeNumber(p.getDoubleValue());
2063 }
2064 break;
2065 }
2066 case ID_TRUE:
2067 writeBoolean(true);
2068 break;
2069 case ID_FALSE:
2070 writeBoolean(false);
2071 break;
2072 case ID_NULL:
2073 writeNull();
2074 break;
2075 case ID_EMBEDDED_OBJECT:
2076 writeObject(p.getEmbeddedObject());
2077 break;
2078 default:
2079 throw new IllegalStateException("Internal error: unknown current token, "+t);
2080 }
2081 }
2082 }
2083
2084 /*
2085 /**********************************************************
2086 /* Public API, context access
2087 /**********************************************************
2088 */
2089
2090 /**
2091 * @return Context object that can give information about logical
2092 * position within generated json content.
2093 */
2094 public abstract JsonStreamContext getOutputContext();
2095
2096 /*
2097 /**********************************************************
2098 /* Public API, buffer handling
2099 /**********************************************************
2100 */
2101
2102 /**
2103 * Method called to flush any buffered content to the underlying
2104 * target (output stream, writer), and to flush the target itself
2105 * as well.
2106 */
2107 @Override
2108 public abstract void flush() throws IOException;
2109
2110 /**
2111 * Method that can be called to determine whether this generator
2112 * is closed or not. If it is closed, no more output can be done.
2113 */
2114 public abstract boolean isClosed();
2115
2116 /*
2117 /**********************************************************
2118 /* Closeable implementation
2119 /**********************************************************
2120 */
2121
2122 /**
2123 * Method called to close this generator, so that no more content
2124 * can be written.
2125 *<p>
2126 * Whether the underlying target (stream, writer) gets closed depends
2127 * on whether this generator either manages the target (i.e. is the
2128 * only one with access to the target -- case if caller passes a
2129 * reference to the resource such as File, but not stream); or
2130 * has feature {@link Feature#AUTO_CLOSE_TARGET} enabled.
2131 * If either of above is true, the target is also closed. Otherwise
2132 * (not managing, feature not enabled), target is not closed.
2133 */
2134 @Override
2135 public abstract void close() throws IOException;
2136
2137 /*
2138 /**********************************************************
2139 /* Helper methods for sub-classes
2140 /**********************************************************
2141 */
2142
2143 /**
2144 * Helper method used for constructing and throwing
2145 * {@link JsonGenerationException} with given base message.
2146 *<p>
2147 * Note that sub-classes may override this method to add more detail
2148 * or use a {@link JsonGenerationException} sub-class.
2149 */
2150 protected void _reportError(String msg) throws JsonGenerationException {
2151 throw new JsonGenerationException(msg, this);
2152 }
2153
2154 protected final void _throwInternal() { VersionUtil.throwInternal(); }
2155
2156 protected void _reportUnsupportedOperation() {
2157 throw new UnsupportedOperationException("Operation not supported by generator of type "+getClass().getName());
2158 }
2159
2160 /**
2161 * @since 2.8
2162 */
2163 protected final void _verifyOffsets(int arrayLength, int offset, int length)
2164 {
2165 if ((offset < 0) || (offset + length) > arrayLength) {
2166 throw new IllegalArgumentException(String.format(
2167 "invalid argument(s) (offset=%d, length=%d) for input array of %d element",
2168 offset, length, arrayLength));
2169 }
2170 }
2171
2172 /**
2173 * Helper method to try to call appropriate write method for given
2174 * untyped Object. At this point, no structural conversions should be done,
2175 * only simple basic types are to be coerced as necessary.
2176 *
2177 * @param value Non-null value to write
2178 */
2179 protected void _writeSimpleObject(Object value) throws IOException
2180 {
2181 // 31-Dec-2009, tatu: Actually, we could just handle some basic
2182 // types even without codec. This can improve interoperability,
2183 // and specifically help with TokenBuffer.
2184 if (value == null) {
2185 writeNull();
2186 return;
2187 }
2188 if (value instanceof String) {
2189 writeString((String) value);
2190 return;
2191 }
2192 if (value instanceof Number) {
2193 Number n = (Number) value;
2194 if (n instanceof Integer) {
2195 writeNumber(n.intValue());
2196 return;
2197 } else if (n instanceof Long) {
2198 writeNumber(n.longValue());
2199 return;
2200 } else if (n instanceof Double) {
2201 writeNumber(n.doubleValue());
2202 return;
2203 } else if (n instanceof Float) {
2204 writeNumber(n.floatValue());
2205 return;
2206 } else if (n instanceof Short) {
2207 writeNumber(n.shortValue());
2208 return;
2209 } else if (n instanceof Byte) {
2210 writeNumber(n.byteValue());
2211 return;
2212 } else if (n instanceof BigInteger) {
2213 writeNumber((BigInteger) n);
2214 return;
2215 } else if (n instanceof BigDecimal) {
2216 writeNumber((BigDecimal) n);
2217 return;
2218
2219 // then Atomic types
2220 } else if (n instanceof AtomicInteger) {
2221 writeNumber(((AtomicInteger) n).get());
2222 return;
2223 } else if (n instanceof AtomicLong) {
2224 writeNumber(((AtomicLong) n).get());
2225 return;
2226 }
2227 } else if (value instanceof byte[]) {
2228 writeBinary((byte[]) value);
2229 return;
2230 } else if (value instanceof Boolean) {
2231 writeBoolean((Boolean) value);
2232 return;
2233 } else if (value instanceof AtomicBoolean) {
2234 writeBoolean(((AtomicBoolean) value).get());
2235 return;
2236 }
2237 throw new IllegalStateException("No ObjectCodec defined for the generator, can only serialize simple wrapper types (type passed "
2238 +value.getClass().getName()+")");
2239 }
2240 }
2241