#![allow(dead_code)]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::format;
use alloc::vec;
use alloc::vec::Vec;
use alloc::string::String;
use alloc::boxed::Box;
use alloc::string::ToString;
use core::cmp::min;
use core::cmp::Ordering;
use core::fmt;
use core::convert::TryFrom;
use core::str::Chars;
use core::str::Utf8Error;
use std::collections::BTreeMap;
use std::fmt::Write;
pub mod memorypool;
pub mod raw_utils;
pub mod parser;
pub mod termcolors;
pub mod macros;
pub mod stringparser;
pub use crate::raw_utils::EncodingError;
pub use crate::memorypool::*;
pub use crate::raw_utils::*;
pub use crate::termcolors::*;
pub use crate::parser::*;
#[allow(unused_imports)]
pub use crate::stringparser::*;
const WIDTH_OF_JSON_TYPE_MASK: usize = 3;
const JSON_TYPE_MASK: usize = (1 << WIDTH_OF_JSON_TYPE_MASK) - 1;
const KEY_HASH_SIZE: usize = 1;
#[derive(PartialEq, Eq)]
pub enum ValueType {
Null = 0, String = 1, BoolFalse = 2, BoolTrue = 3, Float = 4, Int = 5, Object = 6, Array = 7, }
impl ValueType {
pub fn type_string(&self) -> &'static str {
match self {
ValueType::Null => "null",
ValueType::BoolFalse => "bool-false",
ValueType::BoolTrue => "bool-true",
ValueType::Int => "int",
ValueType::Float => "float/double",
ValueType::String => "string",
ValueType::Object => "object",
ValueType::Array => "array",
}
}
}
pub type KeyHash = u8;
pub type Key<'a> = (KeyHash, &'a [u8]);
pub const fn key_empty() -> Key<'static> {
(0, b"")
}
#[derive(PartialOrd, PartialEq, Clone)]
pub enum DecodedValue<'a> {
Null(),
Bool(bool),
Int(i64),
Float(f32),
Double(f64),
String(&'a [u8]), Object(DecodedObject<'a>),
Array(DecodedArray<'a>),
}
impl<'a> Default for DecodedValue<'a> {
fn default() -> Self {
Self::Null()
}
}
impl<'a> DecodedValue<'a> {
pub fn is_valid_json(&self) -> bool {
match self {
DecodedValue::Null() => true,
DecodedValue::Bool(_) => true,
DecodedValue::Int(_) => true,
DecodedValue::Float(_) => true,
DecodedValue::Double(_) => true,
DecodedValue::String(s) => core::str::from_utf8(s).is_ok(),
DecodedValue::Object(m) => {
for ((_,k),v) in m {
if core::str::from_utf8(k).is_err() || !v.is_valid_json() {
return false;
}
}
true
},
DecodedValue::Array(a) => {
for v in a {
if !v.is_valid_json() {
return false;
}
}
true
},
}
}
}
impl<'a> From<&DecodedValue<'a>> for DecodedValue<'a> {
fn from(v: &DecodedValue<'a>) -> Self {
v.clone()
}
}
impl<'a, T: 'a> From<&'a Option<T>> for DecodedValue<'a>
where
DecodedValue<'a>: From<&'a T>,
{
fn from(v: &'a Option<T>) -> Self {
match v {
Some(v) => v.into(),
None => DecodedValue::Null(),
}
}
}
impl<'a> From<&bool> for DecodedValue<'a> {
fn from(v: &bool) -> Self {
Self::Bool(*v)
}
}
impl<'a> From<&i64> for DecodedValue<'a> {
fn from(v: &i64) -> Self {
Self::Int(*v)
}
}
impl<'a> From<&f32> for DecodedValue<'a> {
fn from(v: &f32) -> Self {
Self::Float(*v)
}
}
impl<'a> From<&f64> for DecodedValue<'a> {
fn from(v: &f64) -> Self {
Self::Double(*v)
}
}
impl<'a, const N: usize> From<&'a [u8; N]> for DecodedValue<'a> {
fn from(v: &'a [u8; N]) -> Self {
Self::String(v)
}
}
impl<'a> From<&'a [u8]> for DecodedValue<'a> {
fn from(v: &'a [u8]) -> Self {
Self::String(v)
}
}
impl<'a> From<&'a mut [u8]> for DecodedValue<'a> {
fn from(v: &'a mut [u8]) -> Self {
Self::String(v)
}
}
impl<'a> From<&'a str> for DecodedValue<'a> {
fn from(v: &'a str) -> Self {
Self::String(v.as_bytes())
}
}
impl<'a> From<&'a mut str> for DecodedValue<'a> {
fn from(v: &'a mut str) -> Self {
Self::String(v.as_bytes())
}
}
impl<'a> From<&'a &'a str> for DecodedValue<'a> {
fn from(v: &'a &'a str) -> Self {
Self::String(v.as_bytes())
}
}
impl<'a> From<&'a String> for DecodedValue<'a> {
fn from(v: &'a String) -> Self {
Self::String(v.as_bytes())
}
}
impl<'a> From<&'a &'a String> for DecodedValue<'a> {
fn from(v: &'a &'a String) -> Self {
Self::String(v.as_bytes())
}
}
impl<'a> From<&'a BytecodeVec> for DecodedValue<'a> {
fn from(v: &'a BytecodeVec) -> Self {
Self::String(v.get())
}
}
impl<'a> From<&'_ BytecodeRef<'a>> for DecodedValue<'a> {
fn from(v: &'_ BytecodeRef<'a>) -> Self {
Self::String(v.get())
}
}
impl<'a, T: 'a, const N: usize> From<&'a &'a [T; N]> for DecodedValue<'a>
where
DecodedValue<'a>: From<&'a T>,
T: Clone,
{
fn from(v: &'a &'a [T; N]) -> Self {
let mut retval = DecodedArray::new();
for item in *v {
retval.push(item.into());
}
Self::Array(retval)
}
}
impl<'a, T> From<&'a &'a [T]> for DecodedValue<'a>
where
DecodedValue<'a>: From<&'a T>,
{
fn from(v: &'a &'a [T]) -> Self {
Self::Array(v.iter().map(|x| x.into()).collect())
}
}
impl<'a, T> From<&'a Vec<T>> for DecodedValue<'a>
where
DecodedValue<'a>: From<&'a T>,
{
fn from(v: &'a Vec<T>) -> Self {
Self::Array(v.iter().map(|x| x.into()).collect())
}
}
pub type DecodedObject<'a> = BTreeMap<Key<'a>, DecodedValue<'a>>;
pub type DecodedArray<'a> = Vec<DecodedValue<'a>>;
pub trait CloneInMemoryScope<'c, T> {
fn clone_in(&self, scope: &mut MemoryScope<'c>) -> T;
}
impl<'a, 'b, 'c> CloneInMemoryScope<'c, DecodedObject<'b>> for DecodedObject<'a> where 'c: 'b {
fn clone_in(&self, scope: &mut MemoryScope<'c>) -> DecodedObject<'b> {
let mut retval = DecodedObject::new();
for ((hash, k),v) in self {
retval.insert((*hash, scope.copy_u8(k)), v.clone_in(scope));
}
retval
}
}
impl<'a, 'b, 'c> CloneInMemoryScope<'c, DecodedArray<'b>> for DecodedArray<'a> where 'c: 'b {
fn clone_in(&self, scope: &mut MemoryScope<'c>) -> DecodedArray<'b> {
let mut retval = DecodedArray::new();
for v in self {
retval.push(v.clone_in(scope));
}
retval
}
}
impl<'a> fmt::Debug for DecodedValue<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
DecodedValue::Null() => write!(f, "null"),
DecodedValue::Bool(false) => write!(f, "false"),
DecodedValue::Bool(true) => write!(f, "true"),
DecodedValue::Int(i) => write!(f, "{}", i),
DecodedValue::Float(d) => write!(f, "{}f", d),
DecodedValue::Double(d) => write!(f, "{}", d),
DecodedValue::String(s) => {
if let Ok(s) = core::str::from_utf8(s) {
write!(f, "{}", s)
} else {
write!(f, "{:?}", s)
}
}
DecodedValue::Object(obj) => {
write!(f, "{{")?;
let mut first = true;
for ((_,k),v) in obj {
if !first {
write!(f, ", ")?;
}
if let Ok(key) = core::str::from_utf8(k) {
write!(f, "{}: {:?}", key, v)?;
} else {
write!(f, "{:?}: {:?}", k, v)?;
}
first = false;
}
write!(f, "}}")
},
DecodedValue::Array(arr) => write!(f, "{:?}", arr),
}
}
}
fn json_escaped_write(f: &mut core::fmt::Formatter<'_>, src: &str) -> Result<(),core::fmt::Error> {
let mut utf16_buf = [0u16; 2];
for c in src.chars() {
match c {
'\x08' => write!(f, "\\b")?,
'\x0c' => write!(f, "\\f")?,
'\n' => write!(f, "\\n")?,
'\r' => write!(f, "\\r")?,
'\t' => write!(f, "\\t")?,
'"' => write!(f, "\\\"")?,
'\\' => write!(f, "\\\\")?,
' ' => write!(f, " ")?,
c if (c as u32) < 0x20 => {
let encoded = c.encode_utf16(&mut utf16_buf);
for utf16 in encoded {
write!(f, "\\u{:04X}", utf16)?;
}
},
c => write!(f, "{}", c)?,
}
}
Ok(())
}
impl<'a> core::fmt::Display for DecodedValue<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
DecodedValue::Null() => write!(f, "null"),
DecodedValue::Bool(false) => write!(f, "false"),
DecodedValue::Bool(true) => write!(f, "true"),
DecodedValue::Int(i) => write!(f, "{}", i),
DecodedValue::Float(d) => write!(f, "{}", d),
DecodedValue::Double(d) => write!(f, "{}", d),
DecodedValue::String(s) => {
let s = core::str::from_utf8(s);
if let Ok(s) = s {
write!(f, "\"")?;
json_escaped_write(f, s)?;
write!(f, "\"")
} else {
write!(f, "null")
}
}
DecodedValue::Object(obj) => {
write!(f, "{{")?;
let mut first = true;
for ((_,k),v) in obj {
let key = core::str::from_utf8(k);
if let Ok(key) = key {
if !first {
write!(f, ",")?;
}
write!(f, "\"")?;
json_escaped_write(f, key)?;
write!(f, "\":{}", v)?;
first = false;
} else {
write!(f, "null")?;
}
}
write!(f, "}}")
},
DecodedValue::Array(arr) => {
write!(f, "[")?;
let mut first = true;
for v in arr {
if !first {
write!(f, ",")?;
}
write!(f, "{}", v)?;
first = false;
}
write!(f, "]")
},
}
}
}
fn key_stable_hash(s: &[u8]) -> KeyHash {
let mut state = 0;
for (i,b) in s.iter().enumerate() {
state ^= b.wrapping_add(i as u8);
}
state
}
impl<'a> DecodedValue<'a> {
pub const fn type_string(&self) -> &'static str {
match self {
DecodedValue::Null() => "null",
DecodedValue::Bool(_) => "bool",
DecodedValue::Int(_) => "int",
DecodedValue::Float(_) => "float",
DecodedValue::Double(_) => "double",
DecodedValue::String(_) => "string",
DecodedValue::Object(_) => "object",
DecodedValue::Array(_) => "array",
}
}
pub fn size_of_binary(&self, compact: bool) -> usize {
let mut length_collector = RawWriterLength::new();
self.print_binary(&mut length_collector, compact).unwrap_infallible();
length_collector.length()
}
pub fn print_binary<E, Out: RawOutput<E>>(&self, writer: &mut Out, compact: bool) -> Result<(),E> {
match self {
DecodedValue::Null() => {
writer.write_u8(ValueType::Null as u8)?;
Ok(())
}
DecodedValue::Bool(b) => {
if *b {
writer.write_u8(ValueType::BoolTrue as u8)?;
} else {
writer.write_u8(ValueType::BoolFalse as u8)?;
}
Ok(())
}
DecodedValue::Int(i) => {
if *i == 0 {
writer.write_u8(ValueType::Int as u8)?;
return Ok(());
}
let size = size_of_i64(*i);
debug_assert!(size <= 8);
writer.write_u8((size << WIDTH_OF_JSON_TYPE_MASK) as u8 | ValueType::Int as u8)?;
writer.write_i64(*i, size)?;
Ok(())
}
DecodedValue::Float(f) => {
writer.write_u8((4 << WIDTH_OF_JSON_TYPE_MASK) as u8 | ValueType::Float as u8)?;
writer.write_f32(*f)?;
Ok(())
}
DecodedValue::Double(d) => {
writer.write_u8((8 << WIDTH_OF_JSON_TYPE_MASK) as u8 | ValueType::Float as u8)?;
writer.write_f64(*d)?;
Ok(())
}
DecodedValue::String(s) => {
writer.write_var_u64((s.len() << WIDTH_OF_JSON_TYPE_MASK) as u64 | ValueType::String as u64)?;
writer.write_bytes(s)?;
Ok(())
}
DecodedValue::Array(arr) => {
if arr.is_empty() {
writer.write_u8(ValueType::Array as u8)?;
return Ok(());
}
write_with_header(writer, |writer,total| {
writer.write_var_u64((total as u64) << WIDTH_OF_JSON_TYPE_MASK | ValueType::Array as u64)
}, |writer| {
writer.write_var_u64((arr.len() as u64) << 1)?;
for e in arr {
e.print_binary(writer, compact)?;
}
Ok(())
})
}
DecodedValue::Object(obj) => {
if obj.is_empty() {
writer.write_u8(ValueType::Object as u8)?;
return Ok(());
}
let count = obj.len();
let local_compact = compact || count <= 4;
if !cfg!(feature = "mini") && !local_compact {
write_with_header(writer, |writer,total| {
writer.write_var_u64((total as u64) << WIDTH_OF_JSON_TYPE_MASK | ValueType::Object as u64)
}, |writer| {
let mut positions : Vec<(usize,u8)> = Vec::with_capacity(count); let mut jumps : Vec<(usize,usize)> = Vec::new(); for (i,((hash,key), value)) in obj.iter().enumerate() {
for j in 0..i.trailing_zeros() {
let to_index = i + (2 << j);
if to_index >= count {
break;
}
if obj.iter().nth(to_index-1).unwrap().0.0 == obj.iter().nth(to_index).unwrap().0.0 {
continue;
}
jumps.push((writer.pos(), to_index));
}
positions.push((writer.pos(),*hash));
let key_size = KEY_HASH_SIZE + key.len();
writer.write_var_u64((key_size as u64) << 1)?;
writer.write_u8(*hash)?;
writer.write_bytes(key)?;
value.print_binary(writer, compact)?;
}
for (from_pos, to_index) in jumps.iter().rev() {
let current = writer.pos();
let to_pos = positions[*to_index].0;
let jump = to_pos - from_pos;
writer.write_var_u64(((jump as u64) << 1) | 1)?;
writer.write_u8(positions[*to_index].1)?;
let extra = writer.pos() - current;
writer.swap_range(*from_pos, current)?;
for (pos,_) in positions.iter_mut() {
if *pos >= *from_pos {
*pos += extra;
}
}
}
Ok(())
})?;
return Ok(());
}
write_with_header(writer, |writer,total| {
writer.write_var_u64((total as u64) << WIDTH_OF_JSON_TYPE_MASK | ValueType::Object as u64)
}, |writer| {
for ((hash,key), value) in obj {
let key_size = KEY_HASH_SIZE + key.len();
writer.write_var_u64((key_size as u64) << 1)?;
writer.write_u8(*hash)?;
writer.write_bytes(key)?;
value.print_binary(writer, compact)?;
}
Ok(())
})?;
Ok(())
}
}
}
pub fn to_vec(&self, compact: bool) -> ValueVec {
if cfg!(feature = "mini") {
let mut writer = RawString::new();
self.print_binary(&mut writer, compact).expect("expry: problem during actual write");
ValueVec(writer.data)
} else {
let len = self.size_of_binary(compact);
let mut retval : Vec<u8> = vec![0u8; len];
let mut writer = RawWriter::with(&mut retval[..]);
self.print_binary(&mut writer, compact).expect("expry: calculated size differs from actual size");
debug_assert!(writer.left() == 0);
ValueVec(retval)
}
}
pub fn to_scope<'c>(&self, scope: &mut MemoryScope<'c>, compact: bool) -> ValueRef<'c> {
if cfg!(feature = "mini") {
ValueRef(scope.copy_u8(self.to_vec(compact).get()))
} else {
let len = self.size_of_binary(compact);
let retval = scope.alloc(len);
let mut writer = RawWriter::with(retval);
self.print_binary(&mut writer, compact).expect("expry: calculated size differs from actual size");
debug_assert!(writer.left() == 0);
ValueRef(retval)
}
}
pub fn print_json(&self, writer: &mut Vec<u8>) -> Result<(),Utf8Error> {
match self {
DecodedValue::Null() => {
writer.extend_from_slice(b"null");
}
DecodedValue::Bool(b) => {
if *b {
writer.extend_from_slice(b"true");
} else {
writer.extend_from_slice(b"false");
}
}
DecodedValue::Int(i) => {
writer.extend_from_slice(i.to_string().as_bytes());
}
DecodedValue::Float(f) => {
writer.extend_from_slice(format!("{:.99}", f).as_bytes());
}
DecodedValue::Double(d) => {
writer.extend_from_slice(format!("{:.99}", d).as_bytes());
}
DecodedValue::String(s) => {
writer.extend_from_slice(b"\"");
writer.extend_from_slice(&json_escape(core::str::from_utf8(s)?));
writer.extend_from_slice(b"\"");
}
DecodedValue::Array(arr) => {
writer.extend_from_slice(b"[");
let mut comma = false;
for e in arr {
if comma {
writer.extend_from_slice(b",");
}
e.print_json(writer)?;
comma = true;
}
writer.extend_from_slice(b"]");
}
DecodedValue::Object(obj) => {
writer.extend_from_slice(b"{");
let mut comma = false;
for ((_,k),v) in obj {
if comma {
writer.extend_from_slice(b",");
}
writer.extend_from_slice(b"\"");
writer.extend_from_slice(&json_escape(core::str::from_utf8(k)?));
writer.extend_from_slice(b"\":");
v.print_json(writer)?;
comma = true;
}
writer.extend_from_slice(b"}");
}
};
Ok(())
}
fn lookup_field(&self, key: Key) -> Result<Option<DecodedValue<'a>>,EncodingError> {
if let DecodedValue::Object(values) = self {
Ok(values.get(&key).cloned())
} else {
Err(EncodingError{line_nr: line!()}) }
}
}
impl<'a, 'b, 'c> CloneInMemoryScope<'c, DecodedValue<'b>> for DecodedValue<'a> where 'c: 'b {
fn clone_in(&self, scope: &mut MemoryScope<'c>) -> DecodedValue<'b> {
match self {
DecodedValue::Null() => DecodedValue::Null(),
DecodedValue::Bool(v) => DecodedValue::Bool(*v),
DecodedValue::Int(v) => DecodedValue::Int(*v),
DecodedValue::Float(v) => DecodedValue::Float(*v),
DecodedValue::Double(v) => DecodedValue::Double(*v),
DecodedValue::String(s) => DecodedValue::String(scope.copy_u8(s)),
DecodedValue::Object(values) => {
let mut retval = DecodedObject::new();
for ((hash, k),v) in values {
retval.insert((*hash, scope.copy_u8(k)), v.clone_in(scope));
}
DecodedValue::Object(retval)
},
DecodedValue::Array(values) => {
let mut retval = DecodedArray::new();
for v in values {
retval.push(v.clone_in(scope));
}
DecodedValue::Array(retval)
}
}
}
}
fn write_field(key: &[u8], value: &[u8], writer: &mut RawWriter) -> Result<(),EncodingError> {
let hash = key_stable_hash(key);
write_field_key((hash, key), value, writer)
}
fn write_field_key(key: Key, value: &[u8], writer: &mut RawWriter) -> Result<(),EncodingError> {
let key_size = KEY_HASH_SIZE + key.1.len();
writer.write_var_u64((key_size as u64) << 1)?;
writer.write_u8(key.0)?;
writer.write_bytes(key.1)?;
writer.write_bytes(value)?;
Ok(())
}
pub fn expry_object_with_single_field(key: &[u8], value: &[u8]) -> Result<Vec<u8>,EncodingError> {
let key_size = key.len() + KEY_HASH_SIZE;
let entry = size_of_var_u64((key_size as u64) << 1) + key_size + value.len();
let object_size = size_of_var_u64((entry << WIDTH_OF_JSON_TYPE_MASK) as u64) + entry;
let mut retval : Vec<u8> = vec![0u8; object_size];
let mut writer = RawWriter::with(&mut retval[..]);
write_with_header(&mut writer, |writer,total| {
writer.write_var_u64((total as u64) << WIDTH_OF_JSON_TYPE_MASK | ValueType::Object as u64)
}, |writer| {
write_field(key, value, writer)
})?;
assert_eq!(writer.left(), 0);
Ok(retval)
}
pub fn expry_object_raw<'c>(scope: &mut MemoryScope<'c>, slice: &[(Key<'_>, &[u8])]) -> Result<&'c [u8],EncodingError> {
let mut content_size = 0;
for (key,value) in slice {
let key_size = key.1.len() + KEY_HASH_SIZE;
let entry = size_of_var_u64((key_size as u64) << 1) + key_size + value.len();
content_size += entry;
}
let object_size = size_of_var_u64((content_size << WIDTH_OF_JSON_TYPE_MASK) as u64) + content_size;
let retval = scope.alloc(object_size);
let mut writer = RawWriter::with(retval);
write_with_header(&mut writer, |writer,total| {
writer.write_var_u64((total as u64) << WIDTH_OF_JSON_TYPE_MASK | ValueType::Object as u64)
}, |writer| {
for (key,value) in slice {
write_field_key(*key, value, writer)?;
}
Ok(())
})?;
assert_eq!(writer.left(), 0);
Ok(retval)
}
fn json_escape(src: &str) -> Vec<u8> {
let mut escaped : Vec<u8> = Vec::with_capacity(src.len());
for c in src.chars() {
match c {
'\x08' => escaped.extend_from_slice(b"\\b"),
'\x0c' => escaped.extend_from_slice(b"\\f"),
'\n' => escaped.extend_from_slice(b"\\n"),
'\r' => escaped.extend_from_slice(b"\\r"),
'\t' => escaped.extend_from_slice(b"\\t"),
'"' => escaped.extend_from_slice(b"\\\""),
'\\' => escaped.extend_from_slice(b"\\\\"),
' ' => escaped.extend_from_slice(b" "),
c if (c as u32) < 0x20 => {
let mut utf16_buf = [0u16; 2];
let encoded = c.encode_utf16(&mut utf16_buf);
for utf16 in encoded {
let s = format!("\\u{:04X}", utf16);
escaped.extend_from_slice(s.as_bytes());
}
},
c => {
let mut utf8_buf = [0u8; 4];
escaped.extend_from_slice(c.encode_utf8(&mut utf8_buf).as_bytes());
},
}
}
escaped
}
pub fn key_str(key: &str) -> Key<'_> {
let hash = key_stable_hash(key.as_bytes());
(hash, key.as_bytes())
}
pub fn key_u8(key: &[u8]) -> Key<'_> {
let hash = key_stable_hash(key);
(hash, key)
}
impl TryFrom<usize> for ValueType {
type Error = EncodingError;
fn try_from(v: usize) -> Result<Self, Self::Error> {
match v {
x if x == ValueType::Null as usize => Ok(ValueType::Null),
x if x == ValueType::String as usize => Ok(ValueType::String),
x if x == ValueType::BoolFalse as usize => Ok(ValueType::BoolFalse),
x if x == ValueType::BoolTrue as usize => Ok(ValueType::BoolTrue),
x if x == ValueType::Float as usize => Ok(ValueType::Float),
x if x == ValueType::Int as usize => Ok(ValueType::Int),
x if x == ValueType::Object as usize => Ok(ValueType::Object),
x if x == ValueType::Array as usize => Ok(ValueType::Array),
_ => Err(EncodingError { line_nr: line!() }),
}
}
}
impl<'a> DecodedValue<'a> {
pub fn decoded_type_of(type_and_length: u64) -> Result<ValueType, EncodingError> {
((type_and_length as usize) & JSON_TYPE_MASK).try_into()
}
pub const fn type_of_binary(type_and_length: u64) -> u8 {
((type_and_length as usize) & JSON_TYPE_MASK) as u8
}
pub const fn length_of_binary(type_and_length: u64) -> usize {
(type_and_length >> WIDTH_OF_JSON_TYPE_MASK) as usize
}
pub fn decoded_type_and_length(type_and_length: u64) -> Result<(ValueType, usize), EncodingError> {
Ok((Self::decoded_type_of(type_and_length)?, Self::length_of_binary(type_and_length)))
}
pub fn parse(reader: &mut RawReader<'a>) -> Result<DecodedValue<'a>, EncodingError> {
let type_and_length = reader.read_var_u64()?;
let (t, len) = Self::decoded_type_and_length(type_and_length)?;
match t {
ValueType::Null => {
if len == 0 {
Ok(DecodedValue::Null())
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::String => {
let value = reader.read_bytes(len)?;
Ok(DecodedValue::String(value))
},
ValueType::BoolFalse => {
if len == 0 {
Ok(DecodedValue::Bool(false))
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::BoolTrue => {
if len == 0 {
Ok(DecodedValue::Bool(true))
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::Float => {
if len == 4 {
let value = reader.read_f32()?;
Ok(DecodedValue::Float(value))
} else if len == 8 {
let value = reader.read_f64()?;
Ok(DecodedValue::Double(value))
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::Int => {
let v = reader.read_i64(len)?;
Ok(DecodedValue::Int(v))
}
ValueType::Array => {
if len == 0 {
return Ok(DecodedValue::Array(vec![]));
}
let mut subreader = RawReader::with(reader.read_bytes(len)?);
let mut count = subreader.read_var_u64()?;
count >>= 1;
let mut retval : Vec<DecodedValue> = Vec::with_capacity(min(16384, count as usize)); for _ in 0 .. count {
let v = DecodedValue::parse(&mut subreader)?;
retval.push(v);
}
Ok(DecodedValue::Array(retval))
},
ValueType::Object => {
if len == 0 {
return Ok(DecodedValue::Object(DecodedObject::new()));
}
let mut last : (KeyHash, &[u8]) = (0, b"");
let mut retval = DecodedObject::new();
let mut subreader = RawReader::with(reader.read_bytes(len)?);
while !subreader.is_empty() {
let mut key_length= subreader.read_var_u64()?;
if key_length == 0 {
return Err(EncodingError{ line_nr: line!() });
}
if key_length & 0x1 != 0 {
subreader.read_u8()?;
continue;
}
key_length = (key_length >> 1) - 1; if key_length as usize > subreader.len() {
return Err(EncodingError{ line_nr: line!() });
}
let hash = subreader.read_u8()?;
let key = (hash, subreader.read_bytes(key_length as usize)?);
let v = DecodedValue::parse(&mut subreader)?;
retval.insert(key, v);
if key < last {
return Err(EncodingError{line_nr: line!(), });
}
last = key;
}
debug_assert!(subreader.is_empty());
Ok(DecodedValue::Object(retval))
},
}
}
}
#[derive(PartialEq, Copy, Clone)]
pub enum LazyDecodedValue<'a> {
Null(),
Bool(bool),
Int(i64),
Float(f32),
Double(f64),
String(&'a [u8]), Object(LazyDecodedObject<'a>),
Array(LazyDecodedArray<'a>),
}
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct LazyDecodedObject<'a> {
reader: RawReader<'a>,
}
impl<'a> LazyDecodedObject<'a> {
fn _read_value(reader: &mut RawReader<'a>) -> Result<&'a [u8],EncodingError> {
let mut reader_type = *reader;
let type_and_length = reader_type.read_var_u64()?;
let len = DecodedValue::length_of_binary(type_and_length);
reader_type.skip(len)?;
let v = reader.read_bytes(reader.len() - reader_type.len())?;
Ok(v)
}
fn _read_key(reader: &mut RawReader<'a>) -> Result<Key<'a>,EncodingError> {
let mut key_length = reader.read_var_u64()?;
if key_length == 0 || key_length & 0x1 != 0 {
return Err(EncodingError{ line_nr: line!() });
}
key_length = (key_length >> 1) - 1; let hash = reader.read_u8()?;
let key = reader.read_bytes(key_length as usize)?;
Ok((hash, key))
}
fn _read(reader: &mut RawReader<'a>) -> Result<(Key<'a>, &'a [u8]),EncodingError> {
Ok((Self::_read_key(reader)?, Self::_read_value(reader)?))
}
pub fn lookup_binary<'b>(&self, key: (KeyHash, &'b [u8])) -> Result<Option<&'a [u8]>,EncodingError> where 'a: 'b {
let mut value_reader = self.reader;
match evaluate_seek(key.0, key.1, &mut value_reader) {
Ok(_) => {},
Err(EvalError::FieldNotFound(_)) => return Ok(None),
Err(_) => return Err(EncodingError{ line_nr: line!(), }),
}
let binary_value = Self::_read(&mut value_reader)?.1;
Ok(Some(binary_value))
}
pub fn lookup_value<'b>(&self, key: (KeyHash, &'b [u8])) -> Result<Option<LazyDecodedValue<'a>>,EncodingError> where 'a: 'b {
let binary_value = self.lookup_binary(key)?;
if let Some(binary_value) = binary_value {
Ok(Some(LazyDecodedValue::parse(&mut RawReader::with(binary_value))?))
} else {
Ok(None)
}
}
pub fn get(&mut self) -> Result<(Key<'a>,LazyDecodedValue),EncodingError> {
let (key, value) = LazyDecodedObject::<'a>::_read(&mut self.reader)?;
Ok((key, LazyDecodedValue::parse(&mut RawReader::with(value))?))
}
pub fn is_empty(&mut self) -> Result<bool,EncodingError> {
while self.reader.len() > 0 && self.reader.clone().read_var_u64()? & 0x1 != 0 {
self.reader.read_var_u64()?;
self.reader.read_u8()?;
}
Ok(self.reader.is_empty())
}
pub fn new(reader: RawReader<'a>) -> Self {
Self {
reader,
}
}
}
#[derive(PartialEq, Eq, Copy, Clone)]
pub struct LazyDecodedArray<'a> {
reader: RawReader<'a>,
count: u64,
}
impl<'a> LazyDecodedArray<'a> {
pub fn get(&mut self) -> Result<LazyDecodedValue,EncodingError> {
if self.count == 0 {
return Err(EncodingError{ line_nr: line!() });
}
debug_assert!(!self.reader.is_empty());
self.count -= 1;
LazyDecodedValue::parse(&mut self.reader)
}
pub fn get_raw(&mut self) -> Result<ValueRef<'a>,EncodingError> {
self.count -= 1;
let type_and_length = self.reader.clone().read_var_u64()?;
let len = DecodedValue::length_of_binary(type_and_length);
Ok(ValueRef(self.reader.read_bytes(len + size_of_var_u64(type_and_length))?))
}
pub fn remaining(&self) -> u64 {
self.count
}
pub fn is_empty(&self) -> bool {
self.count == 0
}
}
impl<'a> LazyDecodedValue<'a> {
pub fn type_string(&self) -> &'static str {
match self {
LazyDecodedValue::Null() => "null",
LazyDecodedValue::Bool(_) => "bool",
LazyDecodedValue::Int(_) => "int",
LazyDecodedValue::Float(_) => "float",
LazyDecodedValue::Double(_) => "double",
LazyDecodedValue::String(_) => "string",
LazyDecodedValue::Object(_) => "object",
LazyDecodedValue::Array(_) => "array",
}
}
pub fn parse(reader: &mut RawReader<'a>) -> Result<LazyDecodedValue<'a>, EncodingError> {
let type_and_length = reader.read_var_u64()?;
let (t, len) = DecodedValue::decoded_type_and_length(type_and_length)?;
match t {
ValueType::Null => {
if len == 0 {
Ok(LazyDecodedValue::Null())
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::String => {
let value = reader.read_bytes(len)?;
Ok(LazyDecodedValue::String(value))
},
ValueType::BoolFalse => {
if len == 0 {
Ok(LazyDecodedValue::Bool(false))
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::BoolTrue => {
if len == 0 {
Ok(LazyDecodedValue::Bool(true))
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::Float => {
if len == 4 {
let value = reader.read_f32()?;
Ok(LazyDecodedValue::Float(value))
} else if len == 8 {
let value = reader.read_f64()?;
Ok(LazyDecodedValue::Double(value))
} else {
Err(EncodingError { line_nr: line!() })
}
}
ValueType::Int => {
let v = reader.read_i64(len)?;
Ok(LazyDecodedValue::Int(v))
}
ValueType::Array => {
if len == 0 {
return Ok(LazyDecodedValue::Array(LazyDecodedArray { count: 0, reader: RawReader::with(b""), }));
}
let mut subreader = RawReader::with(reader.read_bytes(len)?);
let mut count = subreader.read_var_u64()?;
count >>= 1;
let retval = LazyDecodedArray {
count,
reader: subreader,
};
Ok(LazyDecodedValue::Array(retval))
},
ValueType::Object => {
if len == 0 {
return Ok(LazyDecodedValue::Object(LazyDecodedObject { reader: RawReader::with(b""), }));
}
Ok(LazyDecodedValue::Object(LazyDecodedObject::new(RawReader::with(reader.read_bytes(len)?))))
},
}
}
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct ValueRef<'a>(pub &'a [u8]);
impl<'a> ValueRef<'a> {
fn lookup_field(&self, key: Key) -> Result<Option<DecodedValue<'a>>,EncodingError> {
if self.get().is_empty() {
return Ok(None);
}
let mut value_reader = RawReader::with(self.get());
if DecodedValue::type_of_binary(value_reader.read_var_u64()?) != ValueType::Object as u8 {
return Err(EncodingError{line_nr: line!()});
}
match evaluate_seek(key.0, key.1, &mut value_reader) {
Ok(_) => {},
Err(EvalError::FieldNotFound(_)) => return Ok(None),
Err(_) => return Err(EncodingError{line_nr: line!()}),
}
let key_length = value_reader.read_var_u64()?;
if key_length == 0 || (key_length & 0x1) != 0 {
return Err(EncodingError{line_nr: line!()});
}
let _key_name = &value_reader.read_bytes(key_length as usize >> 1)?[1..];
Ok(Some(DecodedValue::parse(&mut value_reader)?))
}
pub fn get(&self) -> &'a [u8] {
self.0
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn new() -> Self {
Self(b"")
}
}
impl<'a> Default for ValueRef<'a> {
fn default() -> Self {
Self::new()
}
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct ValueVec(pub Vec<u8>);
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct BytecodeRef<'a>(pub &'a [u8]);
impl<'a> BytecodeRef<'a> {
pub fn get(&self) -> &'a [u8] {
self.0
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn new() -> Self {
Self(b"")
}
}
impl<'a> Default for BytecodeRef<'a> {
fn default() -> Self {
Self::new()
}
}
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct BytecodeVec(pub Vec<u8>);
impl BytecodeVec {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn to_ref(&self) -> BytecodeRef {
BytecodeRef(&self.0)
}
pub fn get(&self) -> &[u8] {
&self.0
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl ValueVec {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn to_ref(&self) -> ValueRef {
ValueRef(&self.0)
}
pub fn get(&self) -> &[u8] {
&self.0
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Into<ValueVec> for Vec<u8> {
fn into(self) -> ValueVec {
ValueVec(self)
}
}
impl Into<BytecodeVec> for Vec<u8> {
fn into(self) -> BytecodeVec {
BytecodeVec(self)
}
}
impl Into<Vec<u8>> for ValueVec {
fn into(self) -> Vec<u8> {
self.0
}
}
impl Into<Vec<u8>> for BytecodeVec {
fn into(self) -> Vec<u8> {
self.0
}
}
fn peek_key_and_entry<'a>(reader: &'_ mut RawReader<'a>) -> Result<(KeyHash,&'a [u8],usize,usize),EncodingError> {
let mut peeker = *reader;
while !peeker.is_empty() {
let mut key_length = peeker.read_var_u64()?;
if key_length == 0 {
return Err(EncodingError{ line_nr: line!() });
}
if (key_length & 0x1) != 0 {
let _hash_of_next_entry = peeker.read_u8()?; *reader = peeker;
continue;
}
key_length = (key_length >> 1) - KEY_HASH_SIZE as u64;
let hash = peeker.read_u8()?;
let key = peeker.read_bytes(key_length as usize)?;
let type_and_length = peeker.read_var_u64()?;
peeker.skip(DecodedValue::length_of_binary(type_and_length))?;
return Ok((hash, key, reader.len() - peeker.len(), type_and_length as usize));
}
Ok((0, b"", 0, 0))
}
pub fn merge_objects<'b, 'c>(lhs: ValueRef, rhs: ValueRef, allocator: &mut MemoryScope<'c>) -> Result<ValueRef<'b>, EncodingError> where 'c: 'b {
let mut lhs_reader = RawReader::with(lhs.get());
let mut rhs_reader = RawReader::with(rhs.get());
let lhs_length_and_type = lhs_reader.read_var_u64()?;
if DecodedValue::type_of_binary(lhs_length_and_type) != ValueType::Object as u8 {
return Err(EncodingError{ line_nr: line!() });
}
if DecodedValue::length_of_binary(lhs_length_and_type) != lhs_reader.len() {
return Err(EncodingError{ line_nr: line!() });
}
let rhs_length_and_type = rhs_reader.read_var_u64()?;
if DecodedValue::type_of_binary(rhs_length_and_type) != ValueType::Object as u8 {
return Err(EncodingError{ line_nr: line!() });
}
if DecodedValue::length_of_binary(rhs_length_and_type) != rhs_reader.len() {
return Err(EncodingError{ line_nr: line!() });
}
let mut chunks : ScopedArrayBuilder<'_, 'c, &[u8]> = ScopedArrayBuilder::new(allocator);
chunks.push(b""); let mut total : usize = 0;
let mut lhs_current : (KeyHash,&[u8],usize,usize) = peek_key_and_entry(&mut lhs_reader)?;
let mut rhs_current : (KeyHash,&[u8],usize,usize) = peek_key_and_entry(&mut rhs_reader)?;
while !lhs_current.1.is_empty() || !rhs_current.1.is_empty() {
let (lhs_hash, lhs_key, lhs_entry_length, lhs_value_length_and_type) = lhs_current;
let (rhs_hash, rhs_key, rhs_entry_length, _) = rhs_current;
let mut entry : &[u8];
if lhs_entry_length > 0 && (lhs_hash, lhs_key) <= (rhs_hash, rhs_key) || rhs_entry_length == 0 {
entry = lhs_reader.read_bytes(lhs_entry_length)?;
if lhs_value_length_and_type == ValueType::Float as usize { entry = b"";
}
if (lhs_hash, lhs_key) == (rhs_hash, rhs_key) {
rhs_reader.skip(rhs_entry_length)?;
rhs_current = peek_key_and_entry(&mut rhs_reader)?;
}
lhs_current = peek_key_and_entry(&mut lhs_reader)?;
} else {
entry = rhs_reader.read_bytes(rhs_entry_length)?;
rhs_current = peek_key_and_entry(&mut rhs_reader)?;
}
if !entry.is_empty() {
chunks.push(entry);
total += entry.len();
}
}
let retval = chunks.build();
retval[0] = to_var_length(allocator, total << WIDTH_OF_JSON_TYPE_MASK | ValueType::Object as usize);
let retval = allocator.concat_u8(retval);
Ok(ValueRef(retval))
}
#[derive(PartialEq, Copy, Clone, Debug)]
enum JSONToken<'a> {
End(),
Bool(bool),
String(&'a [u8]),
Float(f32),
Double(f64),
Int(i64),
Comma(),
ArrayOpen(),
ArrayClose(),
ObjectOpen(),
Colon(),
ObjectClose(),
NullObject(),
Comparison(ExpryComparison),
Arithmetic(Arithmetic),
Logical(Logical),
Bitwise(Bitwise),
Open(),
Close(),
As(),
Not(),
Conditional(),
NullOperator(),
TryOperator(),
Concat(),
Dot(),
Spread(),
Field(&'a str),
FunctionCall(&'a str),
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct LexerError {
line_nr: u32,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum CompileErrorDescription<'a> {
NoToken(),
Lexer(LexerError),
Parser(&'a str),
Optimizer(EvalError<'a>),
}
#[derive(Clone, Debug)]
pub struct CompileError<'a> {
pub error: CompileErrorDescription<'a>,
pub start: usize, pub end: usize, pub extra: Option<(usize, usize)>,
}
impl<'a> CompileError<'a> {
pub fn error_start(&self) -> usize {
self.start
}
pub fn error_end(&self) -> usize {
self.end
}
pub fn error(&self) -> CompileErrorDescription<'a> {
self.