Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   package com.fasterxml.jackson.core.json;
   
   import java.io.*;
   import java.math.BigDecimal;
   import java.math.BigInteger;
   
   
  public class UTF8JsonGenerator
      extends JsonGeneratorImpl
  {
      private final static byte BYTE_u = (byte'u';
  
      private final static byte BYTE_0 = (byte'0';
      
      private final static byte BYTE_LBRACKET = (byte'[';
      private final static byte BYTE_RBRACKET = (byte']';
      private final static byte BYTE_LCURLY = (byte'{';
      private final static byte BYTE_RCURLY = (byte'}';
   
      private final static byte BYTE_BACKSLASH = (byte'\\';
      private final static byte BYTE_COMMA = (byte',';
      private final static byte BYTE_COLON = (byte':';
      private final static byte BYTE_QUOTE = (byte'"';
  
      protected final static int SURR1_FIRST = 0xD800;
      protected final static int SURR1_LAST = 0xDBFF;
      protected final static int SURR2_FIRST = 0xDC00;
      protected final static int SURR2_LAST = 0xDFFF;
  
      // intermediate copies only made up to certain length...
      private final static int MAX_BYTES_TO_BUFFER = 512;
      
      final static byte[] HEX_CHARS = CharTypes.copyHexBytes();
  
      private final static byte[] NULL_BYTES = { 'n''u''l''l' };
      private final static byte[] TRUE_BYTES = { 't''r''u''e' };
      private final static byte[] FALSE_BYTES = { 'f''a''l''s''e' };
  
      /*
      /**********************************************************
      /* Output buffering
      /**********************************************************
       */
    
    
Underlying output stream used for writing JSON content.
  
      final protected OutputStream _outputStream;

    
Intermediate buffer in which contents are buffered before being written using _outputStream.
  
      protected byte[] _outputBuffer;

    
Pointer to the position right beyond the last character to output (end marker; may be past the buffer)
  
      protected int _outputTail = 0;

    
End marker of the output buffer; one past the last valid position within the buffer.
  
      protected final int _outputEnd;

    
Maximum number of chars that we know will always fit in the output buffer after escaping
  
      protected final int _outputMaxContiguous;
    
    
Intermediate buffer in which characters of a String are copied before being encoded.
  
      protected char[] _charBuffer;
    
    
Length of _charBuffer
  
      protected final int _charBufferLength;
    
    
6 character temporary buffer allocated if needed, for constructing escape sequences
  
      protected byte[] _entityBuffer;

    
Flag that indicates whether the output buffer is recycable (and needs to be returned to recycler once we are done) or not.
  
      protected boolean _bufferRecyclable;
      
      /*
     /**********************************************************
     /* Life-cycle
     /**********************************************************
      */
 
     public UTF8JsonGenerator(IOContext ctxtint featuresObjectCodec codec,
             OutputStream out)
     {
         super(ctxtfeaturescodec);
          = out;
          = true;
          = ctxt.allocWriteEncodingBuffer();
          = .;
 
         /* To be exact, each char can take up to 6 bytes when escaped (Unicode
          * escape with backslash, 'u' and 4 hex digits); but to avoid fluctuation,
          * we will actually round down to only do up to 1/8 number of chars
          */
          =  >> 3;
          = ctxt.allocConcatBuffer();
          = .;
 
         // By default we use this feature to determine additional quoting
         if (isEnabled(.)) {
             setHighestNonEscapedChar(127);
         }
     }
     
     public UTF8JsonGenerator(IOContext ctxtint featuresObjectCodec codec,
             OutputStream out,
             byte[] outputBufferint outputOffsetboolean bufferRecyclable)
     {
         
         super(ctxtfeaturescodec);
          = out;
          = bufferRecyclable;
          = outputOffset;
          = outputBuffer;
          = .;
         // up to 6 bytes per char (see above), rounded up to 1/8
          =  >> 3;
          = ctxt.allocConcatBuffer();
          = .;
     }
 
     /*
     /**********************************************************
     /* Overridden configuration methods
     /**********************************************************
      */
     
     @Override
     public Object getOutputTarget() {
         return ;
     }
 
     /*
     /**********************************************************
     /* Overridden methods
     /**********************************************************
      */
 
     @Override
     public final void writeFieldName(String name)  throws IOExceptionJsonGenerationException
     {
         int status = .writeFieldName(name);
         if (status == .) {
             _reportError("Can not write a field name, expecting a value");
         }
         if ( != null) {
             _writePPFieldName(name, (status == .));
             return;
         }
         if (status == .) { // need comma
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
         _writeFieldName(name);
     }
 
     @Override
     public final void writeFieldName(SerializableString name)
         throws IOExceptionJsonGenerationException
     {
         // Object is a value, need to verify it's allowed
         int status = .writeFieldName(name.getValue());
         if (status == .) {
             _reportError("Can not write a field name, expecting a value");
         }
         if ( != null) {
             _writePPFieldName(name, (status == .));
             return;
         }
         if (status == .) {
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
         _writeFieldName(name);
     }
 
     /*
     /**********************************************************
     /* Output method implementations, structural
     /**********************************************************
      */
 
     @Override
     public final void writeStartArray() throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("start an array");
         if ( != null) {
             .writeStartArray(this);
         } else {
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
     }
 
     @Override
     public final void writeEndArray() throws IOExceptionJsonGenerationException
     {
         if (!.inArray()) {
             _reportError("Current context not an ARRAY but "+.getTypeDesc());
         }
         if ( != null) {
             .writeEndArray(this.getEntryCount());
         } else {
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
          = .getParent();
     }
 
     @Override
     public final void writeStartObject() throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("start an object");
         if ( != null) {
             .writeStartObject(this);
         } else {
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
     }
 
     @Override
     public final void writeEndObject() throws IOExceptionJsonGenerationException
     {
         if (!.inObject()) {
             _reportError("Current context not an object but "+.getTypeDesc());
         }
         if ( != null) {
             .writeEndObject(this.getEntryCount());
         } else {
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
          = .getParent();
     }
 
     protected final void _writeFieldName(String name)
         throws IOExceptionJsonGenerationException
     {
         /* To support [JACKSON-46], we'll do this:
          * (Question: should quoting of spaces (etc) still be enabled?)
          */
         if (!isEnabled(.)) {
             _writeStringSegments(name);
             return;
         }
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         // The beef:
         final int len = name.length();
         if (len <= ) { // yes, fits right in
             name.getChars(0, len, 0);
             // But as one segment, or multiple?
             if (len <= ) {
                 if (( + len) > ) { // caller must ensure enough space
                     _flushBuffer();
                 }
                 _writeStringSegment(, 0, len);
             } else {
                 _writeStringSegments(, 0, len);
             }
         } else {
             _writeStringSegments(name);
         }
 
         // and closing quotes; need room for one more char:
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
 
     protected final void _writeFieldName(SerializableString name)
         throws IOExceptionJsonGenerationException
     {
         if (!isEnabled(.)) {
             int len = name.appendQuotedUTF8(); // different quoting (escaping)
             if (len < 0) {
                 _writeBytes(name.asQuotedUTF8());
             } else {
                  += len;
             }
             return;
         }
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         int len = name.appendQuotedUTF8();
         if (len < 0) { // couldn't append, bit longer processing
             _writeBytes(name.asQuotedUTF8());
         } else {
              += len;
         }
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }    
    
    
Specialized version of _writeFieldName, off-lined to keep the "fast path" as simple (and hopefully fast) as possible.
 
     protected final void _writePPFieldName(String nameboolean commaBefore)
         throws IOExceptionJsonGenerationException
     {
         if (commaBefore) {
             .writeObjectEntrySeparator(this);
         } else {
             .beforeObjectEntries(this);
         }
 
         if (isEnabled(.)) { // standard
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
             final int len = name.length();
             if (len <= ) { // yes, fits right in
                 name.getChars(0, len, 0);
                 // But as one segment, or multiple?
                 if (len <= ) {
                     if (( + len) > ) { // caller must ensure enough space
                         _flushBuffer();
                     }
                     _writeStringSegment(, 0, len);
                 } else {
                     _writeStringSegments(, 0, len);
                 }
             } else {
                 _writeStringSegments(name);
             }
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         } else { // non-standard, omit quotes
             _writeStringSegments(name);
         }
     }
 
     protected final void _writePPFieldName(SerializableString nameboolean commaBefore)
         throws IOExceptionJsonGenerationException
     {
         if (commaBefore) {
             .writeObjectEntrySeparator(this);
         } else {
             .beforeObjectEntries(this);
         }
 
         boolean addQuotes = isEnabled(.); // standard
         if (addQuotes) {
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
         _writeBytes(name.asQuotedUTF8());
         if (addQuotes) {
             if ( >= ) {
                 _flushBuffer();
             }
             [++] = ;
         }
     }
     
     /*
     /**********************************************************
     /* Output method implementations, textual
     /**********************************************************
      */
 
     @Override
     public void writeString(String text)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write text value");
         if (text == null) {
             _writeNull();
             return;
         }
         // First: can we make a local copy of chars that make up text?
         final int len = text.length();
         if (len > ) { // nope: off-line handling
             _writeLongString(text);
             return;
         }
         // yes: good.
         text.getChars(0, len, 0);
         // Output: if we can't guarantee it fits in output buffer, off-line as well:
         if (len > ) {
             _writeLongString(, 0, len);
             return;
         }
         if (( + len) >= ) {
             _flushBuffer();
         }
         [++] = ;
         _writeStringSegment(, 0, len); // we checked space already above
         /* [JACKSON-462] But that method may have had to expand multi-byte Unicode
          *   chars, so we must check again
          */
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
     
     private void _writeLongString(String text)
         throws IOExceptionJsonGenerationException
     {
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         _writeStringSegments(text);
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
 
     private void _writeLongString(char[] textint offsetint len)
         throws IOExceptionJsonGenerationException
     {
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         _writeStringSegments(, 0, len);
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
 
     @Override
     public void writeString(char[] textint offsetint len)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write text value");
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         // One or multiple segments?
         if (len <= ) {
             if (( + len) > ) { // caller must ensure enough space
                 _flushBuffer();
             }
             _writeStringSegment(textoffsetlen);
         } else {
             _writeStringSegments(textoffsetlen);
         }
         // And finally, closing quotes
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
 
     @Override
     public final void writeString(SerializableString text)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write text value");
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         int len = text.appendQuotedUTF8();
         if (len < 0) {
             _writeBytes(text.asQuotedUTF8());
         } else {
              += len;
         }
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
 
     @Override
     public void writeRawUTF8String(byte[] textint offsetint length)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write text value");
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         _writeBytes(textoffsetlength);
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
 
     @Override
     public void writeUTF8String(byte[] textint offsetint len)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write text value");
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         // One or multiple segments?
         if (len <= ) {
             _writeUTF8Segment(textoffsetlen);
         } else {
             _writeUTF8Segments(textoffsetlen);
         }
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
     
     /*
     /**********************************************************
     /* Output method implementations, unprocessed ("raw")
     /**********************************************************
      */
 
     @Override
     public void writeRaw(String text)
         throws IOExceptionJsonGenerationException
     {
         int start = 0;
         int len = text.length();
         while (len > 0) {
             char[] buf = ;
             final int blen = buf.length;
             final int len2 = (len < blen) ? len : blen;
             text.getChars(startstart+len2buf, 0);
             writeRaw(buf, 0, len2);
             start += len2;
             len -= len2;
         }
     }
 
     @Override
     public void writeRaw(String textint offsetint len)
         throws IOExceptionJsonGenerationException
     {
         while (len > 0) {
             char[] buf = ;
             final int blen = buf.length;
             final int len2 = (len < blen) ? len : blen;
             text.getChars(offsetoffset+len2buf, 0);
             writeRaw(buf, 0, len2);
             offset += len2;
             len -= len2;
         }
     }
 
     @Override
     public void writeRaw(SerializableString textthrows IOExceptionJsonGenerationException
     {
         byte[] raw = text.asUnquotedUTF8();
         if (raw.length > 0) {
             _writeBytes(raw);
         }
     }
     
     // @TODO: rewrite for speed...
     @Override
     public final void writeRaw(char[] cbufint offsetint len)
         throws IOExceptionJsonGenerationException
     {
         // First: if we have 3 x charCount spaces, we know it'll fit just fine
         {
             int len3 = len+len+len;
             if (( + len3) > ) {
                 // maybe we could flush?
                 if ( < len3) { // wouldn't be enough...
                     _writeSegmentedRaw(cbufoffsetlen);
                     return;
                 }
                 // yes, flushing brings enough space
                 _flushBuffer();
             }
         }
         len += offset// now marks the end
 
         // Note: here we know there is enough room, hence no output boundary checks
         main_loop:
         while (offset < len) {
             inner_loop:
             while (true) {
                 int ch = (intcbuf[offset];
                 if (ch > 0x7F) {
                     break inner_loop;
                 }
                 [++] = (bytech;
                 if (++offset >= len) {
                     break main_loop;
                 }
             }
             char ch = cbuf[offset++];
             if (ch < 0x800) { // 2-byte?
                 [++] = (byte) (0xc0 | (ch >> 6));
                 [++] = (byte) (0x80 | (ch & 0x3f));
             } else {
                 _outputRawMultiByteChar(chcbufoffsetlen);
             }
         }
     }
 
     @Override
     public void writeRaw(char ch)
         throws IOExceptionJsonGenerationException
     {
         if (( + 3) >= ) {
             _flushBuffer();
         }
         final byte[] bbuf = ;
         if (ch <= 0x7F) {
             bbuf[++] = (bytech;
         } else  if (ch < 0x800) { // 2-byte?
             bbuf[++] = (byte) (0xc0 | (ch >> 6));
             bbuf[++] = (byte) (0x80 | (ch & 0x3f));
         } else {
             _outputRawMultiByteChar(chnull, 0, 0);
         }
     }

    
Helper method called when it is possible that output of raw section to output may cross buffer boundary
 
     private void _writeSegmentedRaw(char[] cbufint offsetint len)
         throws IOExceptionJsonGenerationException
     {
         final int end = ;
         final byte[] bbuf = ;
         
         main_loop:
         while (offset < len) {
             inner_loop:
             while (true) {
                 int ch = (intcbuf[offset];
                 if (ch >= 0x80) {
                     break inner_loop;
                 }
                 // !!! TODO: fast(er) writes (roll input, output checks in one)
                 if ( >= end) {
                     _flushBuffer();
                 }
                 bbuf[++] = (bytech;
                 if (++offset >= len) {
                     break main_loop;
                 }
             }
             if (( + 3) >= ) {
                 _flushBuffer();
             }
             char ch = cbuf[offset++];
             if (ch < 0x800) { // 2-byte?
                 bbuf[++] = (byte) (0xc0 | (ch >> 6));
                 bbuf[++] = (byte) (0x80 | (ch & 0x3f));
             } else {
                 _outputRawMultiByteChar(chcbufoffsetlen);
             }
         }
     }
     
     /*
     /**********************************************************
     /* Output method implementations, base64-encoded binary
     /**********************************************************
      */
 
     @Override
     public void writeBinary(Base64Variant b64variant,
             byte[] dataint offsetint len)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write binary value");
         // Starting quotes
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         _writeBinary(b64variantdataoffsetoffset+len);
         // and closing quotes
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
 
     @Override
     public int writeBinary(Base64Variant b64variant,
             InputStream dataint dataLength)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write binary value");
         // Starting quotes
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         byte[] encodingBuffer = .allocBase64Buffer();
         int bytes;
         try {
             if (dataLength < 0) { // length unknown
                 bytes = _writeBinary(b64variantdataencodingBuffer);
             } else {
                 int missing = _writeBinary(b64variantdataencodingBufferdataLength);
                 if (missing > 0) {
                     _reportError("Too few bytes available: missing "+missing+" bytes (out of "+dataLength+")");
                 }
                 bytes = dataLength;
             }
         } finally {
             .releaseBase64Buffer(encodingBuffer);
         }
         // and closing quotes
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         return bytes;
     }
     
     /*
     /**********************************************************
     /* Output method implementations, primitive
     /**********************************************************
      */
 
     @Override
     public void writeNumber(int i)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write number");
         // up to 10 digits and possible minus sign
         if (( + 11) >= ) {
             _flushBuffer();
         }
         if () {
             _writeQuotedInt(i);
             return;
         }
          = NumberOutput.outputInt(i);
     }
 
     private void _writeQuotedInt(int ithrows IOException {
         if (( + 13) >= ) {
             _flushBuffer();
         }
         [++] = ;
          = NumberOutput.outputInt(i);
         [++] = ;
     }    
 
     @Override
     public void writeNumber(long l)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write number");
         if () {
             _writeQuotedLong(l);
             return;
         }
         if (( + 21) >= ) {
             // up to 20 digits, minus sign
             _flushBuffer();
         }
          = NumberOutput.outputLong(l);
     }
 
     private void _writeQuotedLong(long lthrows IOException {
         if (( + 23) >= ) {
             _flushBuffer();
         }
         [++] = ;
          = NumberOutput.outputLong(l);
         [++] = ;
     }
 
     @Override
     public void writeNumber(BigInteger value)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write number");
         if (value == null) {
             _writeNull();
         } else if () {
             _writeQuotedRaw(value);
         } else {
             writeRaw(value.toString());
         }
     }
 
     
     @Override
     public void writeNumber(double d)
         throws IOExceptionJsonGenerationException
     {
         if ( ||
             // [JACKSON-139]
             (((Double.isNaN(d) || Double.isInfinite(d))
                 && isEnabled(.)))) {
             writeString(String.valueOf(d));
             return;
         }
         // What is the max length for doubles? 40 chars?
         _verifyValueWrite("write number");
         writeRaw(String.valueOf(d));
     }
 
     @Override
     public void writeNumber(float f)
         throws IOExceptionJsonGenerationException
     {
         if ( ||
             // [JACKSON-139]
             (((Float.isNaN(f) || Float.isInfinite(f))
                 && isEnabled(.)))) {
             writeString(String.valueOf(f));
             return;
         }
         // What is the max length for floats?
         _verifyValueWrite("write number");
         writeRaw(String.valueOf(f));
     }
 
     @Override
     public void writeNumber(BigDecimal value)
         throws IOExceptionJsonGenerationException
     {
         // Don't really know max length for big decimal, no point checking
         _verifyValueWrite("write number");
         if (value == null) {
             _writeNull();
         } else if () {
             _writeQuotedRaw(value);
         } else {
             writeRaw(value.toString());
         }
     }
 
     @Override
     public void writeNumber(String encodedValue)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write number");
         if () {
             _writeQuotedRaw(encodedValue);            
         } else {
             writeRaw(encodedValue);
         }
     }
 
     private void _writeQuotedRaw(Object valuethrows IOException
     {
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
         writeRaw(value.toString());
         if ( >= ) {
             _flushBuffer();
         }
         [++] = ;
     }
     
     @Override
     public void writeBoolean(boolean state)
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write boolean value");
         if (( + 5) >= ) {
             _flushBuffer();
         }
         byte[] keyword = state ?  : ;
         int len = keyword.length;
         System.arraycopy(keyword, 0, len);
          += len;
     }
 
     @Override
     public void writeNull()
         throws IOExceptionJsonGenerationException
     {
         _verifyValueWrite("write null value");
         _writeNull();
     }
 
     /*
     /**********************************************************
     /* Implementations for other methods
     /**********************************************************
      */
 
     @Override
     protected final void _verifyValueWrite(String typeMsg)
         throws IOExceptionJsonGenerationException
     {
         int status = .writeValue();
         if (status == .) {
             _reportError("Can not "+typeMsg+", expecting field name");
         }
         if ( == null) {
             byte b;
             switch (status) {
             case .:
                 b = ;
                 break;
             case .:
                 b = ;
                 break;
             case .// root-value separator
                 if ( != null) {
                     byte[] raw = .asUnquotedUTF8();
                     if (raw.length > 0) {
                         _writeBytes(raw);
                     }
                 }
                 return;
             case .:
             default:
                 return;
             }
             if ( >= ) {
                 _flushBuffer();
             }
             [] = b;
             ++;
             return;
         }
         // Otherwise, pretty printer knows what to do...
         _verifyPrettyValueWrite(typeMsgstatus);
     }
 
     protected final void _verifyPrettyValueWrite(String typeMsgint status)
         throws IOExceptionJsonGenerationException
     {
         // If we have a pretty printer, it knows what to do:
         switch (status) {
         case .// array
             .writeArrayValueSeparator(this);
             break;
             .writeObjectFieldValueSeparator(this);
             break;
             .writeRootValueSeparator(this);
             break;
         case .:
             // First entry, but of which context?
             if (.inArray()) {
                 .beforeArrayValues(this);
             } else if (.inObject()) {
                 .beforeObjectEntries(this);
             }
            break;
        default:
            _cantHappen();
            break;
        }
    }
    /*
    /**********************************************************
    /* Low-level output handling
    /**********************************************************
     */
    @Override
    public final void flush()
        throws IOException
    {
        _flushBuffer();
        if ( != null) {
            if (isEnabled(.)) {
                .flush();
            }
        }
    }
    @Override
    public void close()
        throws IOException
    {
        super.close();
        /* 05-Dec-2008, tatu: To add [JACKSON-27], need to close open
         *   scopes.
         */
        // First: let's see that we still have buffers...
        if ( != null
            && isEnabled(.)) {
            while (true) {
                JsonStreamContext ctxt = getOutputContext();
                if (ctxt.inArray()) {
                    writeEndArray();
                } else if (ctxt.inObject()) {
                    writeEndObject();
                } else {
                    break;
                }
            }
        }
        _flushBuffer();
        /* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close()
         *   on the underlying Reader, unless we "own" it, or auto-closing
         *   feature is enabled.
         *   One downside: when using UTF8Writer, underlying buffer(s)
         *   may not be properly recycled if we don't close the writer.
         */
        if ( != null) {
            if (.isResourceManaged() || isEnabled(.)) {
                .close();
            } else  if (isEnabled(.)) {
                // If we can't close it, we should at least flush
                <