blob: dbda832e30b547489cf4f62bef347d770ab2a7b4 [file] [log] [blame]
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001/* Jackson JSON-processor.
2 *
3 * Copyright (c) 2007- Tatu Saloranta, tatu.saloranta@iki.fi
Tatu Salorantaf15531c2011-12-22 23:00:40 -08004 */
5package com.fasterxml.jackson.core;
6
7import java.io.*;
8import java.math.BigDecimal;
9import java.math.BigInteger;
Tatu Saloranta0e10fd52013-11-02 21:12:49 -070010import java.util.concurrent.atomic.AtomicBoolean;
11import java.util.concurrent.atomic.AtomicInteger;
12import java.util.concurrent.atomic.AtomicLong;
Tatu Salorantaf15531c2011-12-22 23:00:40 -080013
Tatu Saloranta933f33c2017-02-22 21:20:54 -080014import com.fasterxml.jackson.core.JsonParser.NumberType;
15import com.fasterxml.jackson.core.io.CharacterEscapes;
16import com.fasterxml.jackson.core.util.VersionUtil;
17
Logan Widick54970732017-02-09 16:21:58 -060018import static com.fasterxml.jackson.core.JsonTokenId.*;
Tatu Salorantaf15531c2011-12-22 23:00:40 -080019
20/**
21 * Base class that defines public API for writing JSON content.
22 * Instances are created using factory methods of
23 * a {@link JsonFactory} instance.
24 *
25 * @author Tatu Saloranta
26 */
27public abstract class JsonGenerator
Tatu Salorantaed4098c2014-01-16 22:46:10 -080028 implements Closeable, Flushable, Versioned
Tatu Salorantaf15531c2011-12-22 23:00:40 -080029{
30 /**
31 * Enumeration that defines all togglable features for generators.
32 */
33 public enum Feature {
Cowtowncoderafef47a2015-04-03 15:26:07 -070034 // // Low-level I/O / content features
35
Tatu Salorantaf15531c2011-12-22 23:00:40 -080036 /**
37 * Feature that determines whether generator will automatically
38 * close underlying output target that is NOT owned by the
39 * generator.
40 * If disabled, calling application has to separately
41 * close the underlying {@link OutputStream} and {@link Writer}
42 * instances used to create the generator. If enabled, generator
43 * will handle closing, as long as generator itself gets closed:
44 * this happens when end-of-input is encountered, or generator
45 * is closed by a call to {@link JsonGenerator#close}.
46 *<p>
Tatu07351902012-01-19 13:12:13 -080047 * Feature is enabled by default.
Tatu Salorantaf15531c2011-12-22 23:00:40 -080048 */
Tatu07351902012-01-19 13:12:13 -080049 AUTO_CLOSE_TARGET(true),
Tatu Salorantaf15531c2011-12-22 23:00:40 -080050
51 /**
52 * Feature that determines what happens when the generator is
53 * closed while there are still unmatched
54 * {@link JsonToken#START_ARRAY} or {@link JsonToken#START_OBJECT}
55 * entries in output content. If enabled, such Array(s) and/or
56 * Object(s) are automatically closed; if disabled, nothing
57 * specific is done.
58 *<p>
Tatu07351902012-01-19 13:12:13 -080059 * Feature is enabled by default.
Tatu Salorantaf15531c2011-12-22 23:00:40 -080060 */
Tatu07351902012-01-19 13:12:13 -080061 AUTO_CLOSE_JSON_CONTENT(true),
Tatu Salorantaf15531c2011-12-22 23:00:40 -080062
63 /**
Cowtowncoderafef47a2015-04-03 15:26:07 -070064 * Feature that specifies that calls to {@link #flush} will cause
65 * matching <code>flush()</code> to underlying {@link OutputStream}
66 * or {@link Writer}; if disabled this will not be done.
67 * Main reason to disable this feature is to prevent flushing at
68 * generator level, if it is not possible to prevent method being
69 * called by other code (like <code>ObjectMapper</code> or third
70 * party libraries).
71 *<p>
72 * Feature is enabled by default.
73 */
74 FLUSH_PASSED_TO_STREAM(true),
75
76 // // Quoting-related features
77
78 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -080079 * Feature that determines whether JSON Object field names are
80 * quoted using double-quotes, as specified by JSON specification
81 * or not. Ability to disable quoting was added to support use
82 * cases where they are not usually expected, which most commonly
83 * occurs when used straight from Javascript.
Tatu Saloranta9fc55aa2012-01-18 17:26:28 -080084 *<p>
Tatu07351902012-01-19 13:12:13 -080085 * Feature is enabled by default (since it is required by JSON specification).
Tatu Salorantaf15531c2011-12-22 23:00:40 -080086 */
Tatu07351902012-01-19 13:12:13 -080087 QUOTE_FIELD_NAMES(true),
Tatu Salorantaf15531c2011-12-22 23:00:40 -080088
89 /**
90 * Feature that determines whether "exceptional" (not real number)
91 * float/double values are output as quoted strings.
92 * The values checked are Double.Nan,
93 * Double.POSITIVE_INFINITY and Double.NEGATIVE_INIFINTY (and
94 * associated Float values).
95 * If feature is disabled, these numbers are still output using
96 * associated literal values, resulting in non-conformant
97 * output.
98 *<p>
Tatu07351902012-01-19 13:12:13 -080099 * Feature is enabled by default.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800100 */
Tatu07351902012-01-19 13:12:13 -0800101 QUOTE_NON_NUMERIC_NUMBERS(true),
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800102
103 /**
104 * Feature that forces all Java numbers to be written as JSON strings.
105 * Default state is 'false', meaning that Java numbers are to
106 * be serialized using basic numeric serialization (as JSON
107 * numbers, integral or floating point). If enabled, all such
108 * numeric values are instead written out as JSON Strings.
109 *<p>
110 * One use case is to avoid problems with Javascript limitations:
111 * since Javascript standard specifies that all number handling
112 * should be done using 64-bit IEEE 754 floating point values,
113 * result being that some 64-bit integer values can not be
114 * accurately represent (as mantissa is only 51 bit wide).
115 *<p>
Tatu07351902012-01-19 13:12:13 -0800116 * Feature is disabled by default.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800117 */
Tatu07351902012-01-19 13:12:13 -0800118 WRITE_NUMBERS_AS_STRINGS(false),
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800119
120 /**
Tatu Saloranta0dba7142013-07-04 21:17:31 -0700121 * Feature that determines whether {@link java.math.BigDecimal} entries are
122 * serialized using {@link java.math.BigDecimal#toPlainString()} to prevent
123 * values to be written using scientific notation.
124 *<p>
125 * Feature is disabled by default, so default output mode is used; this generally
126 * depends on how {@link BigDecimal} has been created.
127 *
128 * @since 2.3
129 */
130 WRITE_BIGDECIMAL_AS_PLAIN(false),
131
132 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800133 * Feature that specifies that all characters beyond 7-bit ASCII
134 * range (i.e. code points of 128 and above) need to be output
135 * using format-specific escapes (for JSON, backslash escapes),
136 * if format uses escaping mechanisms (which is generally true
137 * for textual formats but not for binary formats).
Tatu Saloranta9fc55aa2012-01-18 17:26:28 -0800138 *<p>
Cowtowncoder27eb3c12014-11-07 15:16:45 -0800139 * Note that this setting may not necessarily make sense for all
140 * data formats (for example, binary formats typically do not use
141 * any escaping mechanisms; and some textual formats do not have
142 * general-purpose escaping); if so, settings is simply ignored.
143 * Put another way, effects of this feature are data-format specific.
144 *<p>
Tatu07351902012-01-19 13:12:13 -0800145 * Feature is disabled by default.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800146 */
Tatu07351902012-01-19 13:12:13 -0800147 ESCAPE_NON_ASCII(false),
Tatu Salorantaf9ad80f2013-09-24 21:31:16 -0700148
Tatu Salorantaec560f32015-11-23 22:50:22 -0800149// 23-Nov-2015, tatu: for [core#223], if and when it gets implemented
150 /**
151 * Feature that specifies handling of UTF-8 content that contains
152 * characters beyond BMP (Basic Multilingual Plane), which are
153 * represented in UCS-2 (Java internal character encoding) as two
154 * "surrogate" characters. If feature is enabled, these surrogate
155 * pairs are separately escaped using backslash escapes; if disabled,
156 * native output (4-byte UTF-8 sequence, or, with char-backed output
157 * targets, writing of surrogates as is which is typically converted
158 * by {@link java.io.Writer} into 4-byte UTF-8 sequence eventually)
159 * is used.
160 *<p>
161 * Note that the original JSON specification suggests use of escaping;
162 * but that this is not correct from standard UTF-8 handling perspective.
163 * Because of two competing goals, this feature was added to allow either
164 * behavior to be used, but defaulting to UTF-8 specification compliant
165 * mode.
166 *<p>
167 * Feature is disabled by default.
168 *
Tatu Salorantaa7168c62016-01-10 16:23:58 -0800169 * @since Xxx
Tatu Salorantaec560f32015-11-23 22:50:22 -0800170 */
171// ESCAPE_UTF8_SURROGATES(false),
172
Cowtowncoderafef47a2015-04-03 15:26:07 -0700173 // // Schema/Validity support features
174
Tatu Salorantaf9ad80f2013-09-24 21:31:16 -0700175 /**
176 * Feature that determines whether {@link JsonGenerator} will explicitly
177 * check that no duplicate JSON Object field names are written.
178 * If enabled, generator will check all names within context and report
179 * duplicates by throwing a {@link JsonGenerationException}; if disabled,
180 * no such checking will be done. Assumption in latter case is
181 * that caller takes care of not trying to write duplicate names.
182 *<p>
183 * Note that enabling this feature will incur performance overhead
184 * due to having to store and check additional information.
Cowtowncoder27eb3c12014-11-07 15:16:45 -0800185 *<p>
186 * Feature is disabled by default.
Tatu Salorantaf9ad80f2013-09-24 21:31:16 -0700187 *
188 * @since 2.3
189 */
190 STRICT_DUPLICATE_DETECTION(false),
Cowtowncoderafef47a2015-04-03 15:26:07 -0700191
Cowtowncoder27eb3c12014-11-07 15:16:45 -0800192 /**
193 * Feature that determines what to do if the underlying data format requires knowledge
194 * of all properties to output, and if no definition is found for a property that
195 * caller tries to write. If enabled, such properties will be quietly ignored;
196 * if disabled, a {@link JsonProcessingException} will be thrown to indicate the
197 * problem.
198 * Typically most textual data formats do NOT require schema information (although
199 * some do, such as CSV), whereas many binary data formats do require definitions
200 * (such as Avro, protobuf), although not all (Smile, CBOR, BSON and MessagePack do not).
201 *<p>
202 * Note that support for this feature is implemented by individual data format
203 * module, if (and only if) it makes sense for the format in question. For JSON,
204 * for example, this feature has no effect as properties need not be pre-defined.
205 *<p>
206 * Feature is disabled by default, meaning that if the underlying data format
207 * requires knowledge of all properties to output, attempts to write an unknown
208 * property will result in a {@link JsonProcessingException}
209 *
210 * @since 2.5
211 */
212 IGNORE_UNKNOWN(false),
213 ;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800214
Tatu Saloranta9fc55aa2012-01-18 17:26:28 -0800215 private final boolean _defaultState;
Tatu Saloranta9fc55aa2012-01-18 17:26:28 -0800216 private final int _mask;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800217
218 /**
219 * Method that calculates bit set (flags) of all features that
220 * are enabled by default.
221 */
222 public static int collectDefaults()
223 {
224 int flags = 0;
225 for (Feature f : values()) {
226 if (f.enabledByDefault()) {
227 flags |= f.getMask();
228 }
229 }
230 return flags;
231 }
232
Tatu07351902012-01-19 13:12:13 -0800233 private Feature(boolean defaultState) {
Tatu Saloranta9fc55aa2012-01-18 17:26:28 -0800234 _defaultState = defaultState;
Tatu Saloranta483e6622014-11-09 12:47:19 -0800235 _mask = (1 << ordinal());
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800236 }
Tatu Salorantaf9ad80f2013-09-24 21:31:16 -0700237
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800238 public boolean enabledByDefault() { return _defaultState; }
Tatu Salorantaf9ad80f2013-09-24 21:31:16 -0700239
240 /**
241 * @since 2.3
242 */
243 public boolean enabledIn(int flags) { return (flags & _mask) != 0; }
244
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800245 public int getMask() { return _mask; }
246 }
247
248 /*
249 /**********************************************************
250 /* Configuration
251 /**********************************************************
252 */
253
254 /**
255 * Object that handles pretty-printing (usually additional
256 * white space to make results more human-readable) during
257 * output. If null, no pretty-printing is done.
258 */
259 protected PrettyPrinter _cfgPrettyPrinter;
260
261 /*
262 /**********************************************************
Tatu Salorantad6d57e52012-11-12 18:56:31 -0800263 /* Construction, initialization
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800264 /**********************************************************
265 */
266
267 protected JsonGenerator() { }
268
269 /**
Tatu Salorantad6d57e52012-11-12 18:56:31 -0800270 * Method that can be called to set or reset the object to
271 * use for writing Java objects as JsonContent
272 * (using method {@link #writeObject}).
273 *
274 * @return Generator itself (this), to allow chaining
275 */
276 public abstract JsonGenerator setCodec(ObjectCodec oc);
277
278 /**
279 * Method for accessing the object used for writing Java
Tatu Saloranta17498b82016-01-04 22:29:52 -0800280 * object as JSON content
Tatu Salorantad6d57e52012-11-12 18:56:31 -0800281 * (using method {@link #writeObject}).
282 */
283 public abstract ObjectCodec getCodec();
Tatu Salorantae9b48512012-04-17 10:22:07 -0700284
285 /**
Tatu Saloranta48d26092011-12-28 23:11:49 -0800286 * Accessor for finding out version of the bundle that provided this generator instance.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800287 */
Tatu Saloranta23439272013-04-06 20:44:18 -0700288 @Override
Tatu Saloranta48d26092011-12-28 23:11:49 -0800289 public abstract Version version();
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800290
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800291 /*
292 /**********************************************************
Tatu Saloranta08f918c2013-07-27 19:26:51 -0700293 /* Public API, Feature configuration
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800294 /**********************************************************
295 */
296
297 /**
298 * Method for enabling specified parser features:
299 * check {@link Feature} for list of available features.
300 *
301 * @return Generator itself (this), to allow chaining
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800302 */
303 public abstract JsonGenerator enable(Feature f);
304
305 /**
306 * Method for disabling specified features
307 * (check {@link Feature} for list of features)
308 *
309 * @return Generator itself (this), to allow chaining
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800310 */
311 public abstract JsonGenerator disable(Feature f);
312
313 /**
314 * Method for enabling or disabling specified feature:
315 * check {@link Feature} for list of available features.
316 *
317 * @return Generator itself (this), to allow chaining
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800318 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800319 public final JsonGenerator configure(Feature f, boolean state) {
320 if (state) enable(f); else disable(f);
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800321 return this;
322 }
323
324 /**
325 * Method for checking whether given feature is enabled.
326 * Check {@link Feature} for list of available features.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800327 */
328 public abstract boolean isEnabled(Feature f);
329
Tatu Salorantacaefc682013-08-07 19:20:50 -0700330 /**
Cowtowncoder2e262b92015-05-27 17:32:17 -0700331 * Bulk access method for getting state of all standard (non-dataformat-specific)
332 * {@link JsonGenerator.Feature}s.
Tatu Salorantacaefc682013-08-07 19:20:50 -0700333 *
Cowtowncoder2e262b92015-05-27 17:32:17 -0700334 * @return Bit mask that defines current states of all standard {@link JsonGenerator.Feature}s.
Tatu Salorantacaefc682013-08-07 19:20:50 -0700335 *
336 * @since 2.3
337 */
338 public abstract int getFeatureMask();
339
340 /**
Tatu Saloranta483e6622014-11-09 12:47:19 -0800341 * Bulk set method for (re)setting states of all standard {@link Feature}s
Tatu Salorantacaefc682013-08-07 19:20:50 -0700342 *
343 * @since 2.3
344 *
Tatu Saloranta483e6622014-11-09 12:47:19 -0800345 * @param values Bitmask that defines which {@link Feature}s are enabled
346 * and which disabled
347 *
Tatu Salorantacaefc682013-08-07 19:20:50 -0700348 * @return This parser object, to allow chaining of calls
Tatu Salorantad3f03202015-09-23 20:44:10 -0700349 *
Tatu Saloranta155babc2016-05-17 16:13:19 -0700350 * @deprecated Since 2.7, use {@link #overrideStdFeatures(int, int)} instead -- remove from 2.9
Tatu Salorantacaefc682013-08-07 19:20:50 -0700351 */
Tatu Salorantad3f03202015-09-23 20:44:10 -0700352 @Deprecated
Tatu Saloranta483e6622014-11-09 12:47:19 -0800353 public abstract JsonGenerator setFeatureMask(int values);
354
Cowtowncoder2e262b92015-05-27 17:32:17 -0700355 /**
356 * Bulk set method for (re)setting states of features specified by <code>mask</code>.
357 * Functionally equivalent to
358 *<code>
359 * int oldState = getFeatureMask();
Tatu Saloranta6f416282015-07-10 20:25:49 -0700360 * int newState = (oldState &amp; ~mask) | (values &amp; mask);
Cowtowncoder2e262b92015-05-27 17:32:17 -0700361 * setFeatureMask(newState);
362 *</code>
Tatu Salorantad3f03202015-09-23 20:44:10 -0700363 * but preferred as this lets caller more efficiently specify actual changes made.
Cowtowncoder2e262b92015-05-27 17:32:17 -0700364 *
365 * @param values Bit mask of set/clear state for features to change
366 * @param mask Bit mask of features to change
367 *
368 * @since 2.6
369 */
370 public JsonGenerator overrideStdFeatures(int values, int mask) {
371 int oldState = getFeatureMask();
372 int newState = (oldState & ~mask) | (values & mask);
373 return setFeatureMask(newState);
374 }
375
376 /**
377 * Bulk access method for getting state of all {@link FormatFeature}s, format-specific
378 * on/off configuration settings.
379 *
380 * @return Bit mask that defines current states of all standard {@link FormatFeature}s.
381 *
382 * @since 2.6
383 */
384 public int getFormatFeatures() {
385 return 0;
386 }
387
388 /**
389 * Bulk set method for (re)setting states of {@link FormatFeature}s,
390 * by specifying values (set / clear) along with a mask, to determine
391 * which features to change, if any.
392 *<p>
393 * Default implementation will simply throw an exception to indicate that
394 * the generator implementation does not support any {@link FormatFeature}s.
395 *
396 * @param values Bit mask of set/clear state for features to change
397 * @param mask Bit mask of features to change
398 *
399 * @since 2.6
400 */
401 public JsonGenerator overrideFormatFeatures(int values, int mask) {
402 throw new IllegalArgumentException("No FormatFeatures defined for generator of type "+getClass().getName());
403 /*
404 int oldState = getFeatureMask();
405 int newState = (oldState & ~mask) | (values & mask);
406 return setFeatureMask(newState);
407 */
408 }
409
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800410 /*
411 /**********************************************************
Tatu Saloranta08f918c2013-07-27 19:26:51 -0700412 /* Public API, Schema configuration
413 /**********************************************************
414 */
415
416 /**
417 * Method to call to make this generator use specified schema.
418 * Method must be called before generating any content, right after instance
419 * has been created.
420 * Note that not all generators support schemas; and those that do usually only
421 * accept specific types of schemas: ones defined for data format this generator
422 * produces.
423 *<p>
424 * If generator does not support specified schema, {@link UnsupportedOperationException}
425 * is thrown.
426 *
427 * @param schema Schema to use
428 *
429 * @throws UnsupportedOperationException if generator does not support schema
430 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800431 public void setSchema(FormatSchema schema) {
Tatu Saloranta08f918c2013-07-27 19:26:51 -0700432 throw new UnsupportedOperationException("Generator of type "+getClass().getName()+" does not support schema of type '"
433 +schema.getSchemaType()+"'");
434 }
435
436 /**
437 * Method for accessing Schema that this parser uses, if any.
438 * Default implementation returns null.
439 *
440 * @since 2.1
441 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800442 public FormatSchema getSchema() { return null; }
Tatu Saloranta08f918c2013-07-27 19:26:51 -0700443
444 /*
445 /**********************************************************
446 /* Public API, other configuration
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800447 /**********************************************************
448 */
449
450 /**
451 * Method for setting a custom pretty printer, which is usually
452 * used to add indentation for improved human readability.
453 * By default, generator does not do pretty printing.
454 *<p>
455 * To use the default pretty printer that comes with core
456 * Jackson distribution, call {@link #useDefaultPrettyPrinter}
457 * instead.
458 *
459 * @return Generator itself (this), to allow chaining
460 */
461 public JsonGenerator setPrettyPrinter(PrettyPrinter pp) {
462 _cfgPrettyPrinter = pp;
463 return this;
464 }
465
466 /**
Tatu Saloranta664b88b2012-09-28 11:08:15 -0700467 * Accessor for checking whether this generator has a configured
468 * {@link PrettyPrinter}; returns it if so, null if none configured.
469 *
470 * @since 2.1
471 */
472 public PrettyPrinter getPrettyPrinter() {
473 return _cfgPrettyPrinter;
474 }
475
476 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800477 * Convenience method for enabling pretty-printing using
478 * the default pretty printer
479 * ({@link com.fasterxml.jackson.core.util.DefaultPrettyPrinter}).
480 *
481 * @return Generator itself (this), to allow chaining
482 */
483 public abstract JsonGenerator useDefaultPrettyPrinter();
484
485 /**
486 * Method that can be called to request that generator escapes
487 * all character codes above specified code point (if positive value);
488 * or, to not escape any characters except for ones that must be
489 * escaped for the data format (if -1).
490 * To force escaping of all non-ASCII characters, for example,
491 * this method would be called with value of 127.
492 *<p>
493 * Note that generators are NOT required to support setting of value
494 * higher than 127, because there are other ways to affect quoting
495 * (or lack thereof) of character codes between 0 and 127.
496 * Not all generators support concept of escaping, either; if so,
497 * calling this method will have no effect.
498 *<p>
499 * Default implementation does nothing; sub-classes need to redefine
500 * it according to rules of supported data format.
501 *
502 * @param charCode Either -1 to indicate that no additional escaping
503 * is to be done; or highest code point not to escape (meaning higher
504 * ones will be), if positive value.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800505 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800506 public JsonGenerator setHighestNonEscapedChar(int charCode) { return this; }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800507
508 /**
509 * Accessor method for testing what is the highest unescaped character
510 * configured for this generator. This may be either positive value
511 * (when escaping configuration has been set and is in effect), or
512 * 0 to indicate that no additional escaping is in effect.
513 * Some generators may not support additional escaping: for example,
514 * generators for binary formats that do not use escaping should
515 * simply return 0.
516 *
517 * @return Currently active limitation for highest non-escaped character,
518 * if defined; or -1 to indicate no additional escaping is performed.
519 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800520 public int getHighestEscapedChar() { return 0; }
Tatu Salorantad6d57e52012-11-12 18:56:31 -0800521
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800522 /**
523 * Method for accessing custom escapes factory uses for {@link JsonGenerator}s
524 * it creates.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800525 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800526 public CharacterEscapes getCharacterEscapes() { return null; }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800527
528 /**
529 * Method for defining custom escapes factory uses for {@link JsonGenerator}s
530 * it creates.
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800531 *<p>
532 * Default implementation does nothing and simply returns this instance.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800533 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800534 public JsonGenerator setCharacterEscapes(CharacterEscapes esc) { return this; }
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800535
Tatu Saloranta08f918c2013-07-27 19:26:51 -0700536 /**
537 * Method that allows overriding String used for separating root-level
538 * JSON values (default is single space character)
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800539 *<p>
540 * Default implementation throws {@link UnsupportedOperationException}.
Tatu Saloranta08f918c2013-07-27 19:26:51 -0700541 *
542 * @param sep Separator to use, if any; null means that no separator is
543 * automatically added
544 *
545 * @since 2.1
546 */
547 public JsonGenerator setRootValueSeparator(SerializableString sep) {
548 throw new UnsupportedOperationException();
549 }
550
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800551 /*
552 /**********************************************************
Cowtowncoder46b4f022015-05-26 17:59:11 -0700553 /* Public API, output state access
554 /**********************************************************
555 */
556
557 /**
558 * Method that can be used to get access to object that is used
559 * as target for generated output; this is usually either
560 * {@link OutputStream} or {@link Writer}, depending on what
561 * generator was constructed with.
562 * Note that returned value may be null in some cases; including
563 * case where implementation does not want to exposed raw
564 * source to caller.
565 * In cases where output has been decorated, object returned here
566 * is the decorated version; this allows some level of interaction
567 * between users of generator and decorator object.
568 *<p>
569 * In general use of this accessor should be considered as
570 * "last effort", i.e. only used if no other mechanism is applicable.
571 */
572 public Object getOutputTarget() {
573 return null;
574 }
575
576 /**
577 * Method for verifying amount of content that is buffered by generator
578 * but not yet flushed to the underlying target (stream, writer),
579 * in units (byte, char) that the generator implementation uses for buffering;
580 * or -1 if this information is not available.
581 * Unit used is often the same as the unit of underlying target (that is,
582 * `byte` for {@link java.io.OutputStream}, `char` for {@link java.io.Writer}),
583 * but may differ if buffering is done before encoding.
584 * Default JSON-backed implementations do use matching units.
585 *<p>
586 * Note: non-JSON implementations will be retrofitted for 2.6 and beyond;
587 * please report if you see -1 (missing override)
588 *
589 * @return Amount of content buffered in internal units, if amount known and
590 * accessible; -1 if not accessible.
591 *
592 * @since 2.6
593 */
594 public int getOutputBuffered() {
595 return -1;
596 }
597
598 /**
599 * Helper method, usually equivalent to:
600 *<code>
601 * getOutputContext().getCurrentValue();
602 *</code>
Cowtowncoder5f4b48c2015-08-06 17:13:10 -0700603 *<p>
604 * Note that "current value" is NOT populated (or used) by Streaming parser;
605 * it is only used by higher-level data-binding functionality.
606 * The reason it is included here is that it can be stored and accessed hierarchically,
607 * and gets passed through data-binding.
Cowtowncoder46b4f022015-05-26 17:59:11 -0700608 *
609 * @since 2.5
610 */
611 public Object getCurrentValue() {
612 JsonStreamContext ctxt = getOutputContext();
613 return (ctxt == null) ? null : ctxt.getCurrentValue();
614 }
615
616 /**
617 * Helper method, usually equivalent to:
618 *<code>
619 * getOutputContext().setCurrentValue(v);
620 *</code>
621 *
622 * @since 2.5
623 */
624 public void setCurrentValue(Object v) {
625 JsonStreamContext ctxt = getOutputContext();
626 if (ctxt != null) {
627 ctxt.setCurrentValue(v);
628 }
629 }
630
631 /*
632 /**********************************************************
Tatu Saloranta98cb9a72013-08-10 15:05:33 -0700633 /* Public API, capability introspection methods
634 /**********************************************************
635 */
636
637 /**
638 * Method that can be used to verify that given schema can be used with
639 * this generator (using {@link #setSchema}).
640 *
641 * @param schema Schema to check
642 *
643 * @return True if this generator can use given schema; false if not
644 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800645 public boolean canUseSchema(FormatSchema schema) { return false; }
Tatu Saloranta98cb9a72013-08-10 15:05:33 -0700646
647 /**
648 * Introspection method that may be called to see if the underlying
649 * data format supports some kind of Object Ids natively (many do not;
650 * for example, JSON doesn't).
651 * This method <b>must</b> be called prior to calling
652 * {@link #writeObjectId} or {@link #writeObjectRef}.
653 *<p>
654 * Default implementation returns false; overridden by data formats
655 * that do support native Object Ids. Caller is expected to either
656 * use a non-native notation (explicit property or such), or fail,
657 * in case it can not use native object ids.
658 *
659 * @since 2.3
660 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800661 public boolean canWriteObjectId() { return false; }
Tatu Saloranta98cb9a72013-08-10 15:05:33 -0700662
663 /**
664 * Introspection method that may be called to see if the underlying
665 * data format supports some kind of Type Ids natively (many do not;
666 * for example, JSON doesn't).
667 * This method <b>must</b> be called prior to calling
668 * {@link #writeTypeId}.
669 *<p>
670 * Default implementation returns false; overridden by data formats
671 * that do support native Type Ids. Caller is expected to either
672 * use a non-native notation (explicit property or such), or fail,
673 * in case it can not use native type ids.
674 *
675 * @since 2.3
676 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800677 public boolean canWriteTypeId() { return false; }
Tatu Saloranta98cb9a72013-08-10 15:05:33 -0700678
679 /**
Tatu Salorantab8835442013-09-14 12:12:57 -0700680 * Introspection method that may be called to see if the underlying
681 * data format supports "native" binary data; that is, an efficient
682 * output of binary content without encoding.
683 *<p>
684 * Default implementation returns false; overridden by data formats
685 * that do support native binary content.
686 *
687 * @since 2.3
688 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800689 public boolean canWriteBinaryNatively() { return false; }
Tatu Salorantab8835442013-09-14 12:12:57 -0700690
691 /**
Tatu Saloranta98cb9a72013-08-10 15:05:33 -0700692 * Introspection method to call to check whether it is ok to omit
693 * writing of Object fields or not. Most formats do allow omission,
694 * but certain positional formats (such as CSV) require output of
695 * placeholders, even if no real values are to be emitted.
696 *
697 * @since 2.3
698 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800699 public boolean canOmitFields() { return true; }
Tatu Saloranta98cb9a72013-08-10 15:05:33 -0700700
Tatu Salorantae5ded102016-05-24 18:56:21 -0700701 /**
702 * Introspection method to call to check whether it is possible
703 * to write numbers using {@link #writeNumber(java.lang.String)}
704 * using possible custom format, or not. Typically textual formats
705 * allow this (and JSON specifically does), whereas binary formats
706 * do not allow this (except by writing them as Strings).
707 * Usual reason for calling this method is to check whether custom
708 * formatting of numbers may be applied by higher-level code (databinding)
709 * or not.
710 *
711 * @since 2.8
712 */
713 public boolean canWriteFormattedNumbers() { return false; }
714
Tatu Saloranta98cb9a72013-08-10 15:05:33 -0700715 /*
716 /**********************************************************
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800717 /* Public API, write methods, structural
718 /**********************************************************
719 */
720
721 /**
Tatu Saloranta1d076012014-03-24 18:29:33 -0700722 * Method for writing starting marker of a Array value
723 * (for JSON this is character '['; plus possible white space decoration
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800724 * if pretty-printing is enabled).
725 *<p>
726 * Array values can be written in any context where values
727 * are allowed: meaning everywhere except for when
728 * a field name is expected.
729 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800730 public abstract void writeStartArray() throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800731
732 /**
Tatu Saloranta1d076012014-03-24 18:29:33 -0700733 * Method for writing start marker of an Array value, similar
734 * to {@link #writeStartArray()}, but also specifying how many
735 * elements will be written for the array before calling
736 * {@link #writeEndArray()}.
737 *<p>
738 * Default implementation simply calls {@link #writeStartArray()}.
739 *
740 * @param size Number of elements this array will have: actual
741 * number of values written (before matching call to
742 * {@link #writeEndArray()} MUST match; generator MAY verify
743 * this is the case.
Tatu Salorantaba77f232014-09-08 20:20:02 -0700744 *
745 * @since 2.4
Tatu Saloranta1d076012014-03-24 18:29:33 -0700746 */
747 public void writeStartArray(int size) throws IOException {
748 writeStartArray();
749 }
750
751 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800752 * Method for writing closing marker of a JSON Array value
753 * (character ']'; plus possible white space decoration
754 * if pretty-printing is enabled).
755 *<p>
756 * Marker can be written if the innermost structured type
757 * is Array.
758 */
Tatu Saloranta1d076012014-03-24 18:29:33 -0700759 public abstract void writeEndArray() throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800760
761 /**
762 * Method for writing starting marker of a JSON Object value
763 * (character '{'; plus possible white space decoration
764 * if pretty-printing is enabled).
765 *<p>
766 * Object values can be written in any context where values
767 * are allowed: meaning everywhere except for when
768 * a field name is expected.
769 */
Cowtowncoder5cddffa2015-01-15 16:10:26 -0800770 public abstract void writeStartObject() throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800771
772 /**
Tatu Saloranta4bace842016-03-21 21:35:39 -0700773 * Method for writing starting marker of a JSON Object value
774 * (character '{'; plus possible white space decoration
775 * if pretty-printing is enabled), to represent Java given
776 * as the argument. Argument is offered as metadata, but more
777 * importantly it should be assigned as the "current value"
778 * for the Object content that gets constructed and initialized.
779 *<p>
780 * Object values can be written in any context where values
781 * are allowed: meaning everywhere except for when
782 * a field name is expected.
783 *
784 * @since 2.8.
785 */
786 public void writeStartObject(Object forValue) throws IOException
787 {
788 writeStartObject();
789 setCurrentValue(forValue);
790 }
791
792 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800793 * Method for writing closing marker of a JSON Object value
794 * (character '}'; plus possible white space decoration
795 * if pretty-printing is enabled).
796 *<p>
797 * Marker can be written if the innermost structured type
798 * is Object, and the last written event was either a
799 * complete value, or START-OBJECT marker (see JSON specification
800 * for more details).
801 */
Cowtowncoder5cddffa2015-01-15 16:10:26 -0800802 public abstract void writeEndObject() throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800803
804 /**
805 * Method for writing a field name (JSON String surrounded by
806 * double quotes: syntactically identical to a JSON String value),
807 * possibly decorated by white space if pretty-printing is enabled.
808 *<p>
809 * Field names can only be written in Object context (check out
810 * JSON specification for details), when field name is expected
811 * (field names alternate with values).
812 */
Cowtowncoder5cddffa2015-01-15 16:10:26 -0800813 public abstract void writeFieldName(String name) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800814
815 /**
816 * Method similar to {@link #writeFieldName(String)}, main difference
817 * being that it may perform better as some of processing (such as
818 * quoting of certain characters, or encoding into external encoding
819 * if supported by generator) can be done just once and reused for
820 * later calls.
821 *<p>
822 * Default implementation simple uses unprocessed name container in
823 * serialized String; implementations are strongly encouraged to make
824 * use of more efficient methods argument object has.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800825 */
Cowtowncoder5cddffa2015-01-15 16:10:26 -0800826 public abstract void writeFieldName(SerializableString name) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800827
Tatu Saloranta46017852016-06-29 18:00:01 -0700828 /**
829 * Alternative to {@link #writeFieldName(String)} that may be used
830 * in cases where property key is of numeric type; either where
831 * underlying format supports such notion (some binary formats do,
832 * unlike JSON), or for convenient conversion into String presentation.
833 * Default implementation will simply convert id into <code>String</code>
834 * and call {@link #writeFieldName(String)}.
835 *
836 * @since 2.8
837 */
838 public void writeFieldId(long id) throws IOException {
839 writeFieldName(Long.toString(id));
840 }
841
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800842 /*
843 /**********************************************************
Tatu Saloranta5691a372016-05-11 23:17:00 -0700844 /* Public API, write methods, scalar arrays (2.8)
845 /**********************************************************
846 */
847
848 /**
849 * Value write method that can be called to write a single
850 * array (sequence of {@link JsonToken#START_ARRAY}, zero or
851 * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY})
852 *
853 * @since 2.8
854 *
855 * @param array Array that contains values to write
856 * @param offset Offset of the first element to write, within array
857 * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
858 */
859 public void writeArray(int[] array, int offset, int length) throws IOException
860 {
861 if (array == null) {
862 throw new IllegalArgumentException("null array");
863 }
864 _verifyOffsets(array.length, offset, length);
865 writeStartArray();
866 for (int i = offset, end = offset+length; i < end; ++i) {
867 writeNumber(array[i]);
868 }
869 writeEndArray();
870 }
871
Tatu Saloranta5f175922016-05-22 22:46:42 -0700872 /**
873 * Value write method that can be called to write a single
874 * array (sequence of {@link JsonToken#START_ARRAY}, zero or
875 * more {@link JsonToken#VALUE_NUMBER_INT}, {@link JsonToken#END_ARRAY})
876 *
877 * @since 2.8
878 *
879 * @param array Array that contains values to write
880 * @param offset Offset of the first element to write, within array
881 * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
882 */
883 public void writeArray(long[] array, int offset, int length) throws IOException
884 {
885 if (array == null) {
886 throw new IllegalArgumentException("null array");
887 }
888 _verifyOffsets(array.length, offset, length);
889 writeStartArray();
890 for (int i = offset, end = offset+length; i < end; ++i) {
891 writeNumber(array[i]);
892 }
893 writeEndArray();
894 }
895
896 /**
897 * Value write method that can be called to write a single
898 * array (sequence of {@link JsonToken#START_ARRAY}, zero or
899 * more {@link JsonToken#VALUE_NUMBER_FLOAT}, {@link JsonToken#END_ARRAY})
900 *
901 * @since 2.8
902 *
903 * @param array Array that contains values to write
904 * @param offset Offset of the first element to write, within array
905 * @param length Number of elements in array to write, from `offset` to `offset + len - 1`
906 */
907 public void writeArray(double[] array, int offset, int length) throws IOException
908 {
909 if (array == null) {
910 throw new IllegalArgumentException("null array");
911 }
912 _verifyOffsets(array.length, offset, length);
913 writeStartArray();
914 for (int i = offset, end = offset+length; i < end; ++i) {
915 writeNumber(array[i]);
916 }
917 writeEndArray();
918 }
919
Tatu Saloranta5691a372016-05-11 23:17:00 -0700920 /*
921 /**********************************************************
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800922 /* Public API, write methods, text/String values
923 /**********************************************************
924 */
925
926 /**
927 * Method for outputting a String value. Depending on context
928 * this means either array element, (object) field value or
929 * a stand alone String; but in all cases, String will be
930 * surrounded in double quotes, and contents will be properly
931 * escaped as required by JSON specification.
932 */
Cowtowncoder5cddffa2015-01-15 16:10:26 -0800933 public abstract void writeString(String text) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800934
935 /**
936 * Method for outputting a String value. Depending on context
937 * this means either array element, (object) field value or
938 * a stand alone String; but in all cases, String will be
939 * surrounded in double quotes, and contents will be properly
940 * escaped as required by JSON specification.
Logan Widick54970732017-02-09 16:21:58 -0600941 * If the reader is null, then write a null.
Tatu Salorantaab9b00a2017-03-10 15:05:50 -0800942 * If len is &lt; 0, then write all contents of the reader.
Logan Widick54970732017-02-09 16:21:58 -0600943 * Otherwise, write only len characters.
Tatu Saloranta933f33c2017-02-22 21:20:54 -0800944 *
945 * @since 2.9
Logan Widick54970732017-02-09 16:21:58 -0600946 */
Tatu Saloranta21a75422017-02-22 21:58:35 -0800947 public void writeString(Reader reader, int len) throws IOException {
948 // Let's implement this as "unsupported" to make it easier to add new parser impls
949 _reportUnsupportedOperation();
950 }
Logan Widick54970732017-02-09 16:21:58 -0600951
952 /**
953 * Method for outputting a String value. Depending on context
954 * this means either array element, (object) field value or
955 * a stand alone String; but in all cases, String will be
956 * surrounded in double quotes, and contents will be properly
957 * escaped as required by JSON specification.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800958 */
Cowtowncoder5cddffa2015-01-15 16:10:26 -0800959 public abstract void writeString(char[] text, int offset, int len) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800960
961 /**
962 * Method similar to {@link #writeString(String)}, but that takes
963 * {@link SerializableString} which can make this potentially
964 * more efficient to call as generator may be able to reuse
965 * quoted and/or encoded representation.
966 *<p>
967 * Default implementation just calls {@link #writeString(String)};
968 * sub-classes should override it with more efficient implementation
969 * if possible.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800970 */
Cowtowncoder5cddffa2015-01-15 16:10:26 -0800971 public abstract void writeString(SerializableString text) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800972
973 /**
974 * Method similar to {@link #writeString(String)} but that takes as
975 * its input a UTF-8 encoded String that is to be output as-is, without additional
976 * escaping (type of which depends on data format; backslashes for JSON).
977 * However, quoting that data format requires (like double-quotes for JSON) will be added
978 * around the value if and as necessary.
979 *<p>
980 * Note that some backends may choose not to support this method: for
981 * example, if underlying destination is a {@link java.io.Writer}
982 * using this method would require UTF-8 decoding.
983 * If so, implementation may instead choose to throw a
984 * {@link UnsupportedOperationException} due to ineffectiveness
985 * of having to decode input.
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800986 */
987 public abstract void writeRawUTF8String(byte[] text, int offset, int length)
Tatu Salorantaed4098c2014-01-16 22:46:10 -0800988 throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -0800989
990 /**
991 * Method similar to {@link #writeString(String)} but that takes as its input
992 * a UTF-8 encoded String which has <b>not</b> been escaped using whatever
993 * escaping scheme data format requires (for JSON that is backslash-escaping
994 * for control characters and double-quotes; for other formats something else).
995 * This means that textual JSON backends need to check if value needs
996 * JSON escaping, but otherwise can just be copied as is to output.
997 * Also, quoting that data format requires (like double-quotes for JSON) will be added
998 * around the value if and as necessary.
999 *<p>
1000 * Note that some backends may choose not to support this method: for
1001 * example, if underlying destination is a {@link java.io.Writer}
1002 * using this method would require UTF-8 decoding.
1003 * In this case
1004 * generator implementation may instead choose to throw a
1005 * {@link UnsupportedOperationException} due to ineffectiveness
1006 * of having to decode input.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001007 */
1008 public abstract void writeUTF8String(byte[] text, int offset, int length)
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001009 throws IOException;
Cowtowncoder7df7c572014-11-07 17:06:29 -08001010
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001011 /*
1012 /**********************************************************
1013 /* Public API, write methods, binary/raw content
1014 /**********************************************************
1015 */
Cowtowncoder7df7c572014-11-07 17:06:29 -08001016
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001017 /**
1018 * Method that will force generator to copy
1019 * input text verbatim with <b>no</b> modifications (including
1020 * that no escaping is done and no separators are added even
1021 * if context [array, object] would otherwise require such).
1022 * If such separators are desired, use
1023 * {@link #writeRawValue(String)} instead.
1024 *<p>
1025 * Note that not all generator implementations necessarily support
1026 * such by-pass methods: those that do not will throw
1027 * {@link UnsupportedOperationException}.
1028 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001029 public abstract void writeRaw(String text) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001030
1031 /**
1032 * Method that will force generator to copy
1033 * input text verbatim with <b>no</b> modifications (including
1034 * that no escaping is done and no separators are added even
1035 * if context [array, object] would otherwise require such).
1036 * If such separators are desired, use
1037 * {@link #writeRawValue(String)} instead.
1038 *<p>
1039 * Note that not all generator implementations necessarily support
1040 * such by-pass methods: those that do not will throw
1041 * {@link UnsupportedOperationException}.
1042 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001043 public abstract void writeRaw(String text, int offset, int len) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001044
1045 /**
1046 * Method that will force generator to copy
1047 * input text verbatim with <b>no</b> modifications (including
1048 * that no escaping is done and no separators are added even
1049 * if context [array, object] would otherwise require such).
1050 * If such separators are desired, use
1051 * {@link #writeRawValue(String)} instead.
1052 *<p>
1053 * Note that not all generator implementations necessarily support
1054 * such by-pass methods: those that do not will throw
1055 * {@link UnsupportedOperationException}.
1056 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001057 public abstract void writeRaw(char[] text, int offset, int len) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001058
1059 /**
1060 * Method that will force generator to copy
1061 * input text verbatim with <b>no</b> modifications (including
1062 * that no escaping is done and no separators are added even
1063 * if context [array, object] would otherwise require such).
1064 * If such separators are desired, use
1065 * {@link #writeRawValue(String)} instead.
1066 *<p>
1067 * Note that not all generator implementations necessarily support
1068 * such by-pass methods: those that do not will throw
1069 * {@link UnsupportedOperationException}.
1070 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001071 public abstract void writeRaw(char c) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001072
1073 /**
1074 * Method that will force generator to copy
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001075 * input text verbatim with <b>no</b> modifications (including
1076 * that no escaping is done and no separators are added even
1077 * if context [array, object] would otherwise require such).
1078 * If such separators are desired, use
1079 * {@link #writeRawValue(String)} instead.
1080 *<p>
1081 * Note that not all generator implementations necessarily support
1082 * such by-pass methods: those that do not will throw
1083 * {@link UnsupportedOperationException}.
1084 *<p>
1085 * The default implementation delegates to {@link #writeRaw(String)};
1086 * other backends that support raw inclusion of text are encouraged
1087 * to implement it in more efficient manner (especially if they
1088 * use UTF-8 encoding).
1089 *
1090 * @since 2.1
1091 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001092 public void writeRaw(SerializableString raw) throws IOException {
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001093 writeRaw(raw.getValue());
1094 }
Cowtowncoder7df7c572014-11-07 17:06:29 -08001095
Tatu Salorantae6dfc692012-09-28 15:34:05 -07001096 /**
1097 * Method that will force generator to copy
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001098 * input text verbatim without any modifications, but assuming
1099 * it must constitute a single legal JSON value (number, string,
1100 * boolean, null, Array or List). Assuming this, proper separators
1101 * are added if and as needed (comma or colon), and generator
1102 * state updated to reflect this.
1103 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001104 public abstract void writeRawValue(String text) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001105
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001106 public abstract void writeRawValue(String text, int offset, int len) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001107
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001108 public abstract void writeRawValue(char[] text, int offset, int len) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001109
1110 /**
Cowtowncoder7df7c572014-11-07 17:06:29 -08001111 * Method similar to {@link #writeRawValue(String)}, but potentially more
1112 * efficient as it may be able to use pre-encoded content (similar to
1113 * {@link #writeRaw(SerializableString)}.
1114 *
1115 * @since 2.5
1116 */
1117 public void writeRawValue(SerializableString raw) throws IOException {
1118 writeRawValue(raw.getValue());
1119 }
1120
1121 /**
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001122 * Method that will output given chunk of binary data as base64
1123 * encoded, as a complete String value (surrounded by double quotes).
1124 * This method defaults
1125 *<p>
Tatu Saloranta17498b82016-01-04 22:29:52 -08001126 * Note: because JSON Strings can not contain unescaped linefeeds,
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001127 * if linefeeds are included (as per last argument), they must be
1128 * escaped. This adds overhead for decoding without improving
1129 * readability.
1130 * Alternatively if linefeeds are not included,
1131 * resulting String value may violate the requirement of base64
1132 * RFC which mandates line-length of 76 characters and use of
1133 * linefeeds. However, all {@link JsonParser} implementations
1134 * are required to accept such "long line base64"; as do
1135 * typical production-level base64 decoders.
1136 *
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001137 * @param bv Base64 variant to use: defines details such as
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001138 * whether padding is used (and if so, using which character);
1139 * what is the maximum line length before adding linefeed,
1140 * and also the underlying alphabet to use.
1141 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001142 public abstract void writeBinary(Base64Variant bv,
1143 byte[] data, int offset, int len) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001144
1145 /**
1146 * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1147 * but default to using the Jackson default Base64 variant
1148 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).
1149 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001150 public void writeBinary(byte[] data, int offset, int len) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001151 writeBinary(Base64Variants.getDefaultVariant(), data, offset, len);
1152 }
1153
1154 /**
1155 * Similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1156 * but assumes default to using the Jackson default Base64 variant
1157 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}). Also
1158 * assumes that whole byte array is to be output.
1159 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001160 public void writeBinary(byte[] data) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001161 writeBinary(Base64Variants.getDefaultVariant(), data, 0, data.length);
1162 }
1163
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001164 /**
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -07001165 * Similar to {@link #writeBinary(Base64Variant,InputStream,int)},
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001166 * but assumes default to using the Jackson default Base64 variant
1167 * (which is {@link Base64Variants#MIME_NO_LINEFEEDS}).
1168 *
1169 * @param data InputStream to use for reading binary data to write.
Tatu Saloranta63ff5742012-06-08 21:30:30 -07001170 * Will not be closed after successful write operation
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001171 * @param dataLength (optional) number of bytes that will be available;
1172 * or -1 to be indicate it is not known. Note that implementations
1173 * need not support cases where length is not known in advance; this
1174 * depends on underlying data format: JSON output does NOT require length,
1175 * other formats may
1176 */
1177 public int writeBinary(InputStream data, int dataLength)
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001178 throws IOException {
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001179 return writeBinary(Base64Variants.getDefaultVariant(), data, dataLength);
1180 }
1181
1182 /**
1183 * Method similar to {@link #writeBinary(Base64Variant,byte[],int,int)},
1184 * but where input is provided through a stream, allowing for incremental
1185 * writes without holding the whole input in memory.
1186 *
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001187 * @param bv Base64 variant to use
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001188 * @param data InputStream to use for reading binary data to write.
Tatu Saloranta63ff5742012-06-08 21:30:30 -07001189 * Will not be closed after successful write operation
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001190 * @param dataLength (optional) number of bytes that will be available;
Tatu Saloranta63ff5742012-06-08 21:30:30 -07001191 * or -1 to be indicate it is not known.
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -07001192 * If a positive length is given, <code>data</code> MUST provide at least
Tatu Saloranta63ff5742012-06-08 21:30:30 -07001193 * that many bytes: if not, an exception will be thrown.
1194 * Note that implementations
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001195 * need not support cases where length is not known in advance; this
1196 * depends on underlying data format: JSON output does NOT require length,
Tatu Saloranta63ff5742012-06-08 21:30:30 -07001197 * other formats may.
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001198 *
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -07001199 * @return Number of bytes read from <code>data</code> and written as binary payload
Tatu Saloranta2e70a2a2012-06-04 22:21:45 -07001200 *
1201 * @since 2.1
1202 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001203 public abstract int writeBinary(Base64Variant bv,
1204 InputStream data, int dataLength) throws IOException;
Tatu Saloranta3e5ff6d2012-06-27 18:46:43 -07001205
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001206 /*
1207 /**********************************************************
Tatu Salorantacfb08662016-05-24 18:03:17 -07001208 /* Public API, write methods, numeric
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001209 /**********************************************************
1210 */
1211
1212 /**
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001213 * Method for outputting given value as JSON number.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001214 * Can be called in any context where a value is expected
1215 * (Array value, Object field value, root-level value).
1216 * Additional white space may be added around the value
1217 * if pretty-printing is enabled.
Tatu Saloranta5b7bbe12013-04-16 19:08:21 -07001218 *
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001219 * @param v Number value to write
1220 *
Tatu Saloranta5b7bbe12013-04-16 19:08:21 -07001221 * @since 2.2
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001222 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001223 public void writeNumber(short v) throws IOException { writeNumber((int) v); }
Martin Steiger7190d202013-04-13 12:55:32 +02001224
1225 /**
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001226 * Method for outputting given value as JSON number.
Martin Steiger7190d202013-04-13 12:55:32 +02001227 * Can be called in any context where a value is expected
1228 * (Array value, Object field value, root-level value).
1229 * Additional white space may be added around the value
1230 * if pretty-printing is enabled.
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001231 *
1232 * @param v Number value to write
Martin Steiger7190d202013-04-13 12:55:32 +02001233 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001234 public abstract void writeNumber(int v) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001235
1236 /**
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001237 * Method for outputting given value as JSON number.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001238 * Can be called in any context where a value is expected
1239 * (Array value, Object field value, root-level value).
1240 * Additional white space may be added around the value
1241 * if pretty-printing is enabled.
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001242 *
1243 * @param v Number value to write
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001244 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001245 public abstract void writeNumber(long v) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001246
1247 /**
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001248 * Method for outputting given value as JSON number.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001249 * Can be called in any context where a value is expected
1250 * (Array value, Object field value, root-level value).
1251 * Additional white space may be added around the value
1252 * if pretty-printing is enabled.
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001253 *
1254 * @param v Number value to write
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001255 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001256 public abstract void writeNumber(BigInteger v) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001257
1258 /**
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001259 * Method for outputting indicate JSON numeric value.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001260 * Can be called in any context where a value is expected
1261 * (Array value, Object field value, root-level value).
1262 * Additional white space may be added around the value
1263 * if pretty-printing is enabled.
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001264 *
1265 * @param v Number value to write
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001266 */
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001267 public abstract void writeNumber(double v) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001268
1269 /**
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001270 * Method for outputting indicate JSON numeric value.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001271 * Can be called in any context where a value is expected
1272 * (Array value, Object field value, root-level value).
1273 * Additional white space may be added around the value
1274 * if pretty-printing is enabled.
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001275 *
1276 * @param v Number value to write
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001277 */
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001278 public abstract void writeNumber(float v) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001279
1280 /**
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001281 * Method for outputting indicate JSON numeric value.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001282 * Can be called in any context where a value is expected
1283 * (Array value, Object field value, root-level value).
1284 * Additional white space may be added around the value
1285 * if pretty-printing is enabled.
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001286 *
1287 * @param v Number value to write
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001288 */
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001289 public abstract void writeNumber(BigDecimal v) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001290
1291 /**
1292 * Write method that can be used for custom numeric types that can
1293 * not be (easily?) converted to "standard" Java number types.
1294 * Because numbers are not surrounded by double quotes, regular
1295 * {@link #writeString} method can not be used; nor
1296 * {@link #writeRaw} because that does not properly handle
1297 * value separators needed in Array or Object contexts.
1298 *<p>
1299 * Note: because of lack of type safety, some generator
1300 * implementations may not be able to implement this
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001301 * method. For example, if a binary JSON format is used,
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001302 * it may require type information for encoding; similarly
Tatu Saloranta3dcedd22015-01-10 20:15:06 -08001303 * for generator-wrappers around Java objects or JSON nodes.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001304 * If implementation does not implement this method,
1305 * it needs to throw {@link UnsupportedOperationException}.
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001306 *
1307 * @throws UnsupportedOperationException If underlying data format does not
1308 * support numbers serialized textually AND if generator is not allowed
1309 * to just output a String instead (Schema-based formats may require actual
1310 * number, for example)
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001311 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001312 public abstract void writeNumber(String encodedValue) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001313
Tatu Salorantacfb08662016-05-24 18:03:17 -07001314 /*
1315 /**********************************************************
1316 /* Public API, write methods, other value types
1317 /**********************************************************
1318 */
1319
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001320 /**
Tatu Saloranta17498b82016-01-04 22:29:52 -08001321 * Method for outputting literal JSON boolean value (one of
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001322 * Strings 'true' and 'false').
1323 * Can be called in any context where a value is expected
1324 * (Array value, Object field value, root-level value).
1325 * Additional white space may be added around the value
1326 * if pretty-printing is enabled.
1327 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001328 public abstract void writeBoolean(boolean state) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001329
1330 /**
Tatu Saloranta17498b82016-01-04 22:29:52 -08001331 * Method for outputting literal JSON null value.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001332 * Can be called in any context where a value is expected
1333 * (Array value, Object field value, root-level value).
1334 * Additional white space may be added around the value
1335 * if pretty-printing is enabled.
1336 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001337 public abstract void writeNull() throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001338
Tatu Salorantacfb08662016-05-24 18:03:17 -07001339 /**
1340 * Method that can be called on backends that support passing opaque datatypes of
1341 * non-JSON formats
1342 *
1343 * @since 2.8
1344 */
1345 public void writeEmbeddedObject(Object object) throws IOException {
Tatu Salorantafa643902016-09-01 15:32:46 -07001346 // 01-Sep-2016, tatu: As per [core#318], handle small number of cases
1347 if (object == null) {
1348 writeNull();
1349 return;
1350 }
1351 if (object instanceof byte[]) {
1352 writeBinary((byte[]) object);
1353 return;
1354 }
1355 throw new JsonGenerationException("No native support for writing embedded objects of type "
1356 +object.getClass().getName(),
Tatu Salorantacfb08662016-05-24 18:03:17 -07001357 this);
1358 }
1359
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001360 /*
1361 /**********************************************************
Tatu Saloranta5963bc42013-08-03 20:07:13 -07001362 /* Public API, write methods, Native Ids (type, object)
Tatu Saloranta08f918c2013-07-27 19:26:51 -07001363 /**********************************************************
1364 */
Tatu Saloranta2fdf90e2013-07-28 20:04:23 -07001365
1366 /**
Tatu Saloranta5963bc42013-08-03 20:07:13 -07001367 * Method that can be called to output so-called native Object Id.
1368 * Note that it may only be called after ensuring this is legal
1369 * (with {@link #canWriteObjectId()}), as not all data formats
1370 * have native type id support; and some may only allow them in
1371 * certain positions or locations.
1372 * If output is not allowed by the data format in this position,
1373 * a {@link JsonGenerationException} will be thrown.
1374 *
1375 * @since 2.3
1376 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001377 public void writeObjectId(Object id) throws IOException {
Tatu Saloranta77be53c2015-08-17 22:52:56 -07001378 throw new JsonGenerationException("No native support for writing Object Ids", this);
Tatu Saloranta5963bc42013-08-03 20:07:13 -07001379 }
Tatu Salorantaa464bb12013-08-03 20:30:20 -07001380
1381 /**
1382 * Method that can be called to output references to native Object Ids.
1383 * Note that it may only be called after ensuring this is legal
1384 * (with {@link #canWriteObjectId()}), as not all data formats
1385 * have native type id support; and some may only allow them in
1386 * certain positions or locations.
1387 * If output is not allowed by the data format in this position,
1388 * a {@link JsonGenerationException} will be thrown.
1389 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001390 public void writeObjectRef(Object id) throws IOException {
Tatu Saloranta77be53c2015-08-17 22:52:56 -07001391 throw new JsonGenerationException("No native support for writing Object Ids", this);
Tatu Salorantaa464bb12013-08-03 20:30:20 -07001392 }
Tatu Saloranta5963bc42013-08-03 20:07:13 -07001393
1394 /**
Tatu Saloranta08f918c2013-07-27 19:26:51 -07001395 * Method that can be called to output so-called native Type Id.
1396 * Note that it may only be called after ensuring this is legal
1397 * (with {@link #canWriteTypeId()}), as not all data formats
1398 * have native type id support; and some may only allow them in
1399 * certain positions or locations.
1400 * If output is not allowed by the data format in this position,
1401 * a {@link JsonGenerationException} will be thrown.
1402 *
1403 * @since 2.3
1404 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001405 public void writeTypeId(Object id) throws IOException {
Tatu Saloranta77be53c2015-08-17 22:52:56 -07001406 throw new JsonGenerationException("No native support for writing Type Ids", this);
Tatu Saloranta08f918c2013-07-27 19:26:51 -07001407 }
Tatu Saloranta17498b82016-01-04 22:29:52 -08001408
Tatu Salorantacfb08662016-05-24 18:03:17 -07001409 // 24-May-2016, tatu: Looks like this won't quite make it in 2.8... too
1410 // many open questions on whether return value may be used and such to
1411 // really close the loop. But leaving code sample in, in case we can resolve it
1412 // it for 2.9.
1413
1414 /*
1415 * Replacement method for {@link #writeTypeId(Object)} which is called
1416 * regardless of whether format has native type ids. If it does have native
1417 * type ids, those are to be used (if configuration allows this), if not,
1418 * structural type id inclusion is to be used. For JSON, for example, no
1419 * native type ids exist and structural inclusion is always used.
1420 *<p>
1421 * NOTE: from databind perspective, only "as-wrapper-array", "as-wrapper-object" and
1422 * "as-property" inclusion styles call this method; the remaining "as-external-property"
1423 * mechanism always uses writes type id value as simple property.
1424 *
1425 * @param inclStyle Kind of inclusion; {@link JsonToken#START_ARRAY} for "as-wrapper-array",
1426 * {@link JsonToken#START_OBJECT} for "as-wrapper-object" and {@link JsonToken#FIELD_NAME}
1427 * for "as-property"
1428 * @param forValue Java object for which type is being written; not used by standard mechanism
1429 * @param valueShape Expected shape of the value to write, as expressed by the first token (for
1430 * structural type), or any of scalar types for non-structured values (typically
1431 * just {@link JsonToken#VALUE_STRING} -- exact token not required, just the fact it's scalar)
1432 * @param typeId Type id to write
1433 * @param propertyName Name of property to use, in case of "as-property" inclusion style
Tatu Saloranta4bace842016-03-21 21:35:39 -07001434 *
1435 * @since 2.8
1436 */
Tatu Salorantacfb08662016-05-24 18:03:17 -07001437 /*
1438 public Object writeTypeSuffix(JsonToken inclStyle, Object forValue, JsonToken valueShape,
1439 String typeId, String propertyName) throws IOException
1440 {
1441 if (inclStyle == JsonToken.FIELD_NAME) { // as-property
1442 if (typeId == null) { // should not include `null` type id in any form with this style
1443 writeStartObject();
1444 } else if (valueShape == JsonToken.START_OBJECT) {
1445 if (canWriteTypeId()) {
1446 writeTypeId(typeId);
1447 writeStartObject();
1448 } else {
1449 writeStartObject();
1450 writeStringField(propertyName, typeId);
1451 }
1452 } else if (valueShape == JsonToken.START_ARRAY) {
1453 if (canWriteTypeId()) {
1454 writeTypeId(typeId);
1455 writeStartArray();
1456 } else {
1457 writeStartArray();
1458 writeString(typeId);
1459 }
1460 } else { // any scalar
1461 if (canWriteTypeId()) {
1462 writeTypeId(typeId);
1463 }
1464 }
1465 return JsonToken.END_OBJECT;
1466 }
1467 if (inclStyle == JsonToken.START_ARRAY) { // as-wrapper-array
1468 } else if (inclStyle == JsonToken.START_OBJECT) { // as-wrapper-object
1469
1470 } else {
1471 throw new JsonGenerationException("Unrecognized inclusion style: "+inclStyle, this);
1472 }
Tatu Saloranta4bace842016-03-21 21:35:39 -07001473 }
Tatu Salorantacfb08662016-05-24 18:03:17 -07001474 */
Tatu Saloranta4bace842016-03-21 21:35:39 -07001475
Tatu Saloranta08f918c2013-07-27 19:26:51 -07001476 /*
1477 /**********************************************************
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001478 /* Public API, write methods, serializing Java objects
1479 /**********************************************************
1480 */
1481
1482 /**
1483 * Method for writing given Java object (POJO) as Json.
1484 * Exactly how the object gets written depends on object
1485 * in question (ad on codec, its configuration); for most
Tatu Saloranta17498b82016-01-04 22:29:52 -08001486 * beans it will result in JSON Object, but for others JSON
1487 * Array, or String or numeric value (and for nulls, JSON
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001488 * null literal.
1489 * <b>NOTE</b>: generator must have its <b>object codec</b>
1490 * set to non-null value; for generators created by a mapping
1491 * factory this is the case, for others not.
1492 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001493 public abstract void writeObject(Object pojo) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001494
1495 /**
1496 * Method for writing given JSON tree (expressed as a tree
1497 * where given JsonNode is the root) using this generator.
1498 * This will generally just call
1499 * {@link #writeObject} with given node, but is added
1500 * for convenience and to make code more explicit in cases
1501 * where it deals specifically with trees.
1502 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001503 public abstract void writeTree(TreeNode rootNode) throws IOException;
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001504
1505 /*
1506 /**********************************************************
1507 /* Public API, convenience field write methods
1508 /**********************************************************
1509 */
1510
1511 /**
1512 * Convenience method for outputting a field entry ("member")
1513 * that has a String value. Equivalent to:
1514 *<pre>
1515 * writeFieldName(fieldName);
1516 * writeString(value);
1517 *</pre>
1518 *<p>
1519 * Note: many performance-sensitive implementations override this method
1520 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001521 public void writeStringField(String fieldName, String value) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001522 writeFieldName(fieldName);
1523 writeString(value);
1524 }
1525
1526 /**
1527 * Convenience method for outputting a field entry ("member")
1528 * that has a boolean value. Equivalent to:
1529 *<pre>
1530 * writeFieldName(fieldName);
1531 * writeBoolean(value);
1532 *</pre>
1533 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001534 public final void writeBooleanField(String fieldName, boolean value) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001535 writeFieldName(fieldName);
1536 writeBoolean(value);
1537 }
1538
1539 /**
1540 * Convenience method for outputting a field entry ("member")
1541 * that has JSON literal value null. Equivalent to:
1542 *<pre>
1543 * writeFieldName(fieldName);
1544 * writeNull();
1545 *</pre>
1546 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001547 public final void writeNullField(String fieldName) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001548 writeFieldName(fieldName);
1549 writeNull();
1550 }
Tatu Saloranta2f9eb8c2013-08-10 18:53:24 -07001551
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001552 /**
1553 * Convenience method for outputting a field entry ("member")
1554 * that has the specified numeric value. Equivalent to:
1555 *<pre>
1556 * writeFieldName(fieldName);
1557 * writeNumber(value);
1558 *</pre>
1559 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001560 public final void writeNumberField(String fieldName, int value) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001561 writeFieldName(fieldName);
1562 writeNumber(value);
1563 }
1564
1565 /**
1566 * Convenience method for outputting a field entry ("member")
1567 * that has the specified numeric value. Equivalent to:
1568 *<pre>
1569 * writeFieldName(fieldName);
1570 * writeNumber(value);
1571 *</pre>
1572 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001573 public final void writeNumberField(String fieldName, long value) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001574 writeFieldName(fieldName);
1575 writeNumber(value);
1576 }
1577
1578 /**
1579 * Convenience method for outputting a field entry ("member")
1580 * that has the specified numeric value. Equivalent to:
1581 *<pre>
1582 * writeFieldName(fieldName);
1583 * writeNumber(value);
1584 *</pre>
1585 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001586 public final void writeNumberField(String fieldName, double value) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001587 writeFieldName(fieldName);
1588 writeNumber(value);
1589 }
1590
1591 /**
1592 * Convenience method for outputting a field entry ("member")
1593 * that has the specified numeric value. Equivalent to:
1594 *<pre>
1595 * writeFieldName(fieldName);
1596 * writeNumber(value);
1597 *</pre>
1598 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001599 public final void writeNumberField(String fieldName, float value) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001600 writeFieldName(fieldName);
1601 writeNumber(value);
1602 }
1603
1604 /**
1605 * Convenience method for outputting a field entry ("member")
1606 * that has the specified numeric value.
1607 * Equivalent to:
1608 *<pre>
1609 * writeFieldName(fieldName);
1610 * writeNumber(value);
1611 *</pre>
1612 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001613 public final void writeNumberField(String fieldName, BigDecimal value) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001614 writeFieldName(fieldName);
1615 writeNumber(value);
1616 }
1617
1618 /**
1619 * Convenience method for outputting a field entry ("member")
1620 * that contains specified data in base64-encoded form.
1621 * Equivalent to:
1622 *<pre>
1623 * writeFieldName(fieldName);
1624 * writeBinary(value);
1625 *</pre>
1626 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001627 public final void writeBinaryField(String fieldName, byte[] data) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001628 writeFieldName(fieldName);
1629 writeBinary(data);
1630 }
1631
1632 /**
1633 * Convenience method for outputting a field entry ("member")
1634 * (that will contain a JSON Array value), and the START_ARRAY marker.
1635 * Equivalent to:
1636 *<pre>
1637 * writeFieldName(fieldName);
1638 * writeStartArray();
1639 *</pre>
1640 *<p>
1641 * Note: caller still has to take care to close the array
1642 * (by calling {#link #writeEndArray}) after writing all values
1643 * of the value Array.
1644 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001645 public final void writeArrayFieldStart(String fieldName) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001646 writeFieldName(fieldName);
1647 writeStartArray();
1648 }
1649
1650 /**
1651 * Convenience method for outputting a field entry ("member")
1652 * (that will contain a JSON Object value), and the START_OBJECT marker.
1653 * Equivalent to:
1654 *<pre>
1655 * writeFieldName(fieldName);
1656 * writeStartObject();
1657 *</pre>
1658 *<p>
1659 * Note: caller still has to take care to close the Object
1660 * (by calling {#link #writeEndObject}) after writing all
1661 * entries of the value Object.
1662 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001663 public final void writeObjectFieldStart(String fieldName) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001664 writeFieldName(fieldName);
1665 writeStartObject();
1666 }
1667
1668 /**
1669 * Convenience method for outputting a field entry ("member")
1670 * that has contents of specific Java object as its value.
1671 * Equivalent to:
1672 *<pre>
1673 * writeFieldName(fieldName);
1674 * writeObject(pojo);
1675 *</pre>
1676 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001677 public final void writeObjectField(String fieldName, Object pojo) throws IOException {
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001678 writeFieldName(fieldName);
1679 writeObject(pojo);
1680 }
1681
Tatu Saloranta2f9eb8c2013-08-10 18:53:24 -07001682 /**
1683 * Method called to indicate that a property in this position was
1684 * skipped. It is usually only called for generators that return
1685 * <code>false</code> from {@link #canOmitFields()}.
1686 *<p>
1687 * Default implementation does nothing.
1688 *
1689 * @since 2.3
1690 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001691 public void writeOmittedField(String fieldName) throws IOException { }
Tatu Saloranta2f9eb8c2013-08-10 18:53:24 -07001692
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001693 /*
1694 /**********************************************************
1695 /* Public API, copy-through methods
1696 /**********************************************************
1697 */
1698
1699 /**
1700 * Method for copying contents of the current event that
1701 * the given parser instance points to.
1702 * Note that the method <b>will not</b> copy any other events,
Tatu Saloranta17498b82016-01-04 22:29:52 -08001703 * such as events contained within JSON Array or Object structures.
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001704 *<p>
1705 * Calling this method will not advance the given
1706 * parser, although it may cause parser to internally process
1707 * more data (if it lazy loads contents of value events, for example)
1708 */
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001709 public void copyCurrentEvent(JsonParser p) throws IOException
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001710 {
Tatu Salorantae052c312016-07-01 21:11:25 -07001711 JsonToken t = p.currentToken();
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001712 // sanity check; what to do?
1713 if (t == null) {
1714 _reportError("No current event to copy");
1715 }
1716 switch (t.id()) {
1717 case ID_NOT_AVAILABLE:
1718 _reportError("No current event to copy");
Tatu Salorantacd5b6ff2016-07-21 14:38:42 -07001719 break; // never gets here
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001720 case ID_START_OBJECT:
1721 writeStartObject();
1722 break;
1723 case ID_END_OBJECT:
1724 writeEndObject();
1725 break;
1726 case ID_START_ARRAY:
1727 writeStartArray();
1728 break;
1729 case ID_END_ARRAY:
1730 writeEndArray();
1731 break;
1732 case ID_FIELD_NAME:
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001733 writeFieldName(p.getCurrentName());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001734 break;
1735 case ID_STRING:
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001736 if (p.hasTextCharacters()) {
1737 writeString(p.getTextCharacters(), p.getTextOffset(), p.getTextLength());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001738 } else {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001739 writeString(p.getText());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001740 }
1741 break;
1742 case ID_NUMBER_INT:
1743 {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001744 NumberType n = p.getNumberType();
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001745 if (n == NumberType.INT) {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001746 writeNumber(p.getIntValue());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001747 } else if (n == NumberType.BIG_INTEGER) {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001748 writeNumber(p.getBigIntegerValue());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001749 } else {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001750 writeNumber(p.getLongValue());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001751 }
1752 break;
1753 }
1754 case ID_NUMBER_FLOAT:
1755 {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001756 NumberType n = p.getNumberType();
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001757 if (n == NumberType.BIG_DECIMAL) {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001758 writeNumber(p.getDecimalValue());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001759 } else if (n == NumberType.FLOAT) {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001760 writeNumber(p.getFloatValue());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001761 } else {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001762 writeNumber(p.getDoubleValue());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001763 }
1764 break;
1765 }
1766 case ID_TRUE:
1767 writeBoolean(true);
1768 break;
1769 case ID_FALSE:
1770 writeBoolean(false);
1771 break;
1772 case ID_NULL:
1773 writeNull();
1774 break;
1775 case ID_EMBEDDED_OBJECT:
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001776 writeObject(p.getEmbeddedObject());
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001777 break;
1778 default:
1779 _throwInternal();
1780 }
1781 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001782
1783 /**
1784 * Method for copying contents of the current event
1785 * <b>and following events that it encloses</b>
1786 * the given parser instance points to.
1787 *<p>
1788 * So what constitutes enclosing? Here is the list of
1789 * events that have associated enclosed events that will
1790 * get copied:
1791 *<ul>
1792 * <li>{@link JsonToken#START_OBJECT}:
1793 * all events up to and including matching (closing)
1794 * {@link JsonToken#END_OBJECT} will be copied
1795 * </li>
1796 * <li>{@link JsonToken#START_ARRAY}
1797 * all events up to and including matching (closing)
1798 * {@link JsonToken#END_ARRAY} will be copied
1799 * </li>
1800 * <li>{@link JsonToken#FIELD_NAME} the logical value (which
1801 * can consist of a single scalar value; or a sequence of related
Tatu Saloranta17498b82016-01-04 22:29:52 -08001802 * events for structured types (JSON Arrays, Objects)) will
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001803 * be copied along with the name itself. So essentially the
1804 * whole <b>field entry</b> (name and value) will be copied.
1805 * </li>
1806 *</ul>
1807 *<p>
1808 * After calling this method, parser will point to the
1809 * <b>last event</b> that was copied. This will either be
1810 * the event parser already pointed to (if there were no
1811 * enclosed events), or the last enclosed event copied.
1812 */
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001813 public void copyCurrentStructure(JsonParser p) throws IOException
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001814 {
Tatu Salorantae052c312016-07-01 21:11:25 -07001815 JsonToken t = p.currentToken();
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001816 if (t == null) {
1817 _reportError("No current event to copy");
1818 }
1819 // Let's handle field-name separately first
1820 int id = t.id();
1821 if (id == ID_FIELD_NAME) {
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001822 writeFieldName(p.getCurrentName());
1823 t = p.nextToken();
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001824 id = t.id();
1825 // fall-through to copy the associated value
1826 }
1827 switch (id) {
1828 case ID_START_OBJECT:
1829 writeStartObject();
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001830 while (p.nextToken() != JsonToken.END_OBJECT) {
1831 copyCurrentStructure(p);
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001832 }
1833 writeEndObject();
1834 break;
1835 case ID_START_ARRAY:
1836 writeStartArray();
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001837 while (p.nextToken() != JsonToken.END_ARRAY) {
1838 copyCurrentStructure(p);
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001839 }
1840 writeEndArray();
1841 break;
1842 default:
Tatu Saloranta526b46d2016-02-26 18:09:32 -08001843 copyCurrentEvent(p);
Tatu Saloranta5cf2e6e2013-11-02 21:17:30 -07001844 }
1845 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001846
1847 /*
1848 /**********************************************************
1849 /* Public API, context access
1850 /**********************************************************
1851 */
1852
1853 /**
1854 * @return Context object that can give information about logical
1855 * position within generated json content.
1856 */
1857 public abstract JsonStreamContext getOutputContext();
1858
1859 /*
1860 /**********************************************************
1861 /* Public API, buffer handling
1862 /**********************************************************
1863 */
1864
1865 /**
1866 * Method called to flush any buffered content to the underlying
1867 * target (output stream, writer), and to flush the target itself
1868 * as well.
1869 */
Tatu Saloranta23439272013-04-06 20:44:18 -07001870 @Override
Tatu Salorantaf15531c2011-12-22 23:00:40 -08001871 public abstract void flush() throws IOException;
1872
1873 /**
1874 * Method that can be called to determine whether this generator
1875 * is closed or not. If it is closed, no more output can be done.
1876 */
1877 public abstract boolean isClosed();
1878
1879 /*
1880 /**********************************************************
1881 /* Closeable implementation
1882 /**********************************************************
1883 */
1884
1885 /**
1886 * Method called to close this generator, so that no more content
1887 * can be written.
1888 *<p>
1889 * Whether the underlying target (stream, writer) gets closed depends
1890 * on whether this generator either manages the target (i.e. is the
1891 * only one with access to the target -- case if caller passes a
1892 * reference to the resource such as File, but not stream); or
1893 * has feature {@link Feature#AUTO_CLOSE_TARGET} enabled.
1894 * If either of above is true, the target is also closed. Otherwise
1895 * (not managing, feature not enabled), target is not closed.
1896 */
Tatu Saloranta23439272013-04-06 20:44:18 -07001897 @Override
Tatu Salorantae9b48512012-04-17 10:22:07 -07001898 public abstract void close() throws IOException;
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001899
1900 /*
1901 /**********************************************************
1902 /* Helper methods for sub-classes
1903 /**********************************************************
1904 */
1905
1906 /**
1907 * Helper method used for constructing and throwing
1908 * {@link JsonGenerationException} with given base message.
1909 *<p>
1910 * Note that sub-classes may override this method to add more detail
1911 * or use a {@link JsonGenerationException} sub-class.
1912 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001913 protected void _reportError(String msg) throws JsonGenerationException {
Tatu Saloranta77be53c2015-08-17 22:52:56 -07001914 throw new JsonGenerationException(msg, this);
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001915 }
1916
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001917 protected final void _throwInternal() { VersionUtil.throwInternal(); }
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001918
1919 protected void _reportUnsupportedOperation() {
1920 throw new UnsupportedOperationException("Operation not supported by generator of type "+getClass().getName());
1921 }
Tatu Saloranta77be53c2015-08-17 22:52:56 -07001922
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001923 /**
Tatu Salorantabdc5c4e2016-05-10 09:06:38 -07001924 * @since 2.8
1925 */
1926 protected final void _verifyOffsets(int arrayLength, int offset, int length)
1927 {
1928 if ((offset < 0) || (offset + length) > arrayLength) {
1929 throw new IllegalArgumentException(String.format(
1930 "invalid argument(s) (offset=%d, length=%d) for input array of %d element",
1931 offset, length, arrayLength));
1932 }
1933 }
1934
1935 /**
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001936 * Helper method to try to call appropriate write method for given
1937 * untyped Object. At this point, no structural conversions should be done,
1938 * only simple basic types are to be coerced as necessary.
1939 *
1940 * @param value Non-null value to write
1941 */
Tatu Salorantaed4098c2014-01-16 22:46:10 -08001942 protected void _writeSimpleObject(Object value) throws IOException
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001943 {
1944 /* 31-Dec-2009, tatu: Actually, we could just handle some basic
1945 * types even without codec. This can improve interoperability,
1946 * and specifically help with TokenBuffer.
1947 */
1948 if (value == null) {
1949 writeNull();
1950 return;
1951 }
1952 if (value instanceof String) {
1953 writeString((String) value);
1954 return;
1955 }
1956 if (value instanceof Number) {
1957 Number n = (Number) value;
1958 if (n instanceof Integer) {
1959 writeNumber(n.intValue());
1960 return;
1961 } else if (n instanceof Long) {
1962 writeNumber(n.longValue());
1963 return;
1964 } else if (n instanceof Double) {
1965 writeNumber(n.doubleValue());
1966 return;
1967 } else if (n instanceof Float) {
1968 writeNumber(n.floatValue());
1969 return;
1970 } else if (n instanceof Short) {
1971 writeNumber(n.shortValue());
1972 return;
1973 } else if (n instanceof Byte) {
1974 writeNumber(n.byteValue());
1975 return;
1976 } else if (n instanceof BigInteger) {
1977 writeNumber((BigInteger) n);
1978 return;
1979 } else if (n instanceof BigDecimal) {
1980 writeNumber((BigDecimal) n);
1981 return;
Tatu Saloranta77be53c2015-08-17 22:52:56 -07001982
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001983 // then Atomic types
Tatu Saloranta0e10fd52013-11-02 21:12:49 -07001984 } else if (n instanceof AtomicInteger) {
1985 writeNumber(((AtomicInteger) n).get());
1986 return;
1987 } else if (n instanceof AtomicLong) {
1988 writeNumber(((AtomicLong) n).get());
1989 return;
1990 }
1991 } else if (value instanceof byte[]) {
1992 writeBinary((byte[]) value);
1993 return;
1994 } else if (value instanceof Boolean) {
1995 writeBoolean((Boolean) value);
1996 return;
1997 } else if (value instanceof AtomicBoolean) {
1998 writeBoolean(((AtomicBoolean) value).get());
1999 return;
2000 }
2001 throw new IllegalStateException("No ObjectCodec defined for the generator, can only serialize simple wrapper types (type passed "
2002 +value.getClass().getName()+")");
2003 }
Tatu Salorantaf15531c2011-12-22 23:00:40 -08002004}