![JAR search and dependency download from the Maven repository](/logo.png)
org.boon.json.implementation.JsonBaseByteArrayParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boon Show documentation
Show all versions of boon Show documentation
Simple opinionated Java for the novice to expert level Java Programmer.
Low Ceremony. High Productivity. A real boon to Java to developers!
/*
* Copyright 2013-2014 Richard M. Hightower
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* __________ _____ __ .__
* \______ \ ____ ____ ____ /\ / \ _____ | | _|__| ____ ____
* | | _// _ \ / _ \ / \ \/ / \ / \\__ \ | |/ / |/ \ / ___\
* | | ( <_> | <_> ) | \ /\ / Y \/ __ \| <| | | \/ /_/ >
* |______ /\____/ \____/|___| / \/ \____|__ (____ /__|_ \__|___| /\___ /
* \/ \/ \/ \/ \/ \//_____/
* ____. ___________ _____ ______________.___.
* | |____ ___ _______ \_ _____/ / _ \ / _____/\__ | |
* | \__ \\ \/ /\__ \ | __)_ / /_\ \ \_____ \ / | |
* /\__| |/ __ \\ / / __ \_ | \/ | \/ \ \____ |
* \________(____ /\_/ (____ / /_______ /\____|__ /_______ / / ______|
* \/ \/ \/ \/ \/ \/
*/
package org.boon.json.implementation;
import org.boon.IO;
import org.boon.core.Typ;
import org.boon.core.reflection.MapObjectConversion;
import org.boon.json.JsonException;
import org.boon.collections.LazyMap;
import org.boon.primitive.Byt;
import org.boon.primitive.ByteScanner;
import org.boon.primitive.CharBuf;
import org.boon.primitive.InMemoryInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.*;
import static org.boon.primitive.ByteScanner.skipWhiteSpaceFast;
/**
* Created by rick on 12/15/13.
*/
public abstract class JsonBaseByteArrayParser extends BaseJsonParser {
protected byte[] charArray;
protected int __index;
protected int __currentChar;
protected static final int NEW_LINE = '\n';
protected static final int RETURN = '\r';
protected static final int SPACE = ' ';
protected static final int TAB = '\t';
protected static final int BELL = '\b';
protected static final int FORM_FEED = '\f';
protected static final int COLON = ':';
protected static final int OPEN_CURLY = '{';
protected static final int OPEN_BRACKET = '[';
protected static final int LETTER_N = 'n';
protected static final int LETTER_U = 'u';
protected static final int LETTER_L = 'l';
protected static final int LETTER_T = 't';
protected static final int LETTER_R = 'r';
protected static final int LETTER_F = 'f';
protected static final int LETTER_A = 'a';
protected static final int LETTER_S = 's';
protected final CharBuf builder = CharBuf.create( 20 );
protected final boolean hasMore() {
return __index < lastIndex;
}
protected final boolean hasCurrent() {
return __index <= lastIndex;
}
protected final void skipWhiteSpaceIfNeeded() {
int ix = __index;
if (hasCurrent ()) {
this.__currentChar = this.charArray[ix];
}
if (__currentChar <= 32) {
ix = skipWhiteSpaceFast ( this.charArray, ix );
this.__currentChar = this.charArray[ix];
__index = ix;
}
}
protected final int nextChar() {
try {
if ( hasMore() ) {
__index++;
return __currentChar = charArray[ __index ];
} else {
return '\u0000';
}
} catch ( Exception ex ) {
throw new JsonException( exceptionDetails( "unable to advance character" ), ex );
}
}
protected String exceptionDetails( String message ) {
return ByteScanner.errorDetails(message, charArray, __index, __currentChar);
}
private static int skipWhiteSpaceFastBytes( byte [] array, int index ) {
int c;
for (; index< array.length; index++ ) {
c = array [index];
if ( c > 32 ) {
return index;
}
}
return index-1;
}
protected final void skipWhiteSpace() {
__index = skipWhiteSpaceFastBytes ( this.charArray, __index );
this.__currentChar = this.charArray[__index];
}
protected int lastIndex;
private Object decode( byte[] cs ) {
lastIndex = cs.length -1;
charArray = cs;
__index = 0;
return decodeValue();
}
public T parse( Class type, String str ) {
return this.parse( type, str.getBytes( charset ) );
}
public T parse( Class type, byte[] bytes ) {
if ( type == Map.class || type == List.class || Typ.isBasicType (type) ) {
return ( T ) this.decode( bytes );
} else {
Map objectMap = ( Map ) this.decode( bytes );
return MapObjectConversion.fromMap ( objectMap, type );
}
}
@Override
public Object parse ( byte[] bytes ) {
return this.decode ( bytes );
}
public T parse( Class type, InputStream input ) {
return parse( type, IO.input( input ) );
}
public T parse( Class type, CharSequence charSequence ) {
return parse( type, charSequence.toString() );
}
public T parse( Class type, char[] chars ) {
return parse( type, new String( chars ) );
}
protected void complain( String complaint ) {
throw new JsonException( exceptionDetails( complaint ) );
}
protected final Object decodeJsonObject() {
if ( __currentChar == OPEN_CURLY ) {
__index++;
}
LazyMap map = new LazyMap ();
for (; __index < this.charArray.length; __index++ ) {
skipWhiteSpaceIfNeeded ();
if ( __currentChar == DOUBLE_QUOTE ) {
String key =
decodeString();
if ( internKeys ) {
String keyPrime = internedKeysCache.get( key );
if ( keyPrime == null ) {
key = key.intern();
internedKeysCache.put( key, key );
} else {
key = keyPrime;
}
}
skipWhiteSpaceIfNeeded ();
if ( __currentChar != COLON ) {
complain( "expecting current character to be " + charDescription( __currentChar ) + "\n" );
}
__index++;
skipWhiteSpaceIfNeeded ();
Object value = decodeValue();
skipWhiteSpaceIfNeeded ();
map.put( key, value );
}
if ( __currentChar == CLOSED_CURLY ) {
__index++;
break;
} else if ( __currentChar == COMMA) {
continue;
} else {
complain(
"expecting '}' or ',' but got current char " + charDescription( __currentChar ) );
}
}
return map;
}
protected final Object decodeValue() {
Object value = null;
done:
for (; __index < this.charArray.length; __index++ ) {
__currentChar = charArray[ __index ];
switch ( __currentChar ) {
case NEW_LINE:
break;
case RETURN:
case SPACE:
case TAB:
case BELL:
case FORM_FEED:
break;
case DOUBLE_QUOTE:
value = decodeString ();
break done;
case LETTER_T:
value = decodeTrue();
break done;
case LETTER_F:
value = decodeFalse();
break done;
case LETTER_N:
value = decodeNull();
break done;
case OPEN_BRACKET:
value = decodeJsonArray();
break done;
case OPEN_CURLY:
value = decodeJsonObject();
break done;
case ALPHA_1:
case ALPHA_2:
case ALPHA_3:
case ALPHA_4:
case ALPHA_5:
case ALPHA_6:
case ALPHA_7:
case ALPHA_8:
case ALPHA_9:
case ALPHA_0:
value = decodeNumber();
break done;
case MINUS:
value = decodeNumber();
break done;
default:
throw new JsonException( exceptionDetails( "Unable to determine the " +
"current character, it is not a string, number, array, or object" ) );
}
}
return value;
}
int[] endIndex = new int[1];
private final Object decodeNumber() {
Number num = ByteScanner.parseJsonNumber( charArray, __index, charArray.length, endIndex );
__index = endIndex[0];
return num;
}
protected final static byte[] NULL = Byt.bytes( "null" );
protected final Object decodeNull() {
if ( __index + NULL.length <= charArray.length ) {
if ( charArray[ __index ] == LETTER_N &&
charArray[ ++__index ] == LETTER_U &&
charArray[ ++__index ] == LETTER_L &&
charArray[ ++__index ] == LETTER_L ) {
nextChar();
return null;
}
}
throw new JsonException( exceptionDetails( "null not parsed properly" ) );
}
protected final static byte[] TRUE = Byt.bytes( "true" );
protected final boolean decodeTrue() {
if ( __index + TRUE.length <= charArray.length ) {
if ( charArray[ __index ] == LETTER_T &&
charArray[ ++__index ] == LETTER_R &&
charArray[ ++__index ] == LETTER_U &&
charArray[ ++__index ] == LETTER_E ) {
nextChar();
return true;
}
}
throw new JsonException( exceptionDetails( "true not parsed properly" ) );
}
protected final static byte[] FALSE = Byt.bytes( "false" );
protected final boolean decodeFalse() {
if ( __index + FALSE.length <= charArray.length ) {
if ( charArray[ __index ] == LETTER_F &&
charArray[ ++__index ] == LETTER_A &&
charArray[ ++__index ] == LETTER_L &&
charArray[ ++__index ] == LETTER_S &&
charArray[ ++__index ] == LETTER_E ) {
nextChar();
return false;
}
}
throw new JsonException( exceptionDetails( "false not parsed properly" ) );
}
protected abstract String decodeString();
protected final List decodeJsonArray() {
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy