forked from nique_372/JsonParserByLeo
102 lines
6.6 KiB
Markdown
102 lines
6.6 KiB
Markdown
# Especificaciones de JsonParserByLeo
| |
| |
En este documento se presenta los siguientes puntos de JsonParserByLeo:
| |
- Garantias: que garantiza la lib, que valida, etc..
| |
- Casos (raros) en los cuales falla: Exacatmanete cual es el comportamiento de la liberia en ciertos casos.
| |
- Filosofica general: Como es que ha sido contruida esta lib
| |
| |
| |
## Filosofia de diseño
| |
JsonParserByLeo al igual qeu todo el ecositema TSN, prioriza maxima velocida a un nivel (techo de MQL5)
| |
no nos conformamos con un "algortimo que es rapido" buscamos siempre la mejor forma en la que esto se pueda hacer en MQL5 puro,
| |
llegando al limite del lenguaje...
| |
| |
| |
JsonParserByLeo como tal no es una sola liberia JSON.. si no un conjunto de libs para trabajr con JSON en MQL5..
| |
pero el motor "principal" CJsonParser sigue el siguiente estilo:
| |
- DOM (Tape Style): se usa un array long[] para representar el "AST" del JSON
| |
- Eager: Materializa los numeros, booleanos, nulls, etc..
| |
- Lazy: Guarda offsets\len SOLO para keys y strings.
| |
- Solo lectura: No puedes modificar los campos.. solo es para leer un documento, pero puedes navegar tranquilamente o reeler el mismo nodo,
| |
es como la api de un dom (por ejemplo JAson
| |
en la cual peudes navegar tranquilamente, modifcar, etc) pero sin la posiblidad de modificar un nodo.
| |
> Nota: esto solo aplica a CJsonParser... se peude, apartir del tape llamar al backend de CJsonParser en especifico al dom builder
| |
> (CJsonNode::ToDom) para hacer un objeto en memoria el cual si que permite mutar completamente el JSON.
| |
| |
Se podria decir que es una combinacino de DOM y OnDemanad usando el estilo tape (popuralizado por simdjson).
| |
| |
### Arquitectura en si
| |
Tome un par ideas prestadas de simdjson, en concreto estas ideas:
| |
1. Uso de un tape para representar el documento json.
| |
2. Algortimo para detectar el cierre de un string on manejo de escapes.
| |
> Asi que podriamos decir qeu esto no es un port o algo similar... Es en esencia agarrar un par de ideas de algo que funciona en general
| |
> luego aplicar un conocimiento del lengauje host (MQL5) tenicas, de optimzicion y estilo propio de hacer las cosas.. aqui en MQL5.
| |
| |
Todo lo demas (lista enlazada para "pop" "push", algortimo de numeros, arquiteucta de como organizar
| |
las clases las herencias, JIT, algortimo de estados, etc etc) ha sido mi estilo propio o ideas que se me ocurrieron..
| |
en otros proyectos e integre aqui o cuando desarollaba este parser.
| |
| |
### JsonParserByLeo - (extras)
| |
JsonParserByLeo como tal no implemnta todo lo que promete en el README en este repositorio...
| |
Si no que usa el backend de BasesParserSLan (VM y DOM mutable) aqui.. en ese caso jsonparserbyleo
| |
solo "Transforma" su tape a ese formato.. y ya se integra.. tambien JsonPartserByLeo sirve como un ejemplo de uso
| |
de basesparserslan que es un framework que provee utilidades, dom, vm, etc.. para armar parsers de
| |
(base structured language) osea formatos estructurados como JSON, YAML, TOML, etc.., o un lenguaje custom...
| |
tambien se puede reutilizar ciertas partes para parsers mas especificos como .ini, o .rsp, etc..
| |
| |
## (Casos borde) - Resumen de areas
| |
| |
### Parsing (JsonAsm - Json - JsonSax)
| |
| |
1. **Integers**: if the limit is exceeded (`ULONG_MAX` for positive values, or `LONG_MIN` for negative values), the library understands that it is a big int, so it does not throw an overflow error; instead it stores it as a "string", and you can extract the result via `ToString()` with no loss.
| |
2. **Reals**: this is split into the following layers:
| |
> - a) If the number can be represented properly, it is stored as-is as a `double`.
| |
> - b) The number already loses a little precision, but not much, it gets approximated.
| |
> - c) The number is large (for example, exponent > 22 or < -22, etc.) and gets promoted to a string. In `ToDouble`, the `StringToDouble` function is used, which is precise, so nothing is lost — it's just a heads-up about what happens. You can also retrieve it as a string.
| |
3. **Keys**: Las keys no deberan de tener \" (commila en medio de la key es un caso muy raro) de lo contrario probacara comportamiento
| |
indefinido...
| |
> Si no controla la entrada puede usar: JSONPARSERBYLEO_ENABLE_ESCAPED_COMMILAS_IN_KEYS para activar su uso
| |
| |
### Unescape
| |
1. **Keys**: Las key se desescapan por lo que node["\n"] se accecede correcamnte, todos los escapes
| |
validos para json incluido los emojis.. etc... Apaarte algo a mencionar
| |
es que las funciones de la lib casi todas te daran un indice para trbajar con la key no el string ..
| |
dado que no quiero forzar el unescape.. a todos sabiendo que ramrnte un key tiene escapes...
| |
asi que eso....
| |
| |
2. **Algoritmo en si**: Dado que esto se resuelve on-demand en caso encontrar un escape invalido en el string
| |
la lib no tira error alguno en Parse()... donde si tira un error en cuando se intenta hacer la conversion
| |
en ToString(def), retornando def en caso de error, para surrogates invalidos por ahora a lib
| |
usa el caracter de remplzao no tira error.. si es necesario y en las siguientes versiones se pdoria integrar
| |
un bool o algo asi.
| |
| |
| |
### `double` serialization (`CJsonBuilder`, `CJsonBuilderStr`, `CJsonDomSerializer`)
| |
| |
1. Si hay un valor (v) double el cual multiplicado por 10 (pow) digits
| |
ya no cabe en long , el resultado escrito no guarda relacion con el valor real.
| |
Ejemplo: `-1e25` con 16 decimales produce `-922.3372036854775808`. Con `digits = 8`, esto ocurre a partir de `v ≈ 9×10^10`.
| |
> Alternativa para apalear esto: Use ValSWV o PutRaw y use DoubleToString.
| |
2. Parametro digits fuera de rango safe [0-22]: El serializador no valid si digits esta en dicho rango en cada acceso
| |
por lo que un valor invalido puede desencadenar un array out range....
| |
> Normalmente el numero de digitos se sabe en compilacion.. osea es una constante (tipicamente 8-12)
| |
Si es dinamico o es un valor que ud no controla agrege un cheking antes de setear el numero de digitos (o clamp).
| |
3. Valores infinitos o nan: El serializador al no poder representarlos los escribe como null.
| |
| |
| |
## Que garantizamos
| |
### JSON Parser
| |
1. Validacion estricta de numeros (leading zeros, buena formacino de E\e tambien de valores validos luego del . y e\E).
| |
2. Validacion de true\false\null
| |
3. Validacion de strings\keys cerrados correcamtne
| |
4. Validacion gramatical mediante estados...(osea correcto orden)
| |
5. Safe en casos borde (caracters invalidos dentro del json, validacion de cierre correcto de [,{ etc..)
| |
| |
### JSON Builder - Json Serializer
| |
Aparte de el problema mencionado con `double`, todo lo demas esta garantizado.. buena escritura de numeros, escape de caracters
| |
especiales, conservacion de utf8, manejo de emojis etc..
| |
| |
### JSON ASM
| |
al ser un formato custom creado por TSN-JsonParserByLeo este tiene sus propias reglas.
| |
- [Click aqui para ver el spec completo](./Src/ASM/README.md)
| |
|