package com.jsoniter; import com.jsoniter.any.Any; import java.io.IOException; class IterImpl { public static final int readObjectFieldAsHash(JsonIterator iter) throws IOException { if (nextToken(iter) != '"') { throw iter.reportError("readObjectFieldAsHash", "expect \""); } long hash = 0x811c9dc5; for (int i = iter.head; i < iter.tail; i++) { byte c = iter.buf[i]; if (c == '"') { iter.head = i + 1; if (nextToken(iter) != ':') { throw iter.reportError("readObjectFieldAsHash", "expect :"); } return (int) hash; } hash ^= c; hash *= 0x1000193; } throw iter.reportError("readObjectFieldAsHash", "unmatched quote"); } public static final Slice readObjectFieldAsSlice(JsonIterator iter) throws IOException { Slice field = readSlice(iter); if (nextToken(iter) != ':') { throw iter.reportError("readObjectFieldAsSlice", "expect : after object field"); } return field; } final static void skipArray(JsonIterator iter) throws IOException { int level = 1; for (int i = iter.head; i < iter.tail; i++) { switch (iter.buf[i]) { case '"': // If inside string, skip it iter.head = i + 1; skipString(iter); i = iter.head - 1; // it will be i++ soon break; case '[': // If open symbol, increase level level++; break; case ']': // If close symbol, increase level level--; // If we have returned to the original level, we're done if (level == 0) { iter.head = i + 1; return; } break; } } throw iter.reportError("skipArray", "incomplete array"); } final static void skipObject(JsonIterator iter) throws IOException { int level = 1; for (int i = iter.head; i < iter.tail; i++) { switch (iter.buf[i]) { case '"': // If inside string, skip it iter.head = i + 1; skipString(iter); i = iter.head - 1; // it will be i++ soon break; case '{': // If open symbol, increase level level++; break; case '}': // If close symbol, increase level level--; // If we have returned to the original level, we're done if (level == 0) { iter.head = i + 1; return; } break; } } throw iter.reportError("skipObject", "incomplete object"); } final static void skipString(JsonIterator iter) throws IOException { int end = IterImplSkip.findStringEnd(iter); if (end == -1) { throw iter.reportError("skipString", "incomplete string"); } else { iter.head = end; } } final static void skipUntilBreak(JsonIterator iter) throws IOException { // true, false, null, number for (int i = iter.head; i < iter.tail; i++) { byte c = iter.buf[i]; if (IterImplSkip.breaks[c]) { iter.head = i; return; } } iter.head = iter.tail; } final static boolean skipNumber(JsonIterator iter) throws IOException { // true, false, null, number boolean dotFound = false; for (int i = iter.head; i < iter.tail; i++) { byte c = iter.buf[i]; if (c == '.') { dotFound = true; continue; } if (IterImplSkip.breaks[c]) { iter.head = i; return dotFound; } } iter.head = iter.tail; return dotFound; } // read the bytes between " " public final static Slice readSlice(JsonIterator iter) throws IOException { if (IterImpl.nextToken(iter) != '"') { throw iter.reportError("readSlice", "expect \" for string"); } int end = IterImplString.findSliceEnd(iter); if (end == -1) { throw iter.reportError("readSlice", "incomplete string"); } else { // reuse current buffer iter.reusableSlice.reset(iter.buf, iter.head, end - 1); iter.head = end; return iter.reusableSlice; } } final static byte nextToken(JsonIterator iter) throws IOException { int i = iter.head; try { for (; ; ) { byte c = iter.buf[i++]; switch (c) { case ' ': case '\n': case '\r': case '\t': continue; default: if (i > iter.tail) { iter.head = iter.tail; return 0; } iter.head = i; return c; } } } catch (IndexOutOfBoundsException e) { iter.head = iter.tail; return 0; } } final static byte readByte(JsonIterator iter) throws IOException { if (iter.head == iter.tail) { return 0; } return iter.buf[iter.head++]; } public static Any readAny(JsonIterator iter) throws IOException { int start = iter.head; byte c = nextToken(iter); switch (c) { case '"': skipString(iter); return Any.lazyString(iter.buf, start, iter.head); case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (skipNumber(iter)) { return Any.lazyDouble(iter.buf, start, iter.head); } else { return Any.lazyLong(iter.buf, start, iter.head); } case 't': skipUntilBreak(iter); return Any.wrap(true); case 'f': skipUntilBreak(iter); return Any.wrap(false); case 'n': skipUntilBreak(iter); return Any.wrap((Object) null); case '[': skipArray(iter); return Any.lazyArray(iter.buf, start, iter.head); case '{': skipObject(iter); return Any.lazyObject(iter.buf, start, iter.head); default: throw iter.reportError("IterImplSkip", "do not know how to skip: " + c); } } }