UNPKG

trader-server

Version:

OData server for testing strategies, simulating and real trading.

372 lines (307 loc) 14.3 kB
import Utils from "./utils"; import Lexer from "./lexer"; import PrimitiveLiteral from "./primitiveLiteral"; import NameOrIdentifier from "./nameOrIdentifier"; import Expressions from "./expressions"; export namespace ArrayOrObject { export function complexColInUri(value: Utils.SourceArray, index: number): Lexer.Token { let begin = Lexer.beginArray(value, index); if (begin === index) return; let start = index; index = begin; let items = []; let token = ArrayOrObject.complexInUri(value, index); if (token) { while (token) { items.push(token); index = token.next; let end = Lexer.endArray(value, index); if (end > index) { index = end; break; } else { let separator = Lexer.valueSeparator(value, index); if (separator === index) return; index = separator; token = ArrayOrObject.complexInUri(value, index); if (!token) return; } } } else { let end = Lexer.endArray(value, index); if (end === index) return; index = end; } return Lexer.tokenize(value, start, index, { items }, Lexer.TokenType.Array); } export function complexInUri(value: Utils.SourceArray, index: number): Lexer.Token { let begin = Lexer.beginObject(value, index); if (begin === index) return; let start = index; index = begin; let items = []; let token = ArrayOrObject.annotationInUri(value, index) || ArrayOrObject.primitivePropertyInUri(value, index) || ArrayOrObject.complexPropertyInUri(value, index) || ArrayOrObject.collectionPropertyInUri(value, index) || ArrayOrObject.navigationPropertyInUri(value, index); if (token) { while (token) { items.push(token); index = token.next; let end = Lexer.endObject(value, index); if (end > index) { index = end; break; } else { let separator = Lexer.valueSeparator(value, index); if (separator === index) return; index = separator; token = ArrayOrObject.annotationInUri(value, index) || ArrayOrObject.primitivePropertyInUri(value, index) || ArrayOrObject.complexPropertyInUri(value, index) || ArrayOrObject.collectionPropertyInUri(value, index) || ArrayOrObject.navigationPropertyInUri(value, index); if (!token) return; } } } else { let end = Lexer.endObject(value, index); if (end === index) return; index = end; } return Lexer.tokenize(value, start, index, { items }, Lexer.TokenType.Object); } export function collectionPropertyInUri(value: Utils.SourceArray, index: number): Lexer.Token { let mark = Lexer.quotationMark(value, index); if (mark === index) return; let start = index; index = mark; let prop = NameOrIdentifier.primitiveColProperty(value, index) || NameOrIdentifier.complexColProperty(value, index); if (!prop) return; index = prop.next; mark = Lexer.quotationMark(value, index); if (mark === index) return; index = mark; let separator = Lexer.nameSeparator(value, index); if (separator === index) return; index = separator; let propValue = prop.type === Lexer.TokenType.PrimitiveCollectionProperty ? ArrayOrObject.primitiveColInUri(value, index) : ArrayOrObject.complexColInUri(value, index); if (!propValue) return; index = propValue.next; return Lexer.tokenize(value, start, index, { key: prop, value: propValue }, Lexer.TokenType.Property); } export function primitiveColInUri(value: Utils.SourceArray, index: number): Lexer.Token { let begin = Lexer.beginArray(value, index); if (begin === index) return; let start = index; index = begin; let items = []; let token = ArrayOrObject.primitiveLiteralInJSON(value, index); if (token) { while (token) { items.push(token); index = token.next; let end = Lexer.endArray(value, index); if (end > index) { index = end; break; } else { let separator = Lexer.valueSeparator(value, index); if (separator === index) return; index = separator; token = ArrayOrObject.primitiveLiteralInJSON(value, index); if (!token) return; } } } else { let end = Lexer.endArray(value, index); if (end === index) return; index = end; } return Lexer.tokenize(value, start, index, { items }, Lexer.TokenType.Array); } export function complexPropertyInUri(value: Utils.SourceArray, index: number): Lexer.Token { let mark = Lexer.quotationMark(value, index); if (mark === index) return; let start = index; index = mark; let prop = NameOrIdentifier.complexProperty(value, index); if (!prop) return; index = prop.next; mark = Lexer.quotationMark(value, index); if (mark === index) return; index = mark; let separator = Lexer.nameSeparator(value, index); if (separator === index) return; index = separator; let propValue = ArrayOrObject.complexInUri(value, index); if (!propValue) return; index = propValue.next; return Lexer.tokenize(value, start, index, { key: prop, value: propValue }, Lexer.TokenType.Property); } export function annotationInUri(value: Utils.SourceArray, index: number): Lexer.Token { let mark = Lexer.quotationMark(value, index); if (mark === index) return; let start = index; index = mark; let at = Lexer.AT(value, index); if (!at) return; index = at; let namespaceNext = NameOrIdentifier.namespace(value, index); if (namespaceNext === index) return; let namespaceStart = index; index = namespaceNext; if (value[index] !== 0x2e) return; index++; let term = NameOrIdentifier.termName(value, index); if (!term) return; index = term.next; mark = Lexer.quotationMark(value, index); if (mark === index) return; index = mark; let separator = Lexer.nameSeparator(value, index); if (separator === index) return; index = separator; let token = ArrayOrObject.complexInUri(value, index) || ArrayOrObject.complexColInUri(value, index) || ArrayOrObject.primitiveLiteralInJSON(value, index) || ArrayOrObject.primitiveColInUri(value, index); if (!token) return; index = token.next; return Lexer.tokenize(value, start, index, { key: "@" + Utils.stringify(value, namespaceStart, namespaceNext) + "." + term.raw, value: token }, Lexer.TokenType.Annotation); } export function keyValuePairInUri(value: Utils.SourceArray, index: number, keyFn: Function, valueFn: Function): Lexer.Token { let mark = Lexer.quotationMark(value, index); if (mark === index) return; let start = index; index = mark; let prop = keyFn(value, index); if (!prop) return; index = prop.next; mark = Lexer.quotationMark(value, index); if (mark === index) return; index = mark; let separator = Lexer.nameSeparator(value, index); if (separator === index) return; index = separator; let propValue = valueFn(value, index); if (!propValue) return; index = propValue.next; return Lexer.tokenize(value, start, index, { key: prop, value: propValue }, Lexer.TokenType.Property); } export function primitivePropertyInUri(value: Utils.SourceArray, index: number): Lexer.Token { return ArrayOrObject.keyValuePairInUri(value, index, NameOrIdentifier.primitiveProperty, primitiveLiteralInJSON); } export function navigationPropertyInUri(value: Utils.SourceArray, index: number): Lexer.Token { return ArrayOrObject.singleNavPropInJSON(value, index) || ArrayOrObject.collectionNavPropInJSON(value, index); } export function singleNavPropInJSON(value: Utils.SourceArray, index: number): Lexer.Token { return ArrayOrObject.keyValuePairInUri(value, index, NameOrIdentifier.entityNavigationProperty, Expressions.rootExpr); } export function collectionNavPropInJSON(value: Utils.SourceArray, index: number): Lexer.Token { return ArrayOrObject.keyValuePairInUri(value, index, NameOrIdentifier.entityColNavigationProperty, rootExprCol); } export function rootExprCol(value: Utils.SourceArray, index: number): Lexer.Token { let begin = Lexer.beginArray(value, index); if (begin === index) return; let start = index; index = begin; let items = []; let token = Expressions.rootExpr(value, index); if (token) { while (token) { items.push(token); index = token.next; let end = Lexer.endArray(value, index); if (end > index) { index = end; break; } else { let separator = Lexer.valueSeparator(value, index); if (separator === index) return; index = separator; token = Expressions.rootExpr(value, index); if (!token) return; } } } else { let end = Lexer.endArray(value, index); if (end === index) return; index = end; } return Lexer.tokenize(value, start, index, { items }, Lexer.TokenType.Array); } export function primitiveLiteralInJSON(value: Utils.SourceArray, index: number): Lexer.Token { return ArrayOrObject.stringInJSON(value, index) || ArrayOrObject.numberInJSON(value, index) || ArrayOrObject.booleanInJSON(value, index) || ArrayOrObject.nullInJSON(value, index); } export function stringInJSON(value: Utils.SourceArray, index: number): Lexer.Token { let mark = Lexer.quotationMark(value, index); if (mark === index) return; let start = index; index = mark; let char = ArrayOrObject.charInJSON(value, index); while (char > index) { index = char; char = ArrayOrObject.charInJSON(value, index); } mark = Lexer.quotationMark(value, index); if (mark === index) return; index = mark; return Lexer.tokenize(value, start, index, "string", Lexer.TokenType.Literal); } export function charInJSON(value: Utils.SourceArray, index: number): number { let escape = Lexer.escape(value, index); if (escape > index) { if (Utils.equals(value, escape, "%2F")) return escape + 3; if (Utils.equals(value, escape, "/") || Utils.equals(value, escape, "b") || Utils.equals(value, escape, "f") || Utils.equals(value, escape, "n") || Utils.equals(value, escape, "r") || Utils.equals(value, escape, "t")) return escape + 1; if (Utils.equals(value, escape, "u") && Utils.required(value, escape + 1, Lexer.HEXDIG, 4, 4)) return escape + 5; let escapeNext = Lexer.escape(value, escape); if (escapeNext > escape) return escapeNext; let mark = Lexer.quotationMark(value, escape); if (mark > escape) return mark; } else { let mark = Lexer.quotationMark(value, index); if (mark === index) return index + 1; } } export function numberInJSON(value: Utils.SourceArray, index: number): Lexer.Token { let token = PrimitiveLiteral.doubleValue(value, index) || PrimitiveLiteral.int64Value(value, index); if (token) { token.value = "number"; return token; } } export function booleanInJSON(value: Utils.SourceArray, index: number): Lexer.Token { if (Utils.equals(value, index, "true")) return Lexer.tokenize(value, index, index + 4, "boolean", Lexer.TokenType.Literal); if (Utils.equals(value, index, "false")) return Lexer.tokenize(value, index, index + 5, "boolean", Lexer.TokenType.Literal); } export function nullInJSON(value: Utils.SourceArray, index: number): Lexer.Token { if (Utils.equals(value, index, "null")) return Lexer.tokenize(value, index, index + 4, "null", Lexer.TokenType.Literal); } export function arrayOrObject(value: Utils.SourceArray, index: number): Lexer.Token { let token = ArrayOrObject.complexColInUri(value, index) || ArrayOrObject.complexInUri(value, index) || ArrayOrObject.rootExprCol(value, index) || ArrayOrObject.primitiveColInUri(value, index); if (token) return Lexer.tokenize(value, index, token.next, token, Lexer.TokenType.ArrayOrObject); } } export default ArrayOrObject;