mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
Moving iterator functions in the header file (#189)
We want the compiler to inline hot functions in the iterators. Let us leave them in the header file. Please.
This commit is contained in:
@@ -51,170 +51,6 @@ ParsedJson::iterator::iterator(iterator &&o):
|
||||
o.depthindex = nullptr;// we take ownership
|
||||
}
|
||||
|
||||
WARN_UNUSED
|
||||
bool ParsedJson::iterator::isOk() const {
|
||||
return location < tape_length;
|
||||
}
|
||||
|
||||
// useful for debuging purposes
|
||||
size_t ParsedJson::iterator::get_tape_location() const {
|
||||
return location;
|
||||
}
|
||||
|
||||
// useful for debuging purposes
|
||||
size_t ParsedJson::iterator::get_tape_length() const {
|
||||
return tape_length;
|
||||
}
|
||||
|
||||
// returns the current depth (start at 1 with 0 reserved for the fictitious root node)
|
||||
size_t ParsedJson::iterator::get_depth() const {
|
||||
return depth;
|
||||
}
|
||||
|
||||
// A scope is a series of nodes at the same depth, typically it is either an object ({) or an array ([).
|
||||
// The root node has type 'r'.
|
||||
uint8_t ParsedJson::iterator::get_scope_type() const {
|
||||
return depthindex[depth].scope_type;
|
||||
}
|
||||
|
||||
bool ParsedJson::iterator::move_forward() {
|
||||
if(location + 1 >= tape_length) {
|
||||
return false; // we are at the end!
|
||||
}
|
||||
|
||||
if ((current_type == '[') || (current_type == '{')){
|
||||
// We are entering a new scope
|
||||
depth++;
|
||||
depthindex[depth].start_of_scope = location;
|
||||
depthindex[depth].scope_type = current_type;
|
||||
} else if ((current_type == ']') || (current_type == '}')) {
|
||||
// Leaving a scope.
|
||||
depth--;
|
||||
if(depth == 0) {
|
||||
// Should not be necessary
|
||||
return false;
|
||||
}
|
||||
} else if ((current_type == 'd') || (current_type == 'l')) {
|
||||
// d and l types use 2 locations on the tape, not just one.
|
||||
location += 1;
|
||||
}
|
||||
|
||||
location += 1;
|
||||
current_val = pj.tape[location];
|
||||
current_type = (current_val >> 56);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParsedJson::iterator::move_to_key(const char * key) {
|
||||
if(down()) {
|
||||
do {
|
||||
assert(is_string());
|
||||
bool rightkey = (strcmp(get_string(),key)==0);// null chars would fool this
|
||||
next();
|
||||
if(rightkey) {
|
||||
return true;
|
||||
}
|
||||
} while(next());
|
||||
assert(up());// not found
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool ParsedJson::iterator::next() {
|
||||
if ((current_type == '[') || (current_type == '{')){
|
||||
// we need to jump
|
||||
size_t npos = ( current_val & JSONVALUEMASK);
|
||||
if(npos >= tape_length) {
|
||||
return false; // shoud never happen unless at the root
|
||||
}
|
||||
uint64_t nextval = pj.tape[npos];
|
||||
uint8_t nexttype = (nextval >> 56);
|
||||
if((nexttype == ']') || (nexttype == '}')) {
|
||||
return false; // we reached the end of the scope
|
||||
}
|
||||
location = npos;
|
||||
current_val = nextval;
|
||||
current_type = nexttype;
|
||||
return true;
|
||||
}
|
||||
size_t increment = (current_type == 'd' || current_type == 'l') ? 2 : 1;
|
||||
if(location + increment >= tape_length) {
|
||||
return false;
|
||||
}
|
||||
uint64_t nextval = pj.tape[location + increment];
|
||||
uint8_t nexttype = (nextval >> 56);
|
||||
if((nexttype == ']') || (nexttype == '}')) {
|
||||
return false; // we reached the end of the scope
|
||||
}
|
||||
location = location + increment;
|
||||
current_val = nextval;
|
||||
current_type = nexttype;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ParsedJson::iterator::prev() {
|
||||
if(location - 1 < depthindex[depth].start_of_scope) {
|
||||
return false;
|
||||
}
|
||||
location -= 1;
|
||||
current_val = pj.tape[location];
|
||||
current_type = (current_val >> 56);
|
||||
if ((current_type == ']') || (current_type == '}')){
|
||||
// we need to jump
|
||||
size_t new_location = ( current_val & JSONVALUEMASK);
|
||||
if(new_location < depthindex[depth].start_of_scope) {
|
||||
return false; // shoud never happen
|
||||
}
|
||||
location = new_location;
|
||||
current_val = pj.tape[location];
|
||||
current_type = (current_val >> 56);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ParsedJson::iterator::up() {
|
||||
if(depth == 1) {
|
||||
return false; // don't allow moving back to root
|
||||
}
|
||||
to_start_scope();
|
||||
// next we just move to the previous value
|
||||
depth--;
|
||||
location -= 1;
|
||||
current_val = pj.tape[location];
|
||||
current_type = (current_val >> 56);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ParsedJson::iterator::down() {
|
||||
if(location + 1 >= tape_length) {
|
||||
return false;
|
||||
}
|
||||
if ((current_type == '[') || (current_type == '{')) {
|
||||
size_t npos = (current_val & JSONVALUEMASK);
|
||||
if(npos == location + 2) {
|
||||
return false; // we have an empty scope
|
||||
}
|
||||
depth++;
|
||||
location = location + 1;
|
||||
depthindex[depth].start_of_scope = location;
|
||||
depthindex[depth].scope_type = current_type;
|
||||
current_val = pj.tape[location];
|
||||
current_type = (current_val >> 56);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ParsedJson::iterator::to_start_scope() {
|
||||
location = depthindex[depth].start_of_scope;
|
||||
current_val = pj.tape[location];
|
||||
current_type = (current_val >> 56);
|
||||
}
|
||||
|
||||
bool ParsedJson::iterator::print(std::ostream &os, bool escape_strings) const {
|
||||
if(!isOk()) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user