/* * Copyright (C) 2016-2017 Redis Labs * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #ifndef __PATH_H__ #define __PATH_H__ #include #include #include "object.h" #include "redismodule.h" #include "rmstrndup.h" /* The type of a path node */ typedef enum { NT_ROOT = 0, NT_KEY, NT_INDEX, } PathNodeType; /* Error codes returned from path lookups */ typedef enum { // OK E_OK, // dict key does not exist E_NOKEY, // array index is out of range E_NOINDEX, // the path predicate does not match the node type E_BADTYPE, } PathError; /* A single lookup node in a lookup path. A lookup path is just a list of nodes */ typedef struct { PathNodeType type; union { int index; const char *key; } value; } PathNode; /** Evaluate a single path node against an object node */ Node *__pathNode_eval(PathNode *pn, Node *n, PathError *err); /** * A search path parsed from JSON or other formats, representing * a lookup path in the object tree */ typedef struct { PathNode *nodes; uint32_t len; uint32_t cap; int hasLeadingDot; } SearchPath; /* Create a new search path. cap can be 0 if you don't know it */ SearchPath NewSearchPath(size_t cap); /* Append an array index selection node to the path */ void SearchPath_AppendIndex(SearchPath *p, int idx); /* Append a string key lookup node to the search path */ void SearchPath_AppendKey(SearchPath *p, const char *key, const size_t len); /* Appends a root node to the search path (makes sense only as the first append) */ void SearchPath_AppendRoot(SearchPath *p); /* Free a search path and all its nodes */ void SearchPath_Free(SearchPath *p); // Node *__pathNode_eval(PathNode *pn, Node *n, PathError *err); /** * Find a node in an object tree based on a parsed path. * An error code is returned, and if a node matches the path, its value * is put into n's pointer. This can be NULL if the lookup matches a NULL node. */ PathError SearchPath_Find(SearchPath *path, Node *root, Node **n); /** * Like SearchPath_Find, but sets p to the parent container of n. In case of E_NOKEY, E_NOINDEX, * and E_INFINDEX returns the path level of the error in errnode. */ PathError SearchPath_FindEx(SearchPath *path, Node *root, Node **n, Node **p, int *errnode); #endif