#if !defined(FOSSIL_JSON_DETAIL_H_INCLUDED)
#define FOSSIL_JSON_DETAIL_H_INCLUDED
#include "cson_amalgamation.h"
/*
** Impl details for the JSON API which need to be shared
** across multiple C files.
*/
/*
** The "official" list of Fossil/JSON error codes. Their values might
** very well change during initial development but after their first
** public release they must stay stable.
**
** Values must be in the range 1000..9999 for error codes and 1..999
** for warning codes.
**
** Numbers evenly dividable by 100 are "categories", and error codes
** for a given category have their high bits set to the category
** value.
**
*/
enum FossilJsonCodes {
FSL_JSON_W_START = 0,
FSL_JSON_W_UNKNOWN = FSL_JSON_W_START + 1,
FSL_JSON_W_ROW_TO_JSON_FAILED = FSL_JSON_W_START + 2,
FSL_JSON_W_COL_TO_JSON_FAILED = FSL_JSON_W_START + 3,
FSL_JSON_W_STRING_TO_ARRAY_FAILED = FSL_JSON_W_START + 4,
FSL_JSON_W_END = 1000,
FSL_JSON_E_GENERIC = 1000,
FSL_JSON_E_GENERIC_SUB1 = FSL_JSON_E_GENERIC + 100,
FSL_JSON_E_INVALID_REQUEST = FSL_JSON_E_GENERIC_SUB1 + 1,
FSL_JSON_E_UNKNOWN_COMMAND = FSL_JSON_E_GENERIC_SUB1 + 2,
FSL_JSON_E_UNKNOWN = FSL_JSON_E_GENERIC_SUB1 + 3,
FSL_JSON_E_RESOURCE_NOT_FOUND = FSL_JSON_E_GENERIC_SUB1 + 4,
FSL_JSON_E_TIMEOUT = FSL_JSON_E_GENERIC_SUB1 + 5,
FSL_JSON_E_ASSERT = FSL_JSON_E_GENERIC_SUB1 + 6,
FSL_JSON_E_ALLOC = FSL_JSON_E_GENERIC_SUB1 + 7,
FSL_JSON_E_NYI = FSL_JSON_E_GENERIC_SUB1 + 8,
FSL_JSON_E_PANIC = FSL_JSON_E_GENERIC_SUB1 + 9,
FSL_JSON_E_AUTH = 2000,
FSL_JSON_E_MISSING_AUTH = FSL_JSON_E_AUTH + 1,
FSL_JSON_E_DENIED = FSL_JSON_E_AUTH + 2,
FSL_JSON_E_WRONG_MODE = FSL_JSON_E_AUTH + 3,
FSL_JSON_E_RESOURCE_ALREADY_EXISTS = FSL_JSON_E_AUTH + 4,
FSL_JSON_E_LOGIN_FAILED = FSL_JSON_E_AUTH + 100,
FSL_JSON_E_LOGIN_FAILED_NOSEED = FSL_JSON_E_LOGIN_FAILED + 1,
FSL_JSON_E_LOGIN_FAILED_NONAME = FSL_JSON_E_LOGIN_FAILED + 2,
FSL_JSON_E_LOGIN_FAILED_NOPW = FSL_JSON_E_LOGIN_FAILED + 3,
FSL_JSON_E_LOGIN_FAILED_NOTFOUND = FSL_JSON_E_LOGIN_FAILED + 4,
FSL_JSON_E_USAGE = 3000,
FSL_JSON_E_INVALID_ARGS = FSL_JSON_E_USAGE + 1,
FSL_JSON_E_MISSING_ARGS = FSL_JSON_E_USAGE + 2,
FSL_JSON_E_DB = 4000,
FSL_JSON_E_STMT_PREP = FSL_JSON_E_DB + 1,
FSL_JSON_E_STMT_BIND = FSL_JSON_E_DB + 2,
FSL_JSON_E_STMT_EXEC = FSL_JSON_E_DB + 3,
FSL_JSON_E_DB_LOCKED = FSL_JSON_E_DB + 4,
FSL_JSON_E_DB_NEEDS_REBUILD = FSL_JSON_E_DB + 101
};
/*
** Signature for JSON page/command callbacks. Each callback is
** responsible for handling one JSON request/command and/or
** dispatching to sub-commands.
**
** By the time the callback is called, json_page_top() (HTTP mode) or
** json_cmd_top() (CLI mode) will have set up the JSON-related
** environment. Implementations may generate a "result payload" of any
** JSON type by returning its value from this function (ownership is
** tranferred to the caller). On error they should set
** g.json.resultCode to one of the FossilJsonCodes values and return
** either their payload object or NULL. Note that NULL is a legal
** success value - it simply means the response will contain no
** payload. If g.json.resultCode is non-zero when this function
** returns then the top-level dispatcher will destroy any payload
** returned by this function and will output a JSON error response
** instead.
**
** All of the setup/response code is handled by the top dispatcher
** functions and the callbacks concern themselves only with generating
** the payload.
**
** It is imperitive that NO callback functions EVER output ANYTHING to
** stdout, as that will effectively corrupt any JSON output, and
** almost certainly will corrupt any HTTP response headers. Output
** sent to stderr ends up in my apache log, so that might be useful
** for debuggering in some cases, but so such code should be left
** enabled for non-debuggering builds.
*/
typedef cson_value * (*fossil_json_f)();
/*
** Holds name-to-function mappings for JSON page/command dispatching.
**
*/
typedef struct JsonPageDef{
/*
** The commmand/page's name (path, not including leading /json/).
**
** Reminder to self: we cannot use sub-paths with commands this way
** without additional string-splitting downstream. e.g. foo/bar.
** Alternately, we can create different JsonPageDef arrays for each
** subset.
*/
char const * name;
/*
** Returns a payload object for the response. If it returns a
** non-NULL value, the caller owns it. To trigger an error this
** function should set g.json.resultCode to a value from the
** FossilJsonCodes enum. If it sets an error value and returns
** a payload, the payload will be destroyed (not sent with the
** response).
*/
fossil_json_f func;
/*
** Which mode(s) of execution does func() support:
**
** <0 = CLI only, >0 = HTTP only, 0==both
*/
char runMode;
} JsonPageDef;
/*
** Holds common keys used for various JSON API properties.
*/
typedef struct FossilJsonKeys_{
/** maintainers: please keep alpha sorted (case-insensitive) */
char const * anonymousSeed;
char const * authToken;
char const * commandPath;
char const * payload;
char const * requestId;
char const * resultCode;
char const * resultText;
char const * timestamp;
} FossilJsonKeys_;
const FossilJsonKeys_ FossilJsonKeys;
/*
** A page/command dispatch helper for fossil_json_f() implementations.
** pages must be an array of JsonPageDef commands which we can
** dispatch. The final item in the array MUST have a NULL name
** element.
**
** This function takes the command specified in
** json_comand_arg(1+g.json.dispatchDepth) and searches pages for a
** matching name. If found then that page's func() is called to fetch
** the payload, which is returned to the caller.
**
** On error, g.json.resultCode is set to one of the FossilJsonCodes
** values and NULL is returned. If non-NULL is returned, ownership is
** transfered to the caller.
*/
cson_value * json_page_dispatch_helper(JsonPageDef const * pages);
/*
** Implements the /json/wiki family of pages/commands.
**
*/
cson_value * json_page_wiki();
/*
** Implements /json/timeline/wiki and /json/wiki/timeline.
*/
cson_value * json_timeline_wiki();
/*
** Implements /json/timeline family of functions.
*/
cson_value * json_page_timeline();
/*
** Convenience wrapper around cson_value_new_string().
** Returns NULL if str is NULL or on allocation error.
*/
cson_value * json_new_string( char const * str );
#endif/*FOSSIL_JSON_DETAIL_H_INCLUDED*/