Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.jackson.dataformat.smile;
  
  import java.io.*;
  
 
 import static com.fasterxml.jackson.dataformat.smile.SmileConstants.*;

Simple bootstrapper version used with Smile format parser.
 
 public class SmileParserBootstrapper
 {
     /*
     /**********************************************************
     /* Configuration
     /**********************************************************
      */
 
     protected final IOContext _context;
 
     protected final InputStream _in;
     
     /*
     /**********************************************************
     /* Input buffering
     /**********************************************************
      */
 
     protected final byte[] _inputBuffer;
 
     protected int _inputPtr;
 
     protected int _inputEnd;

    
Flag that indicates whether buffer above is to be recycled after being used or not.
 
     protected final boolean _bufferRecyclable;
 
     /*
     /**********************************************************
     /* Input location
     /**********************************************************
      */

    
Current number of input units (bytes or chars) that were processed in previous blocks, before contents of current input buffer.

Note: includes possible BOMs, if those were part of the input.

 
     protected int _inputProcessed;
 
     /*
     /**********************************************************
     /* Life-cycle
     /**********************************************************
      */
 
     public SmileParserBootstrapper(IOContext ctxtInputStream in)
     {
          = ctxt;
          = in;
          = ctxt.allocReadIOBuffer();
          =  = 0;
          = 0;
          = true;
     }
 
     public SmileParserBootstrapper(IOContext ctxtbyte[] inputBufferint inputStartint inputLen)
     {
          = ctxt;
          = null;
          = inputBuffer;
          = inputStart;
          = (inputStart + inputLen);
         // Need to offset this for correct location info
          = -inputStart;
          = false;
     }
 
     public SmileParser constructParser(int generalParserFeaturesint smileFeatures,
             boolean internNames,
             ObjectCodec codecBytesToNameCanonicalizer rootByteSymbols)
         throws IOExceptionJsonParseException
     {
         BytesToNameCanonicalizer can = rootByteSymbols.makeChild(trueinternNames);
     	// We just need a single byte, really, to know if it starts with header
     	ensureLoaded(1);
         SmileParser p = new SmileParser(generalParserFeaturessmileFeatures,
                 codeccan
                 );
        boolean hadSig = false;
        if ( < ) { // only false for empty doc
            if ([] == .) {
                // need to ensure it gets properly handled so caller won't see the signature
                hadSig = p.handleSignature(truetrue);
            }
    	} else {
    	    /* 11-Oct-2012, tatu: Actually, let's allow empty documents even if
    	     *   header signature would otherwise be needed. This is useful for
    	     *   JAX-RS provider, empty PUT/POST payloads.
    	     */
    	    return p;
    	}
    	if (!hadSig && (smileFeatures & ...getMask()) != 0) {
    	    // Ok, first, let's see if it looks like plain JSON...
    	    String msg;
    	    byte firstByte = ( < ) ? [] : 0;
    	    if (firstByte == '{' || firstByte == '[') {
                msg = "Input does not start with Smile format header (first byte = 0x"
                    +Integer.toHexString(firstByte & 0xFF)+") -- rather, it starts with '"+((charfirstByte)
                    +"' (plain JSON input?) -- can not parse";
    	    } else {
                msg = "Input does not start with Smile format header (first byte = 0x"
                +Integer.toHexString(firstByte & 0xFF)+") and parser has REQUIRE_HEADER enabled: can not parse";
    	    }
    	    throw new JsonParseException(msg.);
    	}
        return p;
    }
    /*
    /**********************************************************
    /*  Encoding detection for data format auto-detection
    /**********************************************************
     */
    public static MatchStrength hasSmileFormat(InputAccessor accthrows IOException
    {
        // Ok: ideally we start with the header -- if so, we are golden
        if (!acc.hasMoreBytes()) {
            return .;
        }
        // We always need at least two bytes to determine, so
        byte b1 = acc.nextByte();
        if (!acc.hasMoreBytes()) {
            return .;
        }
        byte b2 = acc.nextByte();
        
        // First: do we see 3 "magic bytes"? If so, we are golden
        if (b1 == .) { // yeah, looks like marker
            if (b2 != .) {
                return .;
            }
            if (!acc.hasMoreBytes()) {
                return .;
            }
            return (acc.nextByte() == .) ?
                    . : .;
        }
        // Otherwise: ideally either Object or Array:
        if (b1 == .) {
            /* Object is bit easier, because now we need to get new name; i.e. can
             * rule out name back-refs
             */
            if (b2 == .) {
                return .;
            }
            int ch = (intb2 & 0xFF;
            if (ch >= 0x80 && ch < 0xF8) {
                return .;
            }
            return .;
        }
        // Array bit trickier
        if (b1 == .) {
            if (!acc.hasMoreBytes()) {
                return .;
            }
            /* For arrays, we will actually accept much wider range of values (including
             * things that could otherwise collide)
             */
            if (likelySmileValue(b2) || possibleSmileValue(b2true)) {
                return .;
            }
            return .;
        }
        // Scalar values are pretty weak, albeit possible; require more certain match, consider it weak:
        if (likelySmileValue(b1) || possibleSmileValue(b2false)) {
            return .;
        }
        return .;
    }
    private static boolean likelySmileValue(byte b)
    {
        if (   (b == // 0xE0
            || (b == // 0xE4
            || (b == // 0xE8
            || (b == // 0xF8
            || (b == // 0xFA
            ) {
            return true;
        }
        int ch = b & 0xFF;
        // ASCII ctrl char range is pretty good match too
        if (ch >= 0x80 && ch <= 0x9F) {
            return true;
        }
        return false;
    }

    

Parameters:
lenient Whether to consider more speculative matches or not (typically true when there is context like start-array)
    private static boolean possibleSmileValue(byte bboolean lenient)
    {
        int ch = (intb & 0xFF;
        // note: we know that likely matches have been handled already, so...
        if (ch >= 0x80) {
            return (ch <= 0xE0);
        }
        if (lenient) {
            if (ch >= 0x40) { // tiny/short ASCII
                return true;
            }
            if (ch >- 0x20) { // various constants
                return (ch < 0x2C); // many reserved bytes that can't be seen
            }
        }
        return false;
    }
    
    /*
    /**********************************************************
    /* Internal methods, raw input access
    /**********************************************************
     */
    protected boolean ensureLoaded(int minimum)
        throws IOException
    {
        if ( == null) { // block source; nothing more to load
            return false;
        }
        /* Let's assume here buffer has enough room -- this will always
         * be true for the limited used this method gets
         */
        int gotten = ( - );
        while (gotten < minimum) {
            int count = .read(. - );
            if (count < 1) {
                return false;
            }
             += count;
            gotten += count;
        }
        return true;
    }
New to GrepCode? Check out our FAQ X