// supports 8 different character classes sclass JSONSpecialIntegral { int minLevel = 1, maxLevel = 8; byte[] input; int[] bracketLevel; byte[] quotesBitSet; // faster replacement for BitSet *() {} *(byte[] *input) {} void analyze(S input) { this.input = toUtf8(input); // XXX probably wrong analyze(); } void analyze(byte[] input) { this.input = input; analyze(); } void analyze { byte[] input = this.input; int n = input.length; bracketLevel = new int[n]; quotesBitSet = byteArrayBitSet_new(n); int bracketLvl = 0; bool inQuotes; for i to n: { byte b = input[i]; if (isOpener(b)) { if (!inQuotes) ++bracketLvl; } else if (isCloser(b)) { if (!inQuotes) --bracketLvl; } else if (b == '\'') { // TODO if (inQuotes) ... } else if (b == '"') { inQuotes = !inQuotes; } bracketLevel[i] = bracketLvl; setBit(quotesBitSet, i, inQuotes); } } int bracketLevel(int idx) { ret bracketLevel[rclamp(0, bracketLevel.length, idx)]; } bool inQuoteBit(int idx) { ret getBit(quotesBitSet, idx); } bool isOpener(byte b) { ret b == '{' || b == '['; } bool isCloser(byte b) { ret b == '}' || b == ']'; } S stats() { ret renderVars( inputLength := l(input), sizeFactor := formatDouble(elementSize(bracketLevel)+1/8.0), 2); } int n() { ret input.length; } }