omni_tool/3rd/sql/ob/include/jzndom.h

5094 lines
176 KiB
C

/* Copyright (c) 2015, 2026, Oracle and/or its affiliates.*/
/* All rights reserved.*/
/*
NAME
jzndom.h - JSON DOM interfaces
DESCRIPTION
Allow manipulation of a JSON object tree as a DOM.
RELATED DOCUMENTS
EXPORT FUNCTION(S)
Contains the following definitions:
- DOM structures and function-pointer interface.
- DOM writer: a facility for creating a DOM by pushing events to a builder
- DOM reader: a facility for treating a DOM as an event source
EXAMPLES
NOTES
This is a public (to customers) header file and world-viewable.
The file can include only public headers.
MODIFIED (MM/DD/YY)
apfwkr 01/09/26 - CI #38834200 of zliu_bug-38802310 from main
apfwkr 10/02/25 - CI #38496481 of zliu_bug-38057189 from main
apfwkr 04/30/25 - CI #37891631 of acolunga_bug-37841761 from main
apfwkr 04/01/25 - CI #37776791 of zliu_bug-37488368 from main
apfwkr 10/30/24 - CI# 37230449 of dmcmahon_bug-36788895 from main
apfwkr 06/06/24 - CI# 36706798 of dmcmahon_bug36357136 from main
dmcmahon 02/11/26 - Bug 38956148: native charset APIs
zliu 12/25/25 - Bug 38802310/28680876: complete support for keyvalue()
zliu 11/01/25 - Bug 38636001: JZNOCT_SERINMEM_ONEPATH/TRY_UB2_OFF
dmcmahon 10/08/25 - Bug 38511169: JsonDomSortObject, JsonDomKeepFields
zliu 07/18/25 - Bug 38212527: JsonDomTxtContains()
dmcmahon 07/10/25 - Bug 38178369: JsonDomFieldCase()
zliu 07/04/25 - Bug38212507,37157467:JsonDomNodeSeqAsAryAnyType()
zliu 06/04/25 - Bug 38057189: fast deep-eq and anytype gen for oson
dmcmahon 04/28/25 - Bug 37898144: JsonDomCreateROWID()
acolunga 04/16/25 - Bug 37841761: event source for AnyType reader
zliu 04/09/25 - Bug 37822204: cache_fieldarypos_jznDomObjFieldName
zliu 03/10/25 - Bug 37488368: JsonDomXXXSimPathRngFilter pred dom api
zliu 01/17/25 - Bug 37486754: JsonDomAryMinMaxJt,JsonDomAryAggRetSca
dmcmahon 01/07/25 - Bug 37454448: JZNANY_FLAG_PRESERVE_[TYPES|ORDER]
zliu 12/20/24 - Bug 37429418 JZNDOM_FIELD_POS_SET
dmcmahon 11/05/24 - Bug 37249695: sb2val/ub2val for jznScalarVal
dmcmahon 10/31/24 - Bug 37236015: lint and tab cleanup
zliu 10/08/24 - Bug 37204122: dom api to push down range cmp/in-clause
zliu 09/10/24 - Bug 37054087: add JZNDOM_OCT_NOT_4_UPD
zliu 08/30/24 - Bug 37020310: JZNDOMCHK_ALLOW_SAME_FAM
dmcmahon 08/22/24 - Bug 36979516: add jznDomWriterGetCount()
dmcmahon 08/16/24 - Bug 36958159: add jznDomWriterGetDoc()
huiz 07/31/24 - Bug 36889754: add JZNDOM_UNKNOWN
zliu 07/08/24 - Bug 36817752: jznDomChkJModifier()
dmcmahon 06/17/24 - Bug 36761296: JZNANY_FLAG_NULL_ON_EMPTY
dmcmahon 06/06/24 - Bug 36732069: jznDomScalarArray()
dmcmahon 12/30/23 - Bug 36148907: jznScalarVal fields for opaque
zliu 12/18/23 - bug 36132471: vector type into json xdk JZNVAL_VECTOR
dmcmahon 10/04/23 - Bug 35875900: jznDomSetRoot return status code
zliu 08/15/23 - Bug 35746966: JZNDOM_OCT_TREE_SZ_UB4
zliu 07/04/23 - Bug 35570236: JZNDOM_PRINT_HDL_RAW_ASOSON
dmcmahon 06/28/23 - Bug 34841184: JsonDomNumberFrom(Long|Double)
dmcmahon 06/27/23 - Bug 35533687: Reader/Writer oramemctx constructors
zliu 05/20/23 - bug 35431180: share oson decoder ctx for json eval
zliu 05/20/23 - bug 35431180: dom api of reset with flag parameter
dmcmahon 05/05/23 - Bug 35284528: JZNDOM_COMPARE_FLAG_TEMP
dmcmahon 03/15/23 - Bug 35185835: comments on JsonDomGetFieldValue
zliu 03/08/23 - Bug 35219425: support ub2_field_name_length for
dmcmahon 03/07/23 - Bug 35113192: xmlctx parameter for TSTZ formatting
dmcmahon 02/15/23 - Bug 35088293: JZNDOM_COMPARE_FLAG_TYPECHECK
dmcmahon 01/20/23 - Bug 35002198: JZNDOM_COMPARE_FLAG_BRACKET
zliu 09/19/22 - Bug 34615330: jznDomCompareWithTypeBracket()
dmcmahon 08/22/22 - Bug 34528802: JsonDomGetScalarType()
dmcmahon 08/09/22 - Bug 34477101: JsonDomReplaceField()
dmcmahon 08/05/22 - Bug 34470402: JsonDomSetScalar()
dmcmahon 08/03/22 - Bug 34457920: JsonDomCopyScalar()
dmcmahon 07/12/22 - Bug 34373161: JZNANY node-type match flags
dmcmahon 06/06/22 - Bug 34248833: JZNDOM_NODE_HASH_LENGTH == 16
dmcmahon 04/30/22 - Bug 34125921: JsonDomAnyCompare()
zliu 04/07/22 - Bug 34050578: add JZNDOM_OCT_COMPACT_CLUSTER
dmcmahon 03/11/22 - Bug 33948659: jznDomUnwrapRootArray
sriksure 02/14/22 - Bug 33845235: Cast mode of schema validation
zliu 01/18/22 - Bug 33766164:JZNDOM_OCT_SHR_SIMP_NODES
dmcmahon 09/09/21 - Bug 33334358: lpxmemctx should not be exposed here
dmcmahon 06/23/21 - Bug 33061052: comments about hash
dmcmahon 06/25/21 - Bug 33048916: new DOM array bulk methods
dmcmahon 06/19/21 - Bug 33022120: Add JsonDomReadAnyType()
dmcmahon 06/12/21 - Bug 32995128: Array sort as a DOM method
dmcmahon 06/10/21 - Bug 32988631: JsonDomSortArray
dmcmahon 06/08/21 - Bug 32973954: max depth/size for JsonDomAnyType
dmcmahon 06/04/21 - Bug 32967328: JsonDomAnyType()
sriksure 05/27/21 - Bug 32934766: Add JsonDomArrayIsUnique()
jvalera 05/21/21 - Bug 32903599: Add JZN_UNKNOWN_DOM
dmcmahon 05/19/21 - Bug 32904319: jznDomHash
dmcmahon 05/19/21 - Bug 32904319: JsonDomHash()
sriksure 03/08/21 - Bug 32593809: Bulk loading from OSON stream
sriksure 02/24/21 - Bug 32409241: Support JZN_FORMAT in JsonDomCreate()
dmcmahon 01/14/21 - Bug 32383277: add JZNDOM_TRACK_POSITIONS
sriksure 10/09/20 - Bug 31996145: Add JsonLoadDom(), JsonSerializeDom()
dmcmahon 08/31/20 - Bug 31820651: add JsonDomLoadItem
dmcmahon 08/12/20 - Bug 31748678: new DOM constructors
dmcmahon 07/17/20 - Bug 31637902: New DOM methods
zliu 07/24/20 - Bug 31694034:
JZNDOM_NO_SHARE_OBJ_DEFN,JZNDOM_USE_UB4_OFFSET
dmcmahon 07/15/20 - Fix jznDomM_SetError again
dmcmahon 07/08/20 - Add dummy_jznoctFieldName
dmcmahon 07/06/20 - Bug 31584233: prop up jznDomM_SetError for clsjson.c
dmcmahon 06/27/20 - Store fldnm offset in jznDomObjFieldName dead space
zliu 06/10/20 - document error return case
dmcmahon 06/05/20 - DOM reader/writer captive constructors move to jzn.h
dmcmahon 05/04/20 - Bug 31292369: Constructors may return NULLs
sriksure 03/24/20 - Bug 31075323: Add JZNVAL type, setter for LdiInterval
sriksure 02/20/20 - Bug 30918101: Add new DOM method, remove varargs
from GetScalarInfo
sriksure 02/20/20 - Bug 30918101: Unpickle native binary values
zliu 01/26/20 - Bug 30840791,30857500: jznDomWriterGetWrtCnt()
zliu 09/11/19 - Bug 30300159: JZNDOM_DOM_FOR_OSON_PUDP_REP_ONLY
dmcmahon 08/12/19 - bug 30180010: add jznDomReaderSetFlags()
bhammers 05/17/19 - bug 29794416: JZNDOM_DISALLOW_SCALARS
dmcmahon 04/24/19 - bug 29687763: add JZNDOM_VALIDATE_STRINGS
zliu 04/08/19 - Bug 29619119: JZNDOM_DOM_FOR_VALIDATION
dmcmahon 04/07/19 - bug 29611018: JZNVAL_ID
dmcmahon 04/04/19 - Bug 29599702: JsonDomFreeNode()
dmcmahon 03/28/19 - Bug 29554518: fix more broken macros
zliu 03/13/19 - Bug 29514638:enable JZNVAL_CANONICAL_FLOAT &
JZNVAL_CANONICAL_DOUBLE
bhammers 03/19/19 - correct macros, indentation, 80 chars per line
dmcmahon 02/27/19 - Fix macro JsonDomDeleteFieldByName()
dmcmahon 02/22/19 - Fix macro JsonDomCreateStream()
zliu 12/04/18 - Bug 28968363: add JZNOCT_FIELD_NM_PARTIAL
sriksure 09/27/18 - Bug 28717127: Rationalize includes in public jzn*.h
zliu 09/26/18 - Bug 28708424: add jznoctLoadInMemDomFromInputOSON_WF()
dmcmahon 09/13/18 - Bug 28645808: fix lint problems
dmcmahon 09/05/18 - bug 28603908: jznDomScalarToString
sriksure 08/23/18 - Bug 28546488: XDK C JSON APIs enhancements
zliu 06/28/18 - Parital OSON update add JZNDOM_DOM_FOR_OSON_PUPD
zliu 04/10/18 - Bug 27896443 add JsonDomGetDescendantNodes()
zliu 01/14/18 - Bug 27390960: add JZNDOM_FIELD_USED
zliu 11/28/17 - number of distinct fields increasing from ub2 to ub4
dmcmahon 10/21/17 - Bug 26739606: comment formatting
zliu 08/12/17 - add JZNDOM_DOM_FOROSON_ENC
zliu 06/22/17 - fix bug 26331370
dmcmahon 04/25/17 - Bug 25954542: oradslen_jznScalarVal typo
dmcmahon 03/07/17 - add JZNDOM_PRESERVE_NODES
zliu 11/29/16 - set oson support
dmcmahon 11/09/16 - Bug 25072880: add jznCreateDomVA()
zliu 08/02/16 - no noinlineleaf mode
zliu 06/15/16 - add JsonDomNodeVisitor() api
zliu 06/15/16 - add JsonDomPrintNode() api
zliu 06/10/16 - add jznoct_dom_visit()
zliu 06/05/16 - add JZNDOM_BATCH_API
zliu 06/04/16 - supporting jzn0dom construction from oson binary
zliu 06/03/16 - JsonDomCreateArray(),JsonDomCreateObject() size param
zliu 06/01/16 - add JZNDOM_REUSE_NAMES
dmcmahon 02/17/16 - Add jznDomWriterReadSource()
zliu 01/25/16 - add inline leaf val encoding for oson
zliu 01/19/16 - streaming encoding for oson
dmcmahon 10/21/15 - Bug 22082373 - Add JsonDomSetXmlContext()
zliu 10/08/15 - add JZNDOM_NO_FRC_UB1_HID
dmcmahon 07/01/15 - Bug 21356957 - add JZNDOM_CHECKLINKS
dmcmahon 04/30/15 - Bug 20992659 - jznDomSortFields()
bhammers 03/31/15 - added JsonDomRenameField
dmcmahon 03/12/15 - Creation
*/
#ifndef JZNDOM_ORACLE
# define JZNDOM_ORACLE
#ifndef ORATYPES
# include <oratypes.h>
#endif
#ifndef ORASTRUC
# include <orastruc.h>
#endif
#ifndef XML_ORACLE
# include <xml.h>
#endif
#ifndef JZNTYPES_ORACLE
# include <jzntypes.h>
#endif
#ifndef JZNEV_ORACLE
# include <jznev.h>
#endif
/*---------------------------------------------------------------------------
PUBLIC TYPES AND CONSTANTS
---------------------------------------------------------------------------*/
/*
** Public Types
*/
#define JsonDomDoc jznDomDoc /* JSON DOM Document Container */
#define JsonDomNode jznDomNode /* Abstract JSON Node Type */
#define JsonDomObject jznDomObject /* JSON Object Type */
#define JsonDomArray jznDomArray /* JSON Array Type */
#define JsonDomScalar jznDomScalar /* JSON Scalar Type */
/*
** Forward Declarations
*/
/*
** JSON DOM Conatiner
*/
typedef struct jznDomDoc jznDomDoc;
/*
** JSON DOM nodes, these are abstract classes
** JSON Scalar DOM node, a derivation type of jznDomNode
** JSON Object DOM node, a derivation type of jznDomNode
** JSON Array DOM node, a derivation type of jznDomNode
*/
typedef struct jznDomNode jznDomNode;
typedef struct jznDomScalar jznDomScalar; /* Castable to jznDomNode */
typedef struct jznDomObject jznDomObject; /* Castable to jznDomNode */
typedef struct jznDomArray jznDomArray; /* Castable to jznDomNode */
#define JZN_SCALAR_VAL_SZ 256 /* ### Not sure why we define this? ### */
#define JZN_ORA_NUM_MAXSZ 22 /* ### Not sure why this is public? ### */
/*****************************************************
* JSON DOM API
*****************************************************/
/*
** DOM Scalar Value Output Structure
*/
typedef struct jznScalarVal
{
jznvaltype type_jznScalarVal;
jzn_sval_union uval_jznScalarVal;
/* JZNVAL_STRING */
#define len_jznScalarVal uval_jznScalarVal.val.valuelen
#define val_jznScalarVal uval_jznScalarVal.val.value
/* JZNVAL_BINARY */
#define binval_jznScalarVal uval_jznScalarVal.bval.value
#define binlen_jznScalarVal uval_jznScalarVal.bval.valuelen
/* JZNVAL_VECTOR */
#define vecval_jznScalarVal uval_jznScalarVal.bval.value
#define veclen_jznScalarVal uval_jznScalarVal.bval.valuelen
/* JZNVAL_ANY_TYPE */
#define subtype_jznScalarVal uval_jznScalarVal.opaque.subtype
#define flags_jznScalarVal uval_jznScalarVal.opaque.flags
#define dtype_jznScalarVal uval_jznScalarVal.opaque.dtype
/* JZNVAL_SHORT, JZNVAL_USHORT - machine native sb2, ub2 */
#define sb2val_jznScalarVal uval_jznScalarVal.ival.shortval
#define ub2val_jznScalarVal uval_jznScalarVal.uval.shortval
/*
** JZNVAL_FLOAT16, JZNVAL_BFLOAT16 - canonical ub2, platform-endian, in-line
** This is done so that comparisons can be done on the ub2. C has no native
** 16-bit floating-point types, but SQL doesn't have a representation either.
*/
/* JZNVAL_SINT, JZNVAL_UINT - machine native sb4, ub4 */
#define sb4val_jznScalarVal uval_jznScalarVal.ival.intval
#define ub4val_jznScalarVal uval_jznScalarVal.uval.intval
/* JZNVAL_SLONG, JZNVAL_ULONG - machine native sb8, ub8 */
#define sb8val_jznScalarVal uval_jznScalarVal.ival.longval
#define ub8val_jznScalarVal uval_jznScalarVal.uval.longval
/* JZNVAL_FLOAT - machine native float */
#define flt_jznScalarVal uval_jznScalarVal.fval.ftval
/* JZNVAL_DOUBLE - machine native double */
#define db_jznScalarVal uval_jznScalarVal.dval.fpval
/* JZNVAL_TSTAMP - structured timestamp */
#define tstamp_jznScalarVal uval_jznScalarVal.tval.dtval
/* JZNVAL_UUID/JZNVAL_OID/JZNVAL_ROWID - in-line ID */
#define id_jznScalarVal uval_jznScalarVal.pval.oidval
/* JZNVAL_DECIMAL - in-line Decimal128 */
#define mem_jznScalarVal uval_jznScalarVal.xval.mem128
/* JZNVAL_CANONICAL_FLOAT, JZNVAL_CANONICAL_DOUBLE
** Oracle native binary/canonical float, double
*/
#define flt_orabin_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define db_orabin_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
/* JZNVAL_ORA_NUMBER - Oracle native number */
#define oranumval_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define oranumlen_jznScalarVal uval_jznScalarVal.obinval.oblen_obinval
/* JZNVAL_ORA_TIME - Oracle native time */
#define oratimeval_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define oratimelen_jznScalarVal uval_jznScalarVal.obinval.oblen_obinval
/* JZNVAL_ORA_DATE - Oracle native date */
#define oradateval_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define oradatelen_jznScalarVal uval_jznScalarVal.obinval.oblen_obinval
/* JZNVAL_ORA_TIMESTAMP - Oracle native timestamp */
#define oratimestampval_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define oratimestamplen_jznScalarVal uval_jznScalarVal.obinval.oblen_obinval
/* JZNVAL_ORA_TIMESTAMPTZ - Oracle native timestamp with timezone */
#define oratimestamptzval_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define oratimestamptzlen_jznScalarVal uval_jznScalarVal.obinval.oblen_obinval
/* JZNVAL_ORA_YEARMONTH_DUR - Oracle native year month interval */
#define orayrmnval_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define orayrmnlen_jznScalarVal uval_jznScalarVal.obinval.oblen_obinval
/* JZNVAL_ORA_DAYSECOND_DUR - Oracle native day second interval */
#define oradsval_jznScalarVal uval_jznScalarVal.obinval.obinptr_obinval
#define oradslen_jznScalarVal uval_jznScalarVal.obinval.oblen_obinval
} jznScalarVal;
/*
** JSON DOM nodes come in three types:
** Scalars: number, string, true/false/null, + extensions
** Objects: containers with unordered field/value pairs
** Arrays: containers with ordered values
*/
typedef enum
{
JZNDOM_UNKNOWN = 0,
JZNDOM_SCALAR = 1,
JZNDOM_OBJECT = 2,
JZNDOM_ARRAY = 3
} jznnodetype;
/*
** Hash id of a JSON object field name (big-endian ub4 encoded)
*/
typedef ub4 jznoct_hashidt;
/*
** Field name offset (for OSON encoding)
*/
typedef ub4 jzndom_fnmOff;
typedef struct jznDomObjFieldName
{
oratext *fnm_jznDomObjFieldName; /* JSON object field name */
ub4 len_jznDomObjFieldName; /* length of JSON field name */
jznoct_hashidt hashid_jznDomObjFieldName; /* hashId of object field name */
/* hashid_jznDomObjFieldName shall be set
* so that jznOctLocateFieldId() for OSON DOM via JsonDomGetFieldValue()
* can use the hashid look up directly
* instead of computing from scratch to improve performance.
* Optimization using hashid is also true for
* in-memory JSON DOM via jzn0DomFindField() using hashid match first.
*/
/*
** ### Ideally we would not expose these internal members to customers.
** ### The size of this structure should then be 16 bytes.
*/
/* Bug 37429418 fix:
** id of the field name within an instance OSON
** It is 1 based instead of 0 based. 0 means the id info is not available.
** Note ub4 shall be the same as jznoct_fnmOff type, which is ub4.
** This is returned by DOM call:
** JsonDomGetFieldValue(doc, (jznDomObject *)curnode, fnm);
** for OSON DOM: JsonDomGetFieldValue()
** calls jznOctLocateFieldId() which uses
** cahced fnm->id_jznDomObjFieldName if available
** or
** pre-computed fnm->hashid_jznDomObjFieldName in shared cursor query plan
** to do binary search of fields with that paritcular field name <fnm>
** For setOSON case, it also uses fnm->idInSetOSON_jznDomObjFieldName.
** jznEngSetUpModifiableFnmFromStep() calls JsonDomGetFieldValue().
** Each jznEng has jznEngFsm struct that has an array of jznDomObjFieldName
** that is used to cache field name ids when traversing oson dom at per
** instance level.
*/
ub4 id_jznDomObjFieldName;
/*
** As total number of distinct field inceases from ub2 to ub4, so
** we can not use ub2 anymore, so we declare id_jznDomObjFieldName as ub4
** above and use ub2hash_jznDomObjFieldName to store ub2 hash.
*/
ub2 ub2hash_jznDomObjFieldName;
#define id_ub2_jznDomObjFieldName ub2hash_jznDomObjFieldName
/* Bug 37822204 fix.
** JZNDOM_FIELD_ARYPOS_SET flag is on
** when this jznDomObjFieldName is set up by
** jznEngSetUpModifiableFnmFromStep() to find a field value
** within OSON bytes for json object , such as
** {"firstName":"zhen","lastNmae":"liu","city":"Berkeley", "zip" : 94701}
** to access field "city"'s value,
** jznEngSetUpModifiableFnmFromStep() uses
** cache_fieldarypos_jznDomObjFieldName
** to cache its array position
** is 3rd position (1 based array) so that for objects of the same structure,
** the cache value can avoid doing binary search again inside object.
** When cache_fieldarypos_jznDomObjFieldName ==0, it means it is NOT set up.
** That is why cache_fieldarypos_jznDomObjFieldName is 1 based array position.
** Note the return value from jznEngSetUpModifiableFnmFromStep() is private
** to each thread, so it is ok to write it at run time.
*/
#define cache_fieldarypos_jznDomObjFieldName ub2hash_jznDomObjFieldName
ub1 flag_jznDomObjFieldName; /* flag */
#define JZNDOM_FIELD_NOT_EXISTS_IN_THIS_SET 0x1
#define JZNDOM_FIELD_USED 0x2
#define JZNDOM_FIELD_POS_SET 0x4
#define JZNDOM_FIELD_ARYPOS_SET 0x8
/* When JZNDOM_FIELD_ARYPOS_SET flag is on, then ub2hash_jznDomObjFieldName
* is interpretted as cache_fieldarypos_jznDomObjFieldName.
* Normal DOM users do not turn on JZNDOM_FIELD_ARYPOS_SET flag, only
* json dom engine internally uses this flag JZNDOM_FIELD_ARYPOS_SET flag.
*/
/* JZNDOM_FIELD_POS_SET indicating pos_jznoctFieldName is valid */
ub1 ub1hash_jznDomObjFieldName; /* 1 byte hashid */
/*
** In OSON set encoding for IMCJ usecase, a set of JSON instances
** is encoded into OSON instances with shared field name buffers, so
** we need to use setId_jznDomObjFieldName to get its field id.
** It is 1 based instead of 0 based. 0 means the id info is not available.
*/
ub2 idInSetOSON_jznoctFieldName;
/*
** Array Position within the array of fieldname structures
** (sideband array of unique fields) prepared by jznp_qjsnBldFidsForPathExpr()
** In step structures for path expressions, this is used as the slot number
** for a sideband array of unique fields.
*/
ub2 pos_jznoctFieldName;
jzndom_fnmOff nmoff_jznoctFieldName; /* offset into the field name seg */
} jznDomObjFieldName;
// ### Temporarily prop up existing readers
#define idInSetOSON_jznDomObjFieldName idInSetOSON_jznoctFieldName
#define jznoctFieldName jznDomObjFieldName
/*
** This structure is used to read field name/value pairs from the DOM.
** The values are always nodes. The field name structure contains the
** name string and length, plus some fields to treat the field name
** via hash/id codes and to deal with set-based DOMs (which share
** the field name information across DOM instances).
*/
typedef struct jznDomNameValuePair
{
jznDomObjFieldName name_jznDomNameValuePair;
jznDomNode *node_jznDomNameValuePair;
} jznDomNameValuePair;
// ### Why didn't we return a pointer to jznDomObjFieldName in the above
// ### structure? It makes the structure 40 bytes in size, whereas in the
// ### DOM itself it's stored as a pair of pointers (16 bytes). This also
// ### forces exposure of the large structure jznDomObjFieldName which is
// ### heavy with internal fields.
#define JZNDOMNODE_NULL ((jznDomNode *)NULL)
/* ### Unfortunately exposed through ordinary DOM ### */
typedef struct jznosonFile jznosonFile;
/*
** jznDomDoc is the container for the JSON DOM tree. It is the
** first argument to all jznDomAPI methods.
** The constructor for jznDomDoc is jznCreateDom() which can creates
** different implementations of the same jznDomAPI interface
*/
typedef struct jznDomAPI jznDomAPI;
struct jznDomDoc
{
/*
** DOM method callback functions (implementation-specific)
*/
jznDomAPI *mthds_jznDomDoc;
/*
** Required members common to all DOMs
*/
xmlctx *xctx_jznDomDoc; /* XML context */
jsonerr errcode_jznDomDoc; /* Error code */
ub4 modcount_jznDomDoc; /* Modification count */
};
typedef enum jznDomTyp
{
JZN_UNKNOWN_DOM = 0, /* Unknown DOM type */
JZN_INMEM_DOM = 1, /* mutable DOM backed by in-memory structures */
JZN_OSON_DOM = 2 /* immutable DOM backed by OSON serialized buffer */
} jznDomTyp;
/*
** Used for DOM visitor callback func JsonDomNodeVisitor
*/
typedef struct JsonDomVisitorInfo
{
jznDomDoc *jdoc_JsonDomVisitorInfo;
jznDomNode *node_JsonDomVisitorInfo;
jznnodetype ntyp_JsonDomVisitorInfo;
/* node type of the node_JsonDomVisitorInfo */
ub4 tot_JsonDomVisitorInfo;
/* total children if the node_JsonDomVisitorInfo is object/array node */
jznScalarVal *scal_JsonDomVisitorInfo;
/* scalar info if the node_JsonDomVisitorInfo is scalar node */
} JsonDomVisitorInfo;
typedef void (*JsonDomVisitorFunc)(JsonDomVisitorInfo *vinfo, void *appctx) ;
/*
** DOM API can fetch an array of obj/array children with size
** JZNDOM_BATCH_API to improve performance
*/
#define JZNDOM_BATCH_API 128
/*
** JSON DOM Constructor flags
**
** Can be used as flags argument in call to jznCreateDom() or JZN_MODE
** varargs argument in call to JsonDomCreate().
*/
#define JZNDOM_FLAGS_NONE 0x00000000
/*
** By default, jznDomDoc can be created once and be re-used for many JSON
** doc instances so that memory resources can be allocated once re-used to
** cycle through many object instances. Setting flag JZNDOM_RECYCLE_ALL
** forces cleaning up resources on each JSON object instance.
*/
#define JZNDOM_RECYCLE_ALL 0x00000001
/*
** By default, oson binary sorts field ids of an object so that
** locating field within an object caqn be very efficient via binary
** search. However, this may be at the expense of encoding the oson
** and looses the original order of fields within the object (although
** order of fields within json object is undefined)
** Setting JZNDOM_OCT_NOSORTFID forces no sorting of field ids for encoding.
*/
#define JZNDOM_OCT_NOSORTFID 0x00000002
/*
** By default, all JSON number are stored as ORA number format.
** However, for internal testing purpose, this JZNDOM_NUM_AS_STR stores
** JSON number as string.
*/
#define JZNDOM_NUM_AS_STR 0x00000004
/*
** By default, float and double are stored as native binary format aka
** canonical format. This flag requests that for reading via
** JsonDomGetScalarInfo(), the types JZNVAL_CANONICAL_DOUBLE and
** JZNVAL_CANONICAL_FLOAT are converted to JZNVAL_DOUBLE and JZNVAL_FLOAT
** when delivered to a DOM read operation.
*/
#define JZNDOM_NUM_AS_IEEE 0x00000008
/*
** Build set oriented DOM for in-memory Columnar JSON processing. In this mode,
** a SET of JSON document instances are encoded together by sharing
** field-name dictionary and path-value dictionary. However, each JSON doc
** still has its navigational tree component seperated.
*/
#define JZNDOM_SET4IMJ 0x00000010
/*
** Bypass internal free lists of nodes. This may give a minor boost to
** performance while sacrificing memory efficiency.
*/
#define JZNDOM_NOFREELIST 0x00000020
/*
** ### This will replace JZNDOM_NUM_AS_STR, which will become the default.
** ### This flag will eventually disable string numbers.
*/
#define JZNDOM_NUM_AS_ORA 0x00000040
/*
** Ensure that non-orphan nodes are not linked multiple times.
** Prevent cyclic references in the DOM tree.
*/
#define JZNDOM_CHECKLINKS 0x00000080
/*
** NOT to Force to Use UB1 hash id for oson hash id
** This flag is DEPRECATED, no usage
*/
#define JZNDOM_NO_FRC_UB1_HID 0x00000100
/*
** OSON streaming encoding, that is each child of an obj/array encoded
** in streaming fashion without tree node table
** This flag is DEPRECATED, no usage
*/
#define JZNDOM_STREAM_ENCODED 0x00000200
/*
** For partial OSON update, if there is only replacement needed without
** extending segments, then we do partial OSON doc update. Otherwise, we do
** full OSON doc update.
*/
#define JZNDOM_DOM_FOR_OSON_PUDP_REP_ONLY 0x00000400
/*
** For JSON DOM construction over a set of JSON docs, re-use hash table
** for field names
*/
#define JZNDOM_REUSE_NAMES 0x00000800
/*
** For JSON DOM mutations preserve freed nodes (e.g. for PL/SQL).
** This is memory-heavy but supports PL/SQL's reference semantics.
*/
#define JZNDOM_PRESERVE_NODES 0x00001000
/*
** This in-memory DOM is used for OSON encoding purpose
*/
#define JZNDOM_DOM_FOROSON_ENC 0x00002000
/*
** Support partial OSON updates on persistent OSON.
*/
#define JZNDOM_DOM_FOR_OSON_PUPD 0x00004000
/*
** Validate incoming OSON bytes and reject possible malicious bytes.
*/
#define JZNDOM_DOM_FOR_VALIDATION 0x00008000
/*
** Ensure strings and field names are correct UTF-8 sequences.
*/
#define JZNDOM_VALIDATE_STRINGS 0x00010000
/*
** Reject if JSON is a scalar value
*/
#define JZNDOM_DISALLOW_SCALARS 0x00020000
/*
** As an event source, preserve extended types
*/
#define JZNDOM_EMIT_EXTENDED_TYPES 0x00040000
/*
** No array of obj sharing defintion optimization during oson encoding
*/
#define JZNDOM_NO_SHARE_OBJ_DEFN 0x00080000
/*
** Use ub4 offset for tree offset always
*/
#define JZNDOM_USE_UB4_OFFSET 0x00100000
/*
** Allow nodes to be mounted on a tree multiple times.
** Effectively allows the DOM to be a directed acyclic graph.
*/
#define JZNDOM_MULTI_PARENT 0x00200000
/*
** Limits the DOM operations to those needed for initial construction.
** Disables remove/unlink operations, rename/move, and replacing values.
*/
#define JZNDOM_CONSTRUCTOR_ONLY 0x00400000
/*
** Adds a node hash table to track the parse position of each DOM node.
** Costly, use only when needed. Only works when constructing a DOM
** from a textual parse. Cannot track later mutations.
*/
#define JZNDOM_TRACK_POSITIONS 0x00800000
/* during oson encoding, all simple
* JSON scalar node representing json null, true,
* false, 0, "" are shared in oson image,
* All empty object {} and all empty array [] are shared in oson image.
* This makes resulting OSON size as compact/small as possible.
*
* {"a":null, "b":null} json scalar null is shared.
* {"a":[], "b":[]} json empty array is shared.
*/
#define JZNDOM_OCT_SHR_SIMP_NODES 0x01000000
/* during oson encoding, sharing JSON scalar node of the same leaf value
* if their parents have the same key name.
* This makes resulting OSON size as compact/small as possible.
*
* [ {"a": "done", "b": "finished" }, {"b": "finished"}]
* leaf node "finished" is shared in oson image.
*/
#define JZNDOM_OCT_SHR_PA_SCALAR 0x02000000
/* during oson encoding, sharing JSON scalar node of the same leaf value
* regardless of its parent key.
* This makes resulting OSON size as compact/small as possible. But this
* encoding mode is very expensive. So it is seldomly used.
*
* [ {"a": "finished", "b": "finished" }, {"b": "finished"}]
* leaf node "finished" is shared in oson image.
*/
/* share all possible leaf scalar nodes having the same leaf value*/
#define JZNDOM_OCT_SHR_ALL_SCALAR 0x04000000
/* offsets in array or object are relative to its parent during OSON
* encoding so that the resulting OSON is friendly for compression
* Example:
* Normal oson encoding:
* array node is at offset=100, its array content is [110, 140, 160].
* array node is at offset=220, its array content is [230, 260, 300].
*
* When JZNDOM_OCT_STR_REL_OFFSET is set,
* we encode the first array as [10, 40, 60].
* we encode the second array as [10, 40, 80].
*
*
* So compression algorithm can now compress 10, 40.
*/
#define JZNDOM_OCT_STR_REL_OFFSET 0x08000000
/* all shared nodes via JZNDOM_OCT_SHR_SIMP_NODES and
* JZNDOM_OCT_SHR_PA_SCALAR are clustered together in a
* a shared node cluster segement within the oson image.
* In this way, it is easy to identify if the node is shared for
* ease of direct node content replacement for partial oson update
*/
#define JZNDOM_OCT_COMPACT_CLUSTER 0x10000000
/* always use ub4 to store tree size, needed for template oson tree */
#define JZNDOM_OCT_TREE_SZ_UB4 0x20000000
/* OSON dom created not for updating OSON */
#define JZNDOM_OCT_NOT_4_UPD 0x40000000
/*
** By default, all JSON number are stored as ORA number format.
** However, for internal testing purpose, this JZNDOM_NUM_AS_DB stores
** JSON number as binary double (Oracle big-endian based binary double)
**
** ### DEPRECATED - See JZNDOM_NUM_AS_ORA
*/
#define JZNDOM_NUM_AS_DB 0x80000000
/* Bug37204122: dom api to push down range cmp/in-clause */
typedef struct jznEng_RngCmpInf jznEng_RngCmpInf;
typedef struct jznEng_InClauseInfo jznEng_InClauseInfo;
struct jznpFunction;
typedef struct jznEng_SimPathRngCmpInf jznEng_SimPathRngCmpInf;
typedef struct jznEng_TxtContInf jznEng_TxtContInf;
/*
** Used for JsonDomKeepFields()
*/
typedef struct jzndomFldKeepS
{
/* This may point to read only area not modifiable by the DOM API */
jznDomObjFieldName *name_jzndomFldKeepS; /* immutable memory */
/* NULL no matching field */
/* DOM Node ptr for in-memory json DOM or OSON node offset */
jznDomNode *node_jzndomFldKeepS;
ub4 fldid_jzndomFldKeepS; /* OSON field id, shall be jznoct_fnmOff */
/* 0 means no field matching this field name*/
ub4 pos_jzndomFldKeepS; /* original position in DOM */
} jzndomFldKeepS;
/*
** NAME:
** jznDomAPI
**
** DESCRIPTION:
** This is really Java Interface or C++ Pure abstract class.
** DOM API is a set of C function pointers; this provides an abstract
** interface whose concrete implementations are defined by each JSON
** DOM implementors. Callers are expected to use the macros to invoke
** the JSON DOM "methods"; these macros dereference the function pointers
** and call them, passing the instance as an argument.
*/
struct jznDomAPI
{
/*
** Loader Methods
*/
jznDomNode *(*jznDomLoadFromInputEventSrc)(jznDomDoc *jdoc,
jznEventSource *evtsrc);
jznDomNode *(*jznDomLoadFromInputOSON)(jznDomDoc *jdoc,
jznosonFile *octbsrc);
/*
** Reader Methods
*/
jznnodetype (*jznDomGetNodeType)(jznDomDoc *jdoc, jznDomNode *node);
jsonerr (*jznDomGetScalarInfo)(jznDomDoc *jdoc, jznDomScalar *nd,
jznScalarVal *val /* OUT */);
jznDomNode *(*jznDomGetRootNode)(jznDomDoc *jdoc);
ub4 (*jznDomGetNumObjField)(jznDomDoc *jdoc, jznDomObject *obj);
jznDomNode *(*jznDomGetFieldVal)(jznDomDoc *jdoc,
jznDomObject *obj,
jznDomObjFieldName *nmkey);
jznDomNode *(*jznDomGetFieldByName)(jznDomDoc *jdoc, jznDomObject *obj,
oratext *nm, ub2 nmlen);
void (*jznDomGetAllFieldNamesAndVals)(jznDomDoc *jdoc, jznDomObject *obj,
jznDomNameValuePair nvps[] /* OUT */);
ub4 (*jznDomGetFieldNamesAndValsBatch)(jznDomDoc *jdoc, jznDomObject *obj,
ub4 startPos, ub4 fetchSz,
jznDomNameValuePair nvps[] /* OUT */);
ub4 (*jznDomGetArraySize)(jznDomDoc *jdoc, jznDomArray *ary);
jznDomNode *(*jznDomGetArrayElem)(jznDomDoc *jdoc,
jznDomArray *ary, ub4 index);
ub4 (*jznDomGetArrayElemBatch)(jznDomDoc *jdoc, jznDomArray *ary,
ub4 startPos, ub4 fetchSz,
jznDomNode *ndary[] /* OUT */);
/*
** Mutator Methods
*/
jsonerr (*jznDomSetRootNode)(jznDomDoc *jdoc, jznDomNode *root);
jsonerr (*jznDomPutFieldValue)(jznDomDoc *jdoc, jznDomObject *obj,
oratext *name, ub2 namelen, jznDomNode *node);
boolean (*jznDomPutItem)(jznDomDoc *jdoc, jznDomArray *arr,
jznDomNode *node, ub4 pos);
boolean (*jznDomAppendItem)(jznDomDoc *jdoc,
jznDomArray *arr, jznDomNode *node);
boolean (*jznDomReplaceItem)(jznDomDoc *jdoc, jznDomArray *arr,
jznDomNode *node, ub4 pos);
boolean (*jznDomDeleteField)(jznDomDoc *jdoc, jznDomObject *obj,
jznDomObjFieldName *nmkey);
jznDomNode *(*jznDomUnlinkField)(jznDomDoc *jdoc, jznDomObject *obj,
jznDomObjFieldName *nmkey);
jsonerr (*jznDomRenameField)(jznDomDoc *jdoc, jznDomObject *obj,
oratext *oldName, ub2 oldNameLen,
oratext *newName, ub2 newNameLen);
boolean (*jznDomDeleteItem)(jznDomDoc *jdoc, jznDomArray *arr, ub4 idx);
jznDomNode *(*jznDomUnlinkItem)(jznDomDoc *jdoc, jznDomArray *arr, ub4 idx);
ub4 (*jznDomDeleteItemBatch)(jznDomDoc *jdoc, jznDomArray *arr,
ub4 start, ub4 deleteSz);
/*
** Constructor Methods (including destroy/free/reset)
*/
jznDomObject *(*jznDomNewObject)(jznDomDoc *jdoc, ub4 sz);
jznDomArray *(*jznDomNewArray)(jznDomDoc *jdoc, ub4 sz);
jznDomScalar *(*jznDomNewScalar)(jznDomDoc *jdoc, jznScalarVal *val);
void (*jznDomDocReset)(jznDomDoc *jdoc);
void (*jznDomDocFree)(jznDomDoc *jdoc);
/*
** Utility Methods
*/
jznEventSource *(*jznDomGetOutputEventSrc)(jznDomDoc *jdoc);
/* Checks whether two given JSON documents are equal.
** One should check the error status by calling JsonDomGetError().
*/
boolean (*jznDomEquals)(jznDomDoc *jdoc1, jznDomNode *nd1,
jznDomDoc *jdoc2, jznDomNode *nd2);
jznDomNode *(*jznDomCopy)(jznDomDoc *srcdoc, jznDomNode *srcnode,
jznDomDoc *destdoc);
jsonerr (*jznDomValidFid)(jznDomDoc *jdoc,
jznDomObjFieldName *fnms, ub2 fnmsn);
jsonerr (*jznDomStoreField)(jznDomDoc *jdoc, oratext *fname, ub4 fnlen,
jznDomObjFieldName *name /* OUT */);
jsonerr (*jznDomPrintNode)(jznDomDoc *jdoc, jznDomNode *node,
jznEventWriter *writer); /* printing method */
void (*jznDomNodeVisitor)(jznDomDoc *jdoc, jznDomNode *node,
JsonDomVisitorFunc func, void *ctx);
/* visitor Func */
/*
** Additional Methods
*/
jznDomScalar *(*jznDomNewScalarVal)(jznDomDoc *jdoc, jznvaltype typ, ...);
boolean (*jznDomDeleteFieldByName)(jznDomDoc *jdoc, jznDomObject *obj,
oratext *name, ub2 namelen);
jznDomNode *(*jznDomUnlinkFieldByName)(jznDomDoc *jdoc, jznDomObject *obj,
oratext *name, ub2 namelen);
boolean (*jznDomFreeNode)(jznDomDoc *jdoc, jznDomNode *node);
jsonerr (*jznDomGetScalarInfoOci)(jznDomDoc *jdoc, jznDomScalar *nd,
jznScalarVal *val /* OUT */,
JsonOCIVal *aux /* OUT */);
oratext *(*jznDomGetError)(jznDomDoc *jdoc,
jsonerr *err /* OUT */, boolean clear);
jznDomNode *(*jznDomReplaceRootNode)(jznDomDoc *jdoc, jznDomNode *root);
jznDomNode *(*jznDomImportFromEventSrc)(jznDomDoc *jdoc,
jznEventSource *evtsrc,
boolean readOneItem);
jznDomNode *(*jznDomGetParent)(jznDomDoc *jdoc, jznDomNode *node);
jsonerr (*jznDomSetNodeProperties)(jznDomDoc *jdoc, jznDomNode *node, ...);
jznDomNode *(*jznDomLoad)(jznDomDoc *jdoc, jsonerr *jerr, ...);
jsonerr (*jznDomSerialize)(jznDomDoc *jdoc, ...);
jznDomNode *(*jznDomGetFieldPos)(jznDomDoc *jdoc, jznDomObject *obj,
oratext *nm, ub2 nmlen, ub4 *pos /* OUT */);
ub4 (*jznDomUnlinkElems)(jznDomDoc *jdoc, jznDomArray *arr,
ub4 pos, ub4 numNodes, jznDomNode **nodes);
ub4 (*jznDomInsertItems)(jznDomDoc *jdoc, jznDomArray *arr,
ub4 pos, ub4 numNodes, jznDomNode **nodes);
// ### Consider dropping this API
jsonerr (*jznDomSortArray)(jznDomDoc *jdoc, jznDomArray *arr, uword flags);
jsonerr (*jznDomCastValue)(jznDomDoc *jdoc, jznDomScalar *snode,
jznExtnType styp);
jznDomScalar *(*jznDomDupScalar)(jznDomDoc *jdoc, jznDomScalar *snode);
jznDomScalar *(*jznDomSetScalar)(jznDomDoc *jdoc, jznDomScalar *snode,
jznScalarVal *val);
jznDomNode *(*jznDomReplaceField)(jznDomDoc *jdoc, jznDomObject *obj,
oratext *nm, ub2 nmlen, jznDomNode *node);
/* reset method with input flag parameter */
void (*jznDomDocResetWF)(jznDomDoc *jdoc, ub4 flag);
jznDomNode * (*jznDomDocDecodeOSONBytesIntoNode)(jznDomDoc *jdoc,
ub1 *oson_byte, ub4 oson_byte_len, jsonerr *ojerr,
jznDomDoc **out_jdoc);
/* Bug37204122: dom api to push down range cmp/in-clause */
/* evaluate range comp filter over array of elements to see if any array
* element of scalar value satisifies the filter
* return TRUE if it is feasible to evaluate the filter, then output result
* is recorded in jznEng_RngCmpInf.
*/
boolean (*jznDomAryFilter)(jznDomDoc *jdoc, jznDomArray *jarray_node,
jznEng_RngCmpInf *cmpI /*IN/OUT */);
/* evaluate range comp filter over the scalar node to see if the scalar
* node of the scalar value satisifies the filter
* return TRUE if it is feasible to evaluate the filter, then output result
* is recorded in jznEng_RngCmpInf.
*/
boolean (*jznDomScalarFilter)(jznDomDoc *jdoc, jznDomScalar *jscalar_node,
jznEng_RngCmpInf *cmpI /*IN/OUT */);
/* evaluate in clause whose value is sorted using pre-sorted merge join as the
* jarray_node of scalar values is sorted. The inclause must be type(strict)
* return TRUE if it is feasible to evaluate the filter, then output result
* is recorded in *rslt.
*/
boolean (*jznDomAryInClauseMrgSort)(jznDomDoc *jdoc, jznDomArray *jarray_node,
jznEng_InClauseInfo *incI, boolean *rslt);
/* evaluate in clause whose value is sorted using binary search, the
* jarray_node of scalar values may NOT be sorted.
* return TRUE if it is feasible to evaluate the filter, then output result
* is recorded in *rslt.
*/
boolean (*jznDomAryInClauseBinSrch)(jznDomDoc *jdoc, jznDomArray *jarray_node,
jznEng_InClauseInfo *incI, boolean *rslt);
/* given a json array, it finds the min or max of the element node using
* json datatype range comparison (DeepDomNodesCompare) semantics
*/
jznDomNode * (*jznDomAryMinMaxJt)(jznDomDoc *jdoc, jznDomArray *jarray_node,
struct jznpFunction *fdesc);
/* given a json array, it applies the aggregation func, such as minNumer(),
* maxNumber(), minTime(), maxTime() that returns a scalar value
* capture via (jtype_o, valptr_o, vallen_o)
* Caller is expected to set valptr_o to point to memory bigger than
* *vallen_o
*/
jsonerr (*jznDomAryAggRetSca)(jznDomDoc *jdoc, jznDomArray *jarray_node,
struct jznpFunction *fdesc, ub4 modeFlags, ub4 maxlen,
jznvaltype* jtype_o, ub1 *valptr_o, ub4 * vallen_o);
/* Bug37488368: JsonDomXXXSimPathRngFilter pred dom api */
/* evaluate simple path <rngCmp> <const/bindvar> via dom API
* return TRUE if it is feasible to evaluate the filter, then output result
* is recorded in *cmpI.
*/
boolean (*jznDomObjSimPathRngFilter)(jznDomDoc *jdoc, jznDomObject *node,
jznEng_SimPathRngCmpInf *simCmpI /*IN/OUT */, ub4 flag);
/* evaluate simple path <rngCmp> <const/bindvar> via dom API
* return TRUE if it is feasible to evaluate the filter, then output result
* is recorded in *cmpI.
*/
boolean (*jznDomArySimPathRngFilter)(jznDomDoc *jdoc, jznDomArray *node,
jznEng_SimPathRngCmpInf *simCmpI /*IN/OUT */, ub4 flag);
/* Bug 38212527 evaluate full text search query from a node recursively
* down to each leaf scalar string node
*/
/* evaluate full text search query for object dom node via dom API
* return TRUE if evaluate is TRUE, then output result
* is recorded in *evinf. FALSE otherwise.
*/
boolean (*jznDomObjTxtContains)(jznDomDoc *jdoc, jznDomObject *node,
jznEng_TxtContInf *evinf /*IN/OUT */, ub4 flag);
/* evaluate full text search query for array dom node via dom API
* return TRUE if evaluate is TRUE, then output result
* is recorded in *evinf. FALSE otherwise.
*/
boolean (*jznDomAryTxtContains)(jznDomDoc *jdoc, jznDomArray *node,
jznEng_TxtContInf *evinf /*IN/OUT */, ub4 flag);
jsonerr (*jznDomSortObject)(jznDomDoc *jdoc,
jznDomObject *obj, uword flags);
jsonerr (*jznDomKeepFields)(jznDomDoc *jdoc, jznDomObject *obj,
jzndomFldKeepS *fields, ub4 numfields);
};
/*---------------------------------------------------------------------------
PUBLIC FUNCTIONS
---------------------------------------------------------------------------*/
/*------------------------- DOM Constructor interfaces ----------------------*/
/*
** NAME:
** JsonDomCreate
**
** PARAMETERS:
** xmlctx *xctx (IN) - XML Context
** jsonerr *jerr (OUT) - JSON Error Code (returned)
**
** RETURNS:
** (JsonDomDoc *) JSON DOM Document Container.
** Returns a NULL on an error condition (e.g. out of memory).
**
** DESCRIPTION:
** Constructor function for JSON DOM Container (JsonDomDoc *). Valid flags
** for JZN_MODE are defined above (See JSON DOM Constructor flags).
**
** NOTES:
** Supported varargs parameters:
** ===================================
** Property Name Expected Type
** ===================================
** JZN_FILE oratext *
** JZN_BUFFER void *
** JZN_BUFFERLEN ub4
** JZN_STREAM orastream *
** JZN_FORMAT oratext * ("JSON" or "OSON")
** JZN_MEMCTX oramemctx *
** JZN_FATAL_HANDLER void (*jznFatalErrHandler)(xmlctx *, oratext *)
** JZN_MODE ub4
**
*/
JsonDomDoc *JsonDomCreate(xmlctx *xctx, jsonerr *jerr, ...);
JsonDomDoc *JsonDomCreateVA(xmlctx *xctx, jsonerr *jerr, va_list va);
/*
** This function returns a concrete implementation class that inherits
** jznDomDoc as the base class, which implements jznDomAPI interface.
**
** Returns a NULL on an error in parameters, or out of memory. Valie flags
** are defined above (See JSON DOM Constructor flags).
**
** ### This is an outdated interface.
** ### The JsonDomCreate() interface has an error return argument.
*/
jznDomDoc *jznCreateDom(xmlctx *xctx, jznDomTyp typ,
jznFatalErrHandler eh, ub4 flag, ...);
jznDomDoc *jznCreateDomVA(xmlctx *xctx, jznDomTyp typ,
jznFatalErrHandler eh, ub4 flag, va_list va);
/*------------------------------ Loader interfaces --------------------------*/
/*
** NAME:
** JsonLoadDom
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - document to load into
** jsonerr jerr (OUT) - output JSON error code
** list (IN) - NULL-terminated list of variable arguments
**
** Supported varargs parameters:
** =======================================================================
** Property Name Expected Type Valid values Notes
** =======================================================================
** JZN_FILE oratext *
** JZN_BUFFER void *
** JZN_BUFFERLEN ub4
** JZN_STREAM orastream *
** JZN_FORMAT oratext * "JSON", "OSON"
** JZN_ENCODING ub2 For "JSON" only
** JZN_ALLOW ub4 Parse flags for
** "JSON" only,
** JZN_RUN_BULK_LOAD
** for "OSON" allowed
**
** RETURNS:
** (jznDomNode *) the root node of the DOM, or NULL on error.
**
** DESCRIPTION:
** Ingests the data supplied in buffer/stream/file as a tree of nodes into
** the target <jdoc>. Sets the new tree of nodes as the root node of <jdoc>,
** and frees any previous root node.
** This is typically used after constructing an empty jznDomDoc to load
** it from a buffer/stream/file. The source data can either be textual
** JSON (JZN_FORMAT = "JSON") or binary OSON (JZN_FORMAT = "OSON").
**
** If you load into a DOM that is not empty, this operation will free
** the old root node and all decendants, plus all orphan nodes.
**
** NOTES:
** If source data is OSON, the target DOM should be JZN_OSON_DOM type.
** If source data is text, the target DOM should be JZN_INMEM_DOM type.
*/
#define JsonLoadDom(jdoc, jerr, ...) \
((jdoc)->mthds_jznDomDoc->jznDomLoad((jdoc), (jerr), __VA_ARGS__))
/*
** NAME:
** JsonDomLoadInput
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - document to load events into
** jznEventSource *evtsrc (IN) - event source (such as the JSON parser)
**
** RETURNS:
** (jznDomNode *) the root node of the DOM, or NULL on error.
**
** DESCRIPTION:
** Ingests the event source as a tree of nodes into the target <jdoc>.
** Sets the new tree of nodes as the root node of <jdoc>, and frees any
** previous root node.
** This is typically used after constructing an empty jznDomDoc to load
** it from a JSON event stream such as the JSON parser or BSON decoder.
**
** NOTES:
** Always check the error code by calling JsonDomGetError before proceeding.
**
** If you load into a DOM that is not empty, this operation will free
** the old root node and all decendants, as per JsonDomSetRoot.
*/
#define JsonDomLoadInput(jdoc, evtsrc) \
((jdoc)->mthds_jznDomDoc->jznDomLoadFromInputEventSrc((jdoc), (evtsrc)))
/*
** NAME:
** JsonDomLoadImage
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - document to map OSON image into
** jznosonFile *octbsrc (IN) - OSON image to load
**
** RETURNS:
** (jznDomNode *) the root node of the DOM, or NULL on error.
**
** DESCRIPTION:
** This method is currently only supported for JZN_OSON_DOM type DOMs.
** After constructing an empty jznDomDoc, it can be mapped to an OSON
** serialized image using this method. The resulting DOM is read-only
** and operations are backed directly by the OSON image.
**
** NOTES:
** Always check the error code by calling JsonDomGetError before proceeding.
**
** ### In the future, this method can also be supported for
** ### JZN_INMEM_DOM type of jznDomDoc to load a mutable in-memory DOM
** ### from persistent OSON storage, necessary to allow updates.
*/
#define JsonDomLoadImage(jdoc, octbsrc) \
((jdoc)->mthds_jznDomDoc->jznDomLoadFromInputOSON((jdoc), (octbsrc)))
/*
** NAME:
** JsonDomImportEvents
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - document to load events into
** jznEventSource *evtsrc (IN) - event source (such as the JSON parser)
**
** RETURNS:
** (jznDomNode *) the new orphan node imported, or NULL on error.
**
** DESCRIPTION:
** Ingests the event source as a tree of nodes into the target <jdoc>.
** Returns the top node of the imported tree, which is an orphan node.
**
** NOTES:
** Always check the error code by calling JsonDomGetError before proceeding.
*/
#define JsonDomImportEvents(jdoc, evtsrc) \
((jdoc)->mthds_jznDomDoc->jznDomImportFromEventSrc((jdoc), (evtsrc), FALSE))
/*
** NAME:
** JsonDomLoadItem
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - document to load events into
** JsonEventSource *evtsrc (IN) - event source (such as the JSON parser)
**
** RETURNS:
** (JsonDomNode *) orphan node representing the item loaded to the DOM
**
** DESCRIPTION:
** Loads the next item from an event source to the target DOM, returning
** it as an orphan node. If the item is a container, all events within
** the container are loaded until the container is closed.
**
** NOTES:
** This is designed to allow part of an in-progress event stream to be
** directed into a DOM, followed by the resumption of consuming the
** event stream by the caller. If an entire event source is put to this
** method, the JZNEV_END event is not consumed.
*/
#define JsonDomLoadItem(jdoc, evtsrc) \
((jdoc)->mthds_jznDomDoc->jznDomImportFromEventSrc((jdoc), (evtsrc), TRUE))
/*------------------------------ Read interfaces ----------------------------*/
/*
** NAME:
** JsonDomGetNodeType
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *node (IN) - node within the DOM
**
** RETURNS:
** (jznnodetype) the type of node (Object, Array, Scalar)
**
** DESCRIPTION:
** Used to test the type of a node. The node may be safely cast to
** the subclass type, e.g. if the return is JZNDOM_SCALAR, the node
** may be cast to (jznDomScalar *).
**
** ERROR HANDLING: It may return JZNDOM_SCALAR in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
**
** Caller must call JsonDomGetError(jdoc) after call of JsonDomGetNodeType()
** to check for error first.
*/
#define JsonDomGetNodeType(jdoc, node) \
((jdoc)->mthds_jznDomDoc->jznDomGetNodeType((jdoc), (node)))
/*
** NAME:
** JsonDomGetScalarInfo
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomScalar *nd (IN) - scalar node to get information about
** jznScalarVal *val (OUT) - returns information about the scalar
**
** RETURNS:
** (jsonerr) error code, JZNERR_OK (0) for no error
**
** DESCRIPTION:
** Used to retrieve a scalar value, which is returned in the val structure
** (which must be supplied by the caller, often a pointer to a local
** variable in the calling code). The return structure is a discriminated
** union. The value's scalar subtype (e.g. JZNVAL_NUMBER) is available
** as the first member, and the scalar's actual value can be read from
** the appropriate union member.
**
** NOTES:
** Variable-length types such as strings, JSON numbers, and Oracle
** internal data types, are returned as pointers to the underlying
** DOM data image or node. Small fixed-length types such as signed
** integers and doubles are returned directly in the union.
**
** ERROR HANDLING: It may return error code in case of error with errrcode
** obtaineable via JsonDomGetError(srcdoc)
*/
#define JsonDomGetScalarInfo(jdoc, nd, val) \
((jdoc)->mthds_jznDomDoc->jznDomGetScalarInfo((jdoc), (nd), (val)))
/*
** NAME:
** JsonDomGetScalarInfoOCI
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomScalar *nd (IN) - scalar node to get information about
** jznScalarVal *val (OUT) - returns information about the scalar
**
** RETURNS:
** (jsonerr) error code, JZNERR_OK (0) for no error
**
** DESCRIPTION:
** Used to retrieve a scalar value, which is returned in the val structure
** (which must be supplied by the caller, often a pointer to a local
** variable in the calling code). The return structure is a discriminated
** union. The value's scalar subtype (e.g. JZNVAL_NUMBER) is available
** as the first member, and the scalar's actual value can be read from
** the appropriate union member.
**
** NOTES:
** Oracle native types are unpickled and returned in structured form in
** auxiliary union of type JsonOCIVal*.
**
** ERROR HANDLING: It may return error code in case of error with errrcode
** obtaineable via JsonDomGetError(srcdoc)
*/
#define JsonDomGetScalarInfoOci(jdoc, nd, val, aux) \
((jdoc)->mthds_jznDomDoc->jznDomGetScalarInfoOci((jdoc), (nd), (val), (aux)))
/*
** NAME:
** JsonDomGetRoot
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (jznDomNode *) root node for the DOM (or NULL if none is set)
**
** DESCRIPTION:
** Returns the root node of a DOM, which is one of the three types of
** nodes (although rare, a scalar with no children is a valid JSON
** document per the RFC).
**
** NOTES:
** So-called "orphan" nodes can't be accessed by descending the tree
** starting from the root.
**
** ERROR HANDLING: It may return error code in case of error with errrcode
** obtaineable via JsonDomGetError(srcdoc)
*/
#define JsonDomGetRoot(jdoc) \
((jdoc)->mthds_jznDomDoc->jznDomGetRootNode((jdoc)))
/*
** NAME:
** JsonDomGetNumFields
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - Object node within the DOM
**
** RETURNS:
** (ub4) a count of the number of fields within this object.
**
** DESCRIPTION:
** Returns the number of fields within the object.
**
** NOTES:
** Duplicate field names are not allowed in most DOMs.
**
** ERROR HANDLING: It may return 0 in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetNumFields(jdoc, obj) \
((jdoc)->mthds_jznDomDoc->jznDomGetNumObjField((jdoc), (obj)))
/*
** NAME:
** JsonDomGetFieldValue
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - Object node within the DOM
** jznDomObjFieldName *nmkey (IN) - Field key structure
**
** RETURNS:
** (jznDomNode *) the value of the field (may be any JSON node type)
**
** DESCRIPTION:
** Returns the value of a field within the object, retrieving it by matching
** the key structure. The key structure contains a pointer to the field
** name and the length of the field name, as well as optional hash and id
** codes that may speed retrieval when using an OSON based DOM.
** Returns NULL if a field matching the key cannot be found.
**
** NOTES:
** For JZNOCT implemented DOM, nm->hashid_jznDomObjFieldName field
** must be set to quickly identify the field with that name. Set it
** to 0 if it's unknown.
** Also, nm->id_jznDomObjFieldName must be 0, unless the <nmkey>
** structure was initialized specifically for the current document.
** See JsonDomCheckFieldKeys().
**
** ERROR HANDLING: It may return NULL in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetFieldValue(jdoc, obj, nmkey) \
((jdoc)->mthds_jznDomDoc->jznDomGetFieldVal((jdoc), (obj), (nmkey)))
/*
** NAME:
** JsonDomGetFieldByName
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - Object node within the DOM
** oratext *fname (IN) - Field name string
** ub2 fnlen (IN) - Length of field name string in bytes
**
** RETURNS:
** (jznDomNode *) the value of the field (may be any JSON node type)
**
** DESCRIPTION:
** Returns the value of a field within the object, retrieving it by matching
** the name string and length.
** Returns NULL if a matching field cannot be found.
**
** NOTES:
** A convenience interface that is otherwise identical in function
** to JsonDomGetFieldValue.
**
** ERROR HANDLING: It may return NULL in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetFieldByName(jdoc, obj, fname, fnlen) \
((jdoc)->mthds_jznDomDoc->jznDomGetFieldByName((jdoc),(obj),(fname),(fnlen)))
/*
** NAME:
** JsonDomGetAllFields
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - Object node within the DOM
** jznDomNameValuePair nvps[] (OUT) - Returns all field name/value pairs
**
** RETURNS:
** (void)
**
** DESCRIPTION:
** Returns all fields for an object by populating an array of name/value
** pairs. The name portion is a jznDomObjFieldName (the key structure
** as used in JsonDomGetFieldValue). The value portion is simply a node
** pointer.
**
** NOTES:
** The array is assumed to be large enough to hold the result. The caller
** takes responsibility for this, calling JsonDomGetNumFields and if
** necessary allocating an array of sufficient size.
**
** ERROR HANDLING: It may return in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetAllFields(jdoc, obj, nvps) \
((jdoc)->mthds_jznDomDoc->jznDomGetAllFieldNamesAndVals((jdoc), (obj), \
(nvps)))
/*
** NAME:
** JsonDomGetFields
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - Object node within the DOM
** ub4 startPos (IN) - Starting position (0-based)
** ub4 fetchSz (IN) - Number of fields to retrieve
** jznDomNameValuePair nvps[] (OUT) - Returns field name/value pairs
**
** RETURNS:
** (ub4) number of fields returned in the output name/value array
**
** DESCRIPTION:
** Returns a set of fields in a batch interface. This allows a caller
** to use a fixed-sized array to iterate over the fields, while still
** retrieving them in bulk. The fields are returned in the same output
** format as JsonDomGetAllFields.
**
** NOTES:
** The first field is at start position 0. The iteration is backed directly
** by the DOM object, so this interface won't work properly if the object
** undergoes modification during the iteration.
**
** ERROR HANDLING: It may return 0 in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetFields(jdoc, obj, startPos, fetchSz, nvps) \
((jdoc)->mthds_jznDomDoc->jznDomGetFieldNamesAndValsBatch((jdoc), (obj), \
(startPos), (fetchSz), (nvps)))
/*
** NAME:
** JsonDomGetArraySize
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *ary (IN) - Array node within the DOM
**
** RETURNS:
** (ub4) a count of the number of elements within this array.
**
** DESCRIPTION:
** Returns the number of elements within the array.
**
** NOTES:
** Duplicate field names are not allowed in most DOMs.
**
** ERROR HANDLING: It may return 0 in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetArraySize(jdoc, ary) \
((jdoc)->mthds_jznDomDoc->jznDomGetArraySize((jdoc), (ary)))
/*
** NAME:
** JsonDomGetArrayElement
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *ary (IN) - Object node within the DOM
** ub4 index (IN) - Position within the array (0-based)
**
** RETURNS:
** (jznDomNode *) the value of the array item (may be any JSON node type)
**
** DESCRIPTION:
** Returns the node at a specific array index, starting from position 0.
** if the index is out of bounds, a NULL is returned.
**
** NOTES:
** An error code may be set if the index is out of bounds. The caller
** should check and if necessary clear the error. (For example, if a
** caller doesn't bother using JsonDomGetArraySize and iterates the array
** while relying on the NULL to signal end-of-iteration.)
**
** ERROR HANDLING: It may return NULL in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetArrayElement(jdoc, ary, index) \
((jdoc)->mthds_jznDomDoc->jznDomGetArrayElem((jdoc), (ary), (index)))
/*
** NAME:
** JsonDomGetElements
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *ary (IN) - Array node within the DOM
** ub4 startPos (IN) - Starting position (0-based)
** ub4 fetchSz (IN) - Number of fields to retrieve
** jznDomNode *ndary[] (OUT) - Returns nodes from the array
**
** RETURNS:
** (ub4) number of elements returned in the output node array
**
** DESCRIPTION:
** Returns a set of elements in a batch interface. This allows a caller
** to use a fixed-sized array to iterate over the elements, while still
** retrieving them in bulk.
**
** NOTES:
** The first element at start position 0. The iteration is backed directly
** by the DOM array, so this interface won't work properly if the array
** undergoes modification during the iteration.
**
** ERROR HANDLING: It may return 0 in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetElements(jdoc, ary, startPos, fetchSz, ndary) \
((jdoc)->mthds_jznDomDoc->jznDomGetArrayElemBatch((jdoc), (ary), \
(startPos), (fetchSz), (ndary)))
/*---------------------------- Mutator interfaces ---------------------------*/
/*
** NAME:
** JsonDomSetRoot
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *root (IN) - orphan node within the DOM
**
** RETURNS:
** (jsonerr)
**
** DESCRIPTION:
** Sets the specified node as the root. The new node may be a NULL.
** The new root must be an orphan node - that is, it cannot be a node
** that exists within the tree descending from the old root, if any.
** Orphan nodes are created by constructors, or by copying node(s)
** from another DOM document, or by unlinking them from the DOM tree.
**
** NOTES:
** The old root and all descendants is freed.
*/
#define JsonDomSetRoot(jdoc, root) \
((jdoc)->mthds_jznDomDoc->jznDomSetRootNode((jdoc), (root)))
/*
** NAME:
** JsonDomReplaceRoot
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *root (IN) - orphan node within the DOM
**
** RETURNS:
** (jznDomNode *)
**
** DESCRIPTION:
** Sets the specified node as the root. The new node may be a NULL.
** The new root must be an orphan node - that is, it cannot be a node
** that exists within the tree descending from the old root, if any.
** Orphan nodes are created by constructors, or by copying node(s)
** from another DOM document, or by unlinking them from the DOM tree.
**
** NOTES:
** Returns the old root node, if any, after unlinking it.
*/
#define JsonDomReplaceRoot(jdoc, root) \
((jdoc)->mthds_jznDomDoc->jznDomReplaceRootNode((jdoc), (root)))
/*
** NAME:
** JsonDomGetParent
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *node (IN) - node within the DOM
**
** RETURNS:
** (jznDomNode *)
**
** DESCRIPTION:
** Get the parent node of a specified node. This returns NULL for an
** orphan node or on any error. The parent may be unavailable for some
** DOMs, for example on a binary image, or if the node has multiple
** parents.
**
** NOTES:
** If an error is possible, the caller needs to call JsonDomGetError.
** on a NULL return. Possible errors:
** - node was previous freed
** - node has multiple parents
** - method is unimplemented in this DOM
*/
#define JsonDomGetParent(jdoc, node) \
((jdoc)->mthds_jznDomDoc->jznDomGetParent((jdoc), (node)))
#define JZNDOM_NODE_REF "reference"
/*
** NAME:
** JsonDomRefNode
** JsonDomDerefNode
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *node (IN) - node within the DOM
**
** RETURNS:
** (jsonerr)
**
** DESCRIPTION:
** Mark a node as externally referenced or dereferenced. A node marked
** as referenced is immune from free operations. A node not marked as
** referenced may be freed if it has no outstanding parent node in the DOM.
**
** NOTES:
** May return an error if the underlying DOM can't support the property.
** This API is intended only for internal implementations such as
** the PL/SQL DOM, where it's necessary to manage external references
** from the host language via this mechanism.
*/
#define JsonDomRefNode(jdoc, node) \
((jdoc)->mthds_jznDomDoc->jznDomSetNodeProperties((jdoc), (node), \
JZNDOM_NODE_REF, TRUE, NULL)
#define JsonDomDerefNode(jdoc, node) \
((jdoc)->mthds_jznDomDoc->jznDomSetNodeProperties((jdoc), (node), \
JZNDOM_NODE_REF, FALSE, NULL)
/*
** NAME:
** JsonDomSetField
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - object within the DOM
** oratext *name (IN) - string with field name to create/replace
** ub2 namelen (IN) - length of field name string
** jznDomNode *node (IN) - orphan node to set as field value
**
** RETURNS:
** (jsonerr) error code, JZNERR_OK (0) for no error
**
** DESCRIPTION:
** Sets the value of the specified field to the specified orphan node.
** The field is created if it doesn't exist, otherwise the old value is
** replaced.
**
** NOTES:
** The old field value, if any, is freed along with all descendants.
*/
#define JsonDomSetField(jdoc, obj, name, namelen, node) \
((jdoc)->mthds_jznDomDoc->jznDomPutFieldValue((jdoc), (obj), \
(name), (namelen), (node)))
/*
** NAME:
** JsonDomReplaceField
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - object within the DOM
** oratext *name (IN) - string with field name to replace
** ub2 namelen (IN) - length of field name string
** jznDomNode *node (IN) - orphan node to set as field value
**
** RETURNS:
** (jznDomNode *) old field value
**
** DESCRIPTION:
** Sets the value of the specified field to the specified orphan node.
** Unlinks and returns the old value. Returns NULL if none.
**
** NOTES:
** An error also returns NULL - the caller must check JsonDomGetError.
**
** This is equivalent to UnlinkField followed by SetField. However,
** that combination may cause the field's "position" to change when
** serialized, while this function will not. A similar problem doesn't
** exist for arrays, where UnlinkElement followed by AddElement is
** always positional.
*/
#define JsonDomReplaceField(jdoc, obj, name, namelen, node) \
((jdoc)->mthds_jznDomDoc->jznDomReplaceField((jdoc), (obj), \
(name), (namelen), (node)))
/*
** NAME:
** JsonDomAddElement
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** jznDomNode *node (IN) - orphan node to set as element value
** ub4 pos (IN) - position within the array (0-based)
**
** RETURNS:
** (boolean) TRUE on success, FALSE on error
**
** DESCRIPTION:
** Inserts an orphan node as a new element in an array. The insertion
** is done at the position specified, with 0 meaning that the inserted
** node becomes the first element in the array, and all other elements
** are shifted, increasing the size of the array by 1 element. The
** array size bound may be specified as a means of appending a node
** to the end of the array.
**
** ERROR HANDLING: It may return FALSE in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomAddElement(jdoc, arr, node, pos) \
((jdoc)->mthds_jznDomDoc->jznDomPutItem((jdoc), (arr), (node), (pos)))
/*
** NAME:
** JsonDomAppendElement
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** jznDomNode *node (IN) - orphan node to set as element value
**
** RETURNS:
** (boolean) TRUE on success, FALSE on error
**
** DESCRIPTION:
** Append an orphan node as a new element in an array, at the last
** position within the array. Equivalent to calling JsonDomAddElement
** and giving the array size as the insertion position.
**
** ERROR HANDLING: It may return FALSE in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomAppendElement(jdoc, arr, node) \
((jdoc)->mthds_jznDomDoc->jznDomAppendItem((jdoc), (arr), (node)))
/*
** NAME:
** JsonDomReplaceElement
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** jznDomNode *node (IN) - orphan node to set as element value
** ub4 pos (IN) - position within the array (0-based)
**
** RETURNS:
** (boolean) TRUE on success, FALSE on error
**
** DESCRIPTION:
** Sets the value of an array element to the specified orphan node.
** The position given must be within the array bounds.
**
** NOTES:
** The old element node is freed along with all descendants.
**
** ERROR HANDLING: It may return FALSE in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomReplaceElement(jdoc, arr, node, pos) \
((jdoc)->mthds_jznDomDoc->jznDomReplaceItem((jdoc), (arr), (node), (pos)))
/*
** NAME:
** JsonDomDeleteField
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - object within the DOM
** jznDomObjFieldName *nmkey (IN) - Field key structure
**
** RETURNS:
** (boolean) TRUE on success, FALSE if the field was not found
**
** DESCRIPTION:
** Deletes a field matching the specified field name. The name is
** conveyed using a key structure (see JsonDomGetFieldValue).
** If the field is not found, nothing it done.
**
** NOTES:
** The old field value, if any, is freed along with all descendants.
**
** ERROR HANDLING: It may return FALSE in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomDeleteField(jdoc, obj, nmkey) \
((jdoc)->mthds_jznDomDoc->jznDomDeleteField((jdoc), (obj), (nmkey)))
/*
** NAME:
** JsonDomDeleteFieldByName
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - object within the DOM
** oratext *fname (IN) - Field name string
** ub2 fnlen (IN) - Length of field name string in bytes
**
** RETURNS:
** (boolean) TRUE on success, FALSE if the field was not found
**
** DESCRIPTION:
** Deletes a field matching the specified field name.
** If the field is not found, nothing it done.
**
** NOTES:
** The old field value, if any, is freed along with all descendants.
**
** ERROR HANDLING: It may return FALSE in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomDeleteFieldByName(jdoc, obj, fname, fnlen) \
((jdoc)->mthds_jznDomDoc->jznDomDeleteFieldByName((jdoc), (obj), \
(fname), (fnlen)))
/*
** NAME:
** JsonDomUnlinkField
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - object within the DOM
** jznDomObjFieldName *nmkey (IN) - Field key structure
**
** RETURNS:
** (jznDomNode *) the field value node (if any)
**
** DESCRIPTION:
** Unlinks a field value from the DOM, returning the field value node.
** The returned node becomes an "orphan", meaning that it is no longer
** reachable by traversing the DOM from the root node.
**
** NOTES:
** If the field is not found, a NULL is returned.
*/
#define JsonDomUnlinkField(jdoc, obj, nmkey) \
((jdoc)->mthds_jznDomDoc->jznDomUnlinkField((jdoc), (obj), (nmkey)))
/*
** NAME:
** JsonDomUnlinkFieldByName
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - object within the DOM
** oratext *fname (IN) - Field name string
** ub2 fnlen (IN) - Length of field name string in bytes
**
** RETURNS:
** (jznDomNode *) the field value node (if any)
**
** DESCRIPTION:
** Unlinks a field value from the DOM, returning the field value node.
** The returned node becomes an "orphan", meaning that it is no longer
** reachable by traversing the DOM from the root node.
**
** NOTES:
** If the field is not found, a NULL is returned.
*/
#define JsonDomUnlinkFieldByName(jdoc, obj, fname, fnlen) \
((jdoc)->mthds_jznDomDoc->jznDomUnlinkFieldByName((jdoc), (obj), \
(fname), (fnlen)))
/*
** NAME:
** JsonDomRenameField
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - object within the DOM
** oratext *oldName (IN) - old field to be renamed
** oratext *oldNameLen (IN) - length of old field name
** oratext *newName (IN) - new name for field
** oratext *newNameLen (IN) - length of new field name
**
** RETURNS:
** jsonerr
**
** DESCRIPTION:
** Unlinks a field value from the DOM and re-attached it with a new name.
** If the field is not found, or if the new name is already present,
** an error is returned.
**
** ERROR HANDLING: It may return errcode in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomRenameField(jdoc, obj, on, onl, nn, nnl) \
((jdoc)->mthds_jznDomDoc->jznDomRenameField((jdoc), (obj), \
(on), (onl), (nn), (nnl)))
/*
** NAME:
** JsonDomDeleteElement
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** ub4 pos (IN) - position within the array (0-based)
**
** RETURNS:
** (boolean) TRUE on success, FALSE on error
**
** DESCRIPTION:
** Remove an element at a specified position within the array, contracting
** the array by 1 element.
** The position given must be within the array bounds.
**
** NOTES:
** The removed element node is freed along with all descendants.
**
** ERROR HANDLING: It may return FALSE in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomDeleteElement(jdoc, arr, idx)\
((jdoc)->mthds_jznDomDoc->jznDomDeleteItem((jdoc), (arr), (idx)))
/*
** NAME:
** JsonDomUnlinkElement
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** ub4 pos (IN) - position within the array (0-based)
**
** RETURNS:
** (jznDomNode *) the element value node, or NULL if out of bounds
**
** DESCRIPTION:
** Remove an element at a specified position within the array, contracting
** the array by 1 element. The removed element becomes an "orphan" and is
** returned.
** The position given must be within the array bounds.
**
** ERROR HANDLING: It may return NULL in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomUnlinkElement(jdoc, arr, idx)\
((jdoc)->mthds_jznDomDoc->jznDomUnlinkItem((jdoc), (arr), (idx)))
/*
** NAME:
** JsonDomDeleteElementRange
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** ub4 start (IN) - position within the array (0-based)
** ub4 deleteSz (IN) - number of elements to delete
**
** RETURNS:
** (ub4) number of elements removed from the array.
**
** DESCRIPTION:
** Removes a range of elements from an array, contracting it by the
** number of elements removed. The start position given should be within
** the array bounds, and refers to the first position to be removed
** (i.e. a 0 implies that the first element will be removed). The
** deleteSz may be larger than the size of the array following the
** start position, in which case the array is truncated at the start
** position. The number of elements actually removed will be returned
** (this may be 0).
**
** NOTES:
** The removed element nodes are freed along with all descendants.
*/
#define JsonDomDeleteElementRange(jdoc, arr, start, deleteSz) \
((jdoc)->mthds_jznDomDoc->jznDomDeleteItemBatch((jdoc), (arr), \
(start), (deleteSz)))
/*
** NAME:
** JsonDomUnlinkElements
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** ub4 pos (IN) - position within the array (0-based)
** ub4 numNodes (IN) - number of elements to unlink
** jznDomNode **nodes (OUT) - nodes removed (optional)
**
** RETURNS:
** (ub4) number of elements removed from the array.
**
** DESCRIPTION:
** Removes a range of elements from an array, contracting it by the
** number of elements removed. The start position given should be within
** the array bounds, and refers to the first position to be removed
** (i.e. a 0 implies that the first element will be removed). The
** deleteSz may be larger than the size of the array following the
** start position, in which case the array is truncated at the start
** position. The number of elements actually removed will be returned
** (this may be 0).
**
** NOTES:
** Elements removed become "orphans". If the optional nodes array is
** given, it's expected to be large enough to hold the unlinked nodes.
*/
#define JsonDomUnlinkElements(jdoc, arr, pos, numNodes, nodes) \
((jdoc)->mthds_jznDomDoc->jznDomUnlinkElems((jdoc), (arr), (pos), \
(numNodes), (nodes)))
/*
** NAME:
** JsonDomInsertElements
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *arr (IN) - array within the DOM
** ub4 pos (IN) - position within the array (0-based)
** ub4 numNodes (IN) - number of elements to insert
** jznDomNode **nodes (IN) - nodes to be inserted
**
** RETURNS:
** (ub4) number of nodes inserted
**
** DESCRIPTION:
** Inserts a set of orphan nodes as new elements in an array. The insertion
** is done at the position specified, with 0 meaning that the inserted
** nodes becomes the first N elements in the array, and all other elements
** are shifted, increasing the size of the array by N element. The
** array size bound may be specified as the insert position as a means
** of appending nodes to the end of the array. The elements are inserted
** in order, effectively advancing the insert position by 1 each time.
**
** ERROR HANDLING: It may return a number less than the requested node count.
** with errrcode obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomInsertElements(jdoc, arr, pos, numNodes, nodes) \
((jdoc)->mthds_jznDomDoc->jznDomInsertItems((jdoc), (arr), (pos), \
(numNodes), (nodes)))
/*------------------------ Constructor interfaces ---------------------------*/
/*
** NAME:
** JsonDomCreateObject
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (jznDomObject *) new orphaned DOM object node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM object node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
*/
#define JsonDomCreateObject(jdoc) \
((jdoc)->mthds_jznDomDoc->jznDomNewObject((jdoc), 0))
/*
** NAME:
** JsonDomCreateObjectWithSize
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** ub4 sz (IN) - initial number of field elements in the obj
** if 0, default size is used. Passing non zero
** size helps to optimize internal memory allocation
** and avoid re-sizing if we know the number of
** field elements it needs in advance.
**
**
** RETURNS:
** (jznDomObject *) new orphaned DOM object node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM object node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
*/
#define JsonDomCreateObjectWithSize(jdoc, sz) \
((jdoc)->mthds_jznDomDoc->jznDomNewObject((jdoc), (sz)))
/*
** NAME:
** JsonDomCreateArray
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (jznDomArray *) new orphaned DOM array node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM array node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
*/
#define JsonDomCreateArray(jdoc) \
((jdoc)->mthds_jznDomDoc->jznDomNewArray((jdoc), 0))
/*
** NAME:
** JsonDomCreateArrayWithSize
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** ub4 sz (IN) - initial number of chd elements in the array
** if 0, default size is used. Passing non zero
** size helps to optimize internal memory allocation
** and avoid re-sizing if we know the number of
** field elements it needs in advance.
**
** RETURNS:
** (jznDomArray *) new orphaned DOM array node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM array node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
*/
#define JsonDomCreateArrayWithSize(jdoc, sz) \
((jdoc)->mthds_jznDomDoc->jznDomNewArray((jdoc), (sz)))
/*
** NAME:
** JsonDomCreateScalar
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznScalarVal *val (IN) - Scalar value structure
**
** RETURNS:
** (jznDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value conveyed by the discriminated union val.
** For variable-length values (such as strings), the bytes representing
** the value are copied into the DOM's memory space.
*/
#define JsonDomCreateScalar(jdoc, val) \
((jdoc)->mthds_jznDomDoc->jznDomNewScalar((jdoc), (val)))
/*
** NAME:
** JsonDomCopyScalar
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomScalar *snode (IN) - Existing scalar node
**
** RETURNS:
** (jznDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node as a duplicate of an existing scalar
** node. The new node is an "orphan" not attached to the DOM tree that
** descends from the root node. If possible, the scalar data value is
** shared in a read-only fashion between the nodes, allowing logical
** copies to be made of nodes with long out-of-line data values such
** as strings or binaries.
*/
#define JsonDomCopyScalar(jdoc, snode) \
((jdoc)->mthds_jznDomDoc->jznDomDupScalar((jdoc), (snode)))
/*
** NAME:
** JsonDomSetScalar
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomScalar *snode (IN) - Existing scalar node
** jznScalarVal *val (IN) - scalar value to set
**
** RETURNS:
** (jznDomScalar *) updated orphan DOM scalar node.
** NULL if the feature is not supported.
**
** DESCRIPTION:
** Updates an existing DOM scalar node to set the value to a new
** scalar value. This is done without deep-copying the value, so
** the memory must remain stable while the node is in use.
** Pass a NULL for <val> to clear the scalar node to its original state.
** if <snode> is NULL, a suitable "temp" scalar is created and then
** the value is pushed to it.
**
** NOTES:
** This is a dangerous API that must be used with caution.
** It's designed for internal use to carry transient values to
** APIs that require a node.
*/
#define JsonDomSetScalar(jdoc, snode, val) \
((jdoc)->mthds_jznDomDoc->jznDomSetScalar((jdoc), (snode), (val)))
/*
** NAME:
** JsonDomCreateScalarVal
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** jznvaltyp vtyp (IN) - Scalar value type
** va_list values (IN) - Scalar value
** (paired with length if applicable)
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value conveyed by the varargs list.
** For variable-length values (such as strings), the bytes representing
** the value are copied into the DOM's memory space.
*/
#define JsonDomCreateScalarVal(jdoc, vtyp, ...) \
((jdoc)->mthds_jznDomDoc->jznDomNewScalarVal((jdoc), (vtyp), __VA_ARGS__))
/*
** NAME:
** JsonDomCreateString
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** oratext *sval (IN) - String pointer
** ub4 slen (IN) - String size in bytes
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateString(jdoc, sval, slen) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_STRING, (sval), (slen)))
/*
** NAME:
** JsonDomCreateBinary
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub1 *bval (IN) - Binary buffer pointer
** ub4 blen (IN) - Buffer size in bytes
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateBinary(jdoc, bval, blen) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_BINARY, (bval), (blen)))
/*
** NAME:
** JsonDomCreateVector
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub1 *bval (IN) - Vector Binary buffer pointer
** ub4 blen (IN) - Vector Buffer size in bytes
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateVector(jdoc, bval, blen) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_VECTOR, (bval), (blen)))
/*
** NAME:
** JsonDomCreateInteger
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** sb4 ival (IN) - Integer value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateInteger(jdoc, ival) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_SINT, (ival)))
/*
** NAME:
** JsonDomCreateUnsignedInteger
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub4 ival (IN) - Integer value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateUnsignedInteger(jdoc, ival) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_UINT, (ival)))
/*
** NAME:
** JsonDomCreateLong
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** sb8 ival (IN) - Long value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateLong(jdoc, lnval) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_SLONG, (lnval)))
/*
** NAME:
** JsonDomCreateUnsignedLong
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub8 ival (IN) - Long value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateUnsignedLong(jdoc, lnval) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_ULONG, (lnval)))
/*
** NAME:
** JsonDomCreateFloat
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** float fval (IN) - Float value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateFloat(jdoc, fval) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_FLOAT, (fval)))
/*
** NAME:
** JsonDomCreateDouble
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** double dval (IN) - Double value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateDouble(jdoc, dval) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DOUBLE, (dval)))
/*
** NAME:
** JsonDomCreateShort
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** short ival (IN) - 16-bit signed integer value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateShort(jdoc, ival) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_SHORT, (ival)))
/*
** NAME:
** JsonDomCreateUShort
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** short uval (IN) - 16-bit unsigned integer value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
#define JsonDomCreateUshort(jdoc, ival) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_USHORT, (ival)))
// ### To-do: CreateFloat16, CreateBFloat16 - but how?
/*
** NAME:
** JsonDomCreateTrue
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the TRUE.
*/
#define JsonDomCreateTrue(jdoc) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_TRUE, NULL))
/*
** NAME:
** JsonDomCreateFalse
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the FALSE.
*/
#define JsonDomCreateFalse(jdoc) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_FALSE, NULL))
/*
** NAME:
** JsonDomCreateBoolean
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** boolean bval (IN) - TRUE or FALSE
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the boolean value passed.
*/
#define JsonDomCreateBoolean(jdoc, bval) \
((bval) ? JsonDomCreateTrue(jdoc) : JsonDomCreateFalse(jdoc))
/*
** NAME:
** JsonDomCreateNull
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to a JSON null.
*/
#define JsonDomCreateNull(jdoc) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_NULL, NULL))
/*
** NAME:
** JsonDomCreateNumber
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub1 *nval (IN) - Pointer to byte array
** ub4 nlen (IN) - Buffer size in bytes
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateNumber(jdoc, nval, nlen) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_ORA_NUMBER, (nval), (nlen)))
/*
** NAME:
** JsonDomCreateDate
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub1 *dval (IN) - Pointer to byte array
** ub4 dlen (IN) - Buffer size in bytes
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateDate(jdoc, dval, dlen) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_ORA_DATE, (dval), (dlen)))
/*
** NAME:
** JsonDomCreateTimestamp
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub1 *tsval (IN) - Pointer to byte array
** ub4 tslen (IN) - Buffer size in bytes
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateTimestamp(jdoc, tsval, tslen) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_ORA_TIMESTAMP, (tsval), (tslen)))
/*
** NAME:
** JsonDomCreateId
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** ub1 *bval (IN) - Binary buffer pointer
** ub4 blen (IN) - Buffer size in bytes
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateId(jdoc, bval, blen) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_ID, (bval), (blen)))
/*
** NAME:
** JsonDomNumberFromLong
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** sb8 ival (IN) - Long value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
JsonDomScalar *JsonDomNumberFromLong(JsonDomDoc *jdoc, sb8 ival);
/*
** NAME:
** JsonDomNumberFromDouble
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** double dval (IN) - Double value
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
*/
JsonDomScalar *JsonDomNumberFromDouble(JsonDomDoc *jdoc, double dval);
/*
** NAME:
** JsonDomFloat16FromFloat
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** float fval (IN) - 32-bit float
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node, IEEE 754 16-bit float
** NULL on an out of memory condition or if the input cannot be converted
** due to the smaller scale of the 16-bit float.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
JsonDomScalar *JsonDomFloat16FromFloat(JsonDomDoc *jdoc, float fval);
/*
** NAME:
** JsonDomBFloat16FromFloat
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** float fval (IN) - 32-bit float
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node, Google 16-bit float
** NULL on an out of memory condition or if the input cannot be converted.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
JsonDomScalar *JsonDomBFloat16FromFloat(JsonDomDoc *jdoc, float fval);
/*
** NAME:
** JsonDomCreateStream
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** orastream *strm (IN) - Read input stream
** is_bin is_bin (IN) - TRUE
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition, or on a stream reading error;
** call JsonDomGetError() if this occurs.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value read from the input read stream.
** The stream bytes are read and copied into the DOM's memory space.
*/
#define JsonDomCreateStream(jdoc, strm, is_bin) \
((is_bin) ? (JsonDomCreateScalarVal((jdoc), JZNVAL_BIN_STREAM, (strm))) : \
(JsonDomCreateScalarVal((jdoc), JZNVAL_CHR_STREAM, (strm))))
/*
** NAME:
** JsonDomCreateOCIString
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** OCIString *ostr (IN) - OCIString instance
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateOCIString(jdoc, ostr) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_OCI_STRING, (ostr)))
/*
** NAME:
** JsonDomCreateOCIRaw
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** OCIRaw *oraw (IN) - OCIRaw instance
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateOCIRaw(jdoc, oraw) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_OCI_RAW, (oraw)))
/*
** NAME:
** JsonDomCreateOCINumber
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** OCINumber *onum (IN) - OCINumber instance
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateOCINumber(jdoc, onum) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_OCI_NUMBER, (onum)))
/*
** NAME:
** JsonDomCreateOCIDate
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** OCIDate *odate (IN) - OCIDate instance
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateOCIDate(jdoc, odate) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_OCI_DATE, (odate)))
/*
** NAME:
** JsonDomCreateOCIDateTime
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** OCIDateTime *otime (IN) - OCIDateTime instance
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateOCIDateTime(jdoc, otime) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_OCI_DATETIME, (otime)))
/*
** NAME:
** JsonDomCreateOCIInteval
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** OCIInterval *oint (IN) - OCIInterval instance
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is set to the value passed in as parameter.
** The bytes representing the value are copied into the DOM's memory space.
*/
#define JsonDomCreateOCIInterval(jdoc, oint) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_OCI_INTERVAL, (oint)))
/*
** NAME:
** JsonDomCreateDecimal
** JsonDomCreateDecimalString
** JsonDomCreateDecimalInt
** JsonDomCreateDecimalLong
** JsonDomCreateDecimalFloat
** JsonDomCreateDecimalDouble
** JsonDomCreateDecimalUnsigned
** JsonDomCreateDecimalUL
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** <various> x (IN) - Numeric input
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is an in-line IEEE Decimal 128. The input may be any of
** the following: signed int, unsigned int, signed long, unsigned long,
** float, double, or OCI Number.
*/
#define JsonDomCreateDecimal(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_OCI_NUMBER, (x)))
#define JsonDomCreateDecimalString(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_STRING, (x)))
#define JsonDomCreateDecimalInt(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_SINT, (x)))
#define JsonDomCreateDecimalLong(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_SLONG, (x)))
#define JsonDomCreateDecimalUnsigned(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_UINT, (x)))
#define JsonDomCreateDecimalUL(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_ULONG, (x)))
#define JsonDomCreateDecimalFloat(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_FLOAT, (x)))
#define JsonDomCreateDecimalDouble(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_DECIMAL, JZNVAL_DOUBLE, (x)))
/*
** NAME:
** JsonDomCreateDateTime
** JsonDomCreateDateTimeMillis
** JsonDomCreateDateTimeString
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** <various> x (IN) - OCIDateTime instance, or
** milliseconds since 1970-01-01, or
** ISO string (null-terminated)
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is an in-line date/time structure.
*/
#define JsonDomCreateDateTime(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_TSTAMP, JZNVAL_OCI_DATETIME, (x)))
#define JsonDomCreateDateTimeMillis(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_TSTAMP, JZNVAL_SLONG, (x)))
#define JsonDomCreateDateTimeString(jdoc, x) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_TSTAMP, JZNVAL_STRING, (x)))
/*
** NAME:
** JsonDomCreateUUID
** JsonDomCreateOID
** JsonDomCreateROWID
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - JSON DOM
** oratext *idstr (IN) - Hexadecimal string
**
** RETURNS:
** (JsonDomScalar *) new orphaned DOM scalar node
** NULL on an out of memory condition.
**
** DESCRIPTION:
** Creates a new DOM scalar node. The new node is an "orphan", meaning
** it is not attached to the DOM tree that descends from the root node.
** The scalar is an in-line UUID or OID value.
*/
#define JsonDomCreateUUID(jdoc, idstr) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_UUID, (idstr)))
#define JsonDomCreateOID(jdoc, idstr) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_OID, (idstr)))
#define JsonDomCreateROWID(jdoc, idstr) \
(JsonDomCreateScalarVal((jdoc), JZNVAL_ROWID, (idstr)))
/*
** Create a JZNVAL_SCALAR_ARRAY instance from an input JSON array.
** The input array must contain scalar nodes compatible with the
** requested array element type <vtype>.
*/
JsonDomScalar *jznDomScalarArray(JsonDomDoc *srcDoc, JsonDomArray *srcArr,
JsonDomDoc *outDoc, jznvaltype vtype);
/*------------------------- Utility interfaces ------------------------------*/
/*
** NAME:
** JsonDomClear
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (void)
**
** DESCRIPTION:
** Clears all state associated with a DOM, returning it to the "new"
** state and eliminating the root node (if any) and all descendants,
** as well as all orphan nodes.
**
** NOTES:
** This allows a DOM to be a reusable container into which a series
** of serialized JSON documents may be loaded, processed, and unloaded.
*/
#define JsonDomClear(jdoc) \
((jdoc)->mthds_jznDomDoc->jznDomDocReset((jdoc)))
/*
** NAME:
** JsonDomFree
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (void)
**
** DESCRIPTION:
** Release all memory associated with a DOM, destroying it.
*/
#define JsonDomFree(jdoc) \
((jdoc)->mthds_jznDomDoc->jznDomDocFree((jdoc)))
/*
** NAME:
** JsonDomFreeNode
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *nd (IN) - Node to free
**
** RETURNS:
** boolean - TRUE if freed, FALSE if not an orphan
**
** DESCRIPTION:
** Free an orphan node and all descendants.
*/
#define JsonDomFreeNode(jdoc, nd) \
((jdoc)->mthds_jznDomDoc->jznDomFreeNode((jdoc),(nd)))
/*
** NAME:
** JsonDomToEventSource
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM to use as event source
**
** RETURNS:
** (jznEventSource *) An event source backed by the DOM
**
** DESCRIPTION:
** Returns an event source that can be used to consume the DOM as a series
** of events, e.g. in order to write it to an encoder in another format.
** The events begin with the root node.
**
** NOTES:
** The event source is backed by the DOM and is a stateful object that
** simply walks the DOM tree. The DOM should not undergo mutation while
** events are being produced.
** ### Internally we should check this using the modification counter.
** The event source should not be destroyed conventionally, because it's
** a captive sub-object of the DOM itself.
*/
#define JsonDomToEventSource(jdoc) \
((jdoc)->mthds_jznDomDoc->jznDomGetOutputEventSrc((jdoc)))
/*
** NAME:
** JsonDomEquals
**
** PARAMETERS:
** jznDomDoc *jdoc1 (IN) - First DOM
** jznDomNode *nd1 (IN) - Node within first DOM
** jznDomDoc *jdoc2 (IN) - Second DOM
** jznDomNode *nd2 (IN) - Node within second DOM
**
** RETURNS:
** (boolean) TRUE if the nodes are identical
**
** DESCRIPTION:
** This performs a "deep equals" on two nodes which may be from the same
** DOM or from two different DOMs. Objects are compared by matching them
** field-by-field using the names, and arrays are compared by matching
** them position-by-position. Scalars are compared using domain-specific
** comparators.
**
** NOTES:
** Scalars are converted to canonical representations for comparison.
** Thus, 1E2 and 100 should both compare as equal numerically.
**
** ### The comparison method from the first document is used.
*/
#define JsonDomEquals(jdoc1, nd1, jdoc2, nd2) \
((jdoc1)->mthds_jznDomDoc->jznDomEquals((jdoc1), (nd1), (jdoc2), (nd2)))
/*
** NAME:
** JsonDomCopy
**
** PARAMETERS:
** jznDomDoc *srcdoc (IN) - Source DOM
** jznDomNode *srcnode (IN) - Source node within source DOM
** jznDomDoc *destdoc (IN) - Target DOM
**
** RETURNS:
** (jznDomNode *) Copy of the node in the target DOM
** NULL on an out of memory condition.
**
** DESCRIPTION:
** This performs a "deep copy" of a source node to a new node, possibly
** in another DOM. The root of the copy is returned as an "orphan" node
** in the target DOM. The target DOM may be the same as the source DOM.
**
** NOTES:
** The copy method from the target document is used.
*/
#define JsonDomCopy(srcdoc, srcnode, destdoc) \
((destdoc)->mthds_jznDomDoc->jznDomCopy((srcdoc), (srcnode), (destdoc)))
/*
** NAME:
** JsonDomCheckFieldKeys
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - Target DOM
** jznDomObjFieldName *fnms (IN) - Array of field name structures
** ub2 fnmsn (IN) - number of field names in the array
**
** RETURNS:
** (jsonerr) error code, JZNERR_OK (0) for no error
**
** DESCRIPTION:
** Validates a set of field IDs against a target DOM. The fields are
** conveyed as an array of key structures identical to that used by
** JsonDomGetFieldValue. The fields are checked against the target DOM
** to see if the fast-access IDs are identical and therefore safe to
** use against the target DOM. If not, they're set to 0.
**
** NOTES:
** This is needed because each DOM instance may, for binary formats,
** assign different numeric key IDs to field names, based on the order
** they are encountered. (And, in some cases, an instance may never have
** encountered a particular field name.) IDs provide faster access than
** using hash codes, but IDs aren't in general portable across instances,
** whereas hash codes are always the same.
*/
#define JsonDomCheckFieldKeys(jdoc, fnms, fnmsn) \
((jdoc)->mthds_jznDomDoc->jznDomValidFid(jdoc, fnms, fnmsn))
/*
** NAME:
** JsonDomStoreFieldName
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - Target DOM
** oratext *fname (IN) - Field name string
** ub4 fnlen (IN) - Length of field name string
** jznDomObjFieldName *nmkey (OUT) - Field name structure
**
** RETURNS:
** (jsonerr) error code, JZNERR_OK (0) for no error
**
** DESCRIPTION:
** Ensures that a field name is stored durably in the DOM, and populates
** a field name key structure with the result.
**
** NOTES:
** If the field name is already stored durably, the existing value is
** returned and no change is made to the DOM memory.
*/
#define JsonDomStoreFieldName(jdoc, fname, fnlen, nmkey) \
((jdoc)->mthds_jznDomDoc->jznDomStoreField((jdoc),(fname),(fnlen),(nmkey)))
/*
** Deep copy a tree of nodes from a source DOM into a target DOM.
** The two DOMs may be the same. The head of the new tree is returned.
*/
JsonDomNode *jznDomCopy(JsonDomDoc *srcdoc, JsonDomNode *srcroot,
JsonDomDoc *destdoc);
/*
** Compute a "deep equals" between two nodes from two possibly different DOMs.
*/
boolean jznDomEquals(JsonDomDoc *doc1, JsonDomNode *root1,
JsonDomDoc *doc2, JsonDomNode *root2);
/* Given two JSON scalar values, tell whether they are the same */
boolean jznScalarEquals(jznScalarVal *val1, jznScalarVal *val2);
sword jznScalarCompare(jznScalarVal *val1, jznScalarVal *val2,
uword flags);
/*
** Compare two nodes returning
** > 0 if node1 > node2
** < 0 if node1 < node2
** 0 if node1 == node2
*/
sword jznDomCompare(JsonDomDoc *doc1, JsonDomNode *node1,
JsonDomDoc *doc2, JsonDomNode *node2);
/*
** Perform a deep comparison of two nodes from two documents.
** Returns the status code if anything goes wrong, otherwise returns
** JZNERR_OK and the result of the comparison is found in <result>.
** Returns > 0, < 0, or 0 for node1 > node2, node1 < node2, or equality.
*/
#define JZNDOM_COMPARE_FLAG_EQUALS 0x0001
#define JZNDOM_COMPARE_FLAG_ALLOC 0x0002
#define JZNDOM_COMPARE_FLAG_BRACKET 0x0004
#define JZNDOM_COMPARE_FLAG_TYPECHECK 0x0008
#define JZNDOM_COMPARE_FLAG_TEMP 0x0010
#define JZNDOM_COMPARE_FLAG_NO_OSON_OM 0x0020
/* NO fast path for OSON DOM Deep Equality */
/* Bug 38057189 fix, using fast path OSON DOM Deep Equality by default.
* JZNDOM_COMPARE_FLAG_NO_OSON_OM is to avoid using fast path
* OSON DOM Deep Equality
*/
#define JZNDOM_COMPARE_FLAG_OSON_USEALLOC 0x0040
/* fast path for OSON DOM Deep Equality using JZNDOM_COMPARE_FLAG_ALLOC
* not the default, just for testing.
*/
sword jznDomCompareEx(JsonDomDoc *doc1, JsonDomNode *node1,
JsonDomDoc *doc2, JsonDomNode *node2,
sword *result, uword flags);
/* typeBracket = TRUE means node1 and node2 is of the same kind of node
* (object, array, scalar of compatabile type). Otherwise, it returns
* JZNERR_INCOMPATIBLE_COMPARE.
*/
/* Bug34615330: jznDomCompareWithTypeBracket() */
/* when typeBracket is TRUE, the node1 and node2 must of the same
* node type
* (object node vs object node, array node vs array node,
* scalar node vs scalar node of compatible scalar value type
* at top level.
* It internally passes down JZNANY_FLAG_MATCH_DATA_TYPE to achieve this.
*
* It returns JZNERR_INCOMPATIBLE_COMPARE if node is NOT compatible.
*/
sword jznDomCompareWithTypeBracket(JsonDomDoc *doc1, JsonDomNode *node1,
JsonDomDoc *doc2, JsonDomNode *node2,
sword *result, uword flags,
boolean typeBracket);
/*
** Sort all fields in a DOM object node (using heapsort in-place)
*/
void jznDomSortFields(jznDomNameValuePair *nvps, ub4 numfields);
/*
** Get the scalar value type for a node.
** If the node is non-scalar, returns a generic JZNVAL_DOC_NODE.
*/
jznvaltype JsonDomGetScalarType(JsonDomDoc *doc, JsonDomNode *node);
/*--------------------------- Serializer interfaces -------------------------*/
/*
** NAME:
** JsonSerializeDom
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM to be serialized
** list (IN) - NULL-terminated list of variable arguments
**
** Supported varargs parameters:
** =======================================================================
** Property Name Expected Type Valid values Notes
** =======================================================================
** JZN_FILE oratext *
** JZN_BUFFER void *
** JZN_BUFFERLEN ub4 * IN/OUT
** JZN_STREAM orastream *
** JZN_FORMAT oratext * "JSON", "OSON"
** JZN_PRINT_FLAGS ub4 For "JSON" only
** JZN_DOM JsonDomDoc * Must for "OSON"
**
** RETURNS:
** (jsonerr)
**
** DESCRIPTION:
** Serializes a DOM and writes to a sink specified in the varargs list. The
** output format can either be textual JSON (JZN_FORMAT = "JSON") or binary
** OSON (JZN_FORMAT = "OSON").
**
** NOTES:
** If output format requested is OSON, source DOM should be JZN_INMEM_DOM
** type.
**
*/
#define JsonSerializeDom(jdoc, ...) \
((jdoc)->mthds_jznDomDoc->jznDomSerialize((jdoc), __VA_ARGS__))
/*
** NAME:
** JsonDomPrintDocument
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM to be printed
** jznPrintCtx *printCtx (IN) - Print context to write the DOM to
**
** RETURNS:
** (jsonerr) - Error code
**
** DESCRIPTION:
** Serializes a DOM to a print context. The print context is a type of
** event writer or "sink". The DOM is walked from the root, and events
** delivered to the print context, which serializes the DOM as valid JSON.
**
** NOTES:
** The caller is expected to have set up the print context before calling
** this interface. The print context may be backed by a stream or a
** fixed sized buffer, or by an extensible buffer internal to the
** print context.
** 1. Before this function is called for the first time, call
** jznuPrintCreate() to initialize the printCtx.
** 2. Once a jznuPrintCtx is created, it can be reused to serialize
** multiple documents by calling this function multiple times.
** 3. When done with serializing all documents, call
** jznuPrintDestroy() to destroy the printCtx.
*/
#define JsonDomPrintDocument(jdoc, printCtx) \
jznDomPrintDocument((jdoc), (printCtx))
/*
** NAME:
** JsonDomPrintNode
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM containing nodes to be printed
** jznDomNode *node (IN) - node within the DOM to serialize
** jznEventWriter *writer (IN) - Event writer to consume the events
**
** RETURNS:
** (jsonerr) - Error code
**
** DESCRIPTION:
** Serializes a DOM node tree to an event writer. The event writer is
** commonly a print context, but may also be another event consumer
** such as a binary encoder
**
** NOTES:
** This interface is a more general version of JsonDomPrintDocument.
** JsonDomPrintDocument is equivalent to calling this interface with
** jznuPrintToWriter() around the print context and JsonDomGetRoot()
** as the starting node.
*/
/* instead of calling generic jznDomPrintNode((jdoc), (node), (writer)),
* we call each DOM implmentation method which is more efficient due to
* direct internal func call
*/
#define JsonDomPrintNode(jdoc, node, writer) \
((jdoc)->mthds_jznDomDoc->jznDomPrintNode((jdoc), (node), (writer)))
/*
** NAME:
** JsonDomSave
**
** PARAMETERS:
** JsonDomDoc *jdoc (IN) - DOM containing nodes to be printed
** jsonerr *jerr (OUT) - Error code
**
** RETURNS:
** (ubig_ora) - Number of bytes return to the output sink
**
** DESCRIPTION:
** Serializes a DOM node tree to a sink. The sink can be specified using the
** varargs.
**
** NOTES:
** This interface is a more general version of JsonDomPrintDocument.
** Supported varargs parameters:
** ===================================
** Property Name Expected Type
** ===================================
** JZN_FILE oratext *
** JZN_BUFFER void *
** JZN_BUFFERLEN ub4
** JZN_STREAM orastream *
** JZN_PRETTY boolean
** JZN_ASCII boolean
** JZN_EXTENSIBLE_BUF boolean
*/
ubig_ora JsonSaveDom(JsonDomDoc *jdoc, jsonerr *jerr, ...);
ubig_ora JsonSaveDomVA(JsonDomDoc *jdoc, jsonerr *jerr, va_list va);
/*
** NAME:
** jznDomScalarToString
**
** DESCRIPTION:
** Convert a jznScalarVal to its textual representation
**
** INPUTS:
** xmlctx *xctx : XML context (NULL OK)
** jznScalarVal *val : Scalar value to convert
** char *outbuf : Buffer to hold the result
** ub4 *outlen : IN/OUT length of the buffer 'outbuf'
**
** OUTPUTS:
** sword : indicates the status of the conversion.
** JZNERR_OK means conversion is successful.
** All callers should check the return status before proceeding.
*/
sword jznDomScalarToString(xmlctx *xctx, jznScalarVal *val,
char *outbuf, ub4 *outlen);
/*
** Print an entire DOM to a print context.
*/
jsonerr jznDomPrintDocument(JsonDomDoc *doc, jznuPrintCtx *pctx);
#define JZNDOM_PRINT_SORT_NONE 0x0000 /* No sorting */
#define JZNDOM_PRINT_SORT_KEYNAME 0x0001 /* Sort objects by key name */
#define JZNDOM_PRINT_SORT_OPTIMIZE 0x0002 /* Optimize field ordering */
#define JZNDOM_PRINT_SORT_METADATA 0x0004 /* put _id/_etag first */
#define JZNDOM_PRINT_HDL_RAW_ASOSON 0x0008 /* detect oson embedded in raw*/
/*
** Print a tree of nodes from a given starting point within the DOM.
** Optionally can produce nodes in sorted order.
*/
jsonerr jznDomPrintSortNode(JsonDomDoc *doc, JsonDomNode *node,
jznEventWriter *writer, ub4 flags);
/*
** Print a tree of nodes from a given starting point within the DOM.
*/
jsonerr jznDomPrintNode(JsonDomDoc *doc, JsonDomNode *node,
jznEventWriter *writer);
/*
** NAME:
** jznuGetScalarLength
**
** PARAMETERS:
** val : scalar value
**
** RETURNS:
** length of the given scalar value
**
** DESCRIPTION:
** Returns the length of a scalar value
*/
ub4 jznuGetScalarLength(jznScalarVal *val);
/*
** Return the number of entries in the DOM hash table.
** ### Move this to jzn0.h ?
*/
ub4 jznDomHashGetSize(jznDomHashTable *ht);
/*---------------------------- OSON Utility interfaces ----------------------*/
/*
** NAME:
** jznoctLoadInMemDomFromInputOSON
** jznoctLoadInMemDomFromInputOSON_WF
**
** PARAMETERS:
** JsonDomDoc *srcdoc (IN) - OSON DOM container
** JsonDomDoc *srcroot (IN) - Root node of the OSON DOM
** JsonDomDoc *destdoc (IN) - In-memory DOM container
** ub4 flag (IN) - Flags for loading
**
** RETURNS:
** (JsonDomNode *) - Root node after loading
**
** DESCRIPTION:
** Loads in-memory JSON DOM from OSON DOM backed by OSON buffer. If source
** OSON bytes buffer in srcdoc is guaranteed to be stable during the life
** time of the in-memory JSON DOM loaded from the OSON bytes buffer, then
** flags can be used for optimizing in-memory DOM loading process.
** Calling jznoctLoadInMemDomFromInputOSON() is semantically equivalent to
** calling jznoctLoadInMemDomFromInputOSON_WF() with JZNOCT_NO_CPY_LEAF_VAL
** flag.
**
** NOTES:
** ERROR HANDLING: It may return NULL in case of error with errrcode
** obtaineable via JsonDomGetError(srcdoc).
*/
JsonDomNode *jznoctLoadInMemDomFromInputOSON_WF(JsonDomDoc *srcdoc,
JsonDomNode *srcroot,
JsonDomDoc *destdoc, ub4 flag);
JsonDomNode *jznoctLoadInMemDomFromInputOSON(JsonDomDoc *srcdoc,
JsonDomNode *srcroot,
JsonDomDoc *destdoc);
/*
** Avoids deep copy of the leaf value as the leaf value resides in the OSON
** bytes buffer is stable. However, in case the leaf value needs to be
** modified, then a deep copy of leaf content will be made by then by using
** JZN0DOM_SC_VAL_IN_OSON_BUF flag.
*/
#define JZNOCT_NO_CPY_LEAF_VAL 0x1
/*
** If there is no modification of field names (adding field names) for the
** in-memory JSON DOM loaded from OSON buffer, JZNOCT_NO_CPY_FIELDNAME_BUF
** can be used so that the field name buffer point to OSON field name
** dictionary buffer withotu deep copy.
*/
#define JZNOCT_NO_CPY_FIELDNAME_BUF 0x2
/*
** OSON to in-memory JSON DOM copy with field name dictionary partially
** set up because input oosn dom is not copied from root so that destination
** dom does not need all field name dictionary from the original oson dom.
** ERROR HANDLING: It may return NULL in case of error with errrcode
** obtaineable via JsonDomGetError(srcdoc)
*/
#define JZNOCT_FIELD_NM_PARTIAL 0x4
/*
** NAME:
** jznoctSerInMemDomToOSON
** jznoctSerInMemDomToOSON_WF
**
** PARAMETERS:
** JsonDomDoc *oct (IN) - OSON DOM container
** JsonDomDoc *doc (IN) - Root node of the OSON DOM
** JsonDomNode *root (IN) - In-memory DOM root node
** jznosonfile *ofile (IN) - OSON writer context
** ub4 flag (IN) - Flags for loading
**
** RETURNS:
** (jsonerr) - Error code
**
** DESCRIPTION:
** Generates OSON bytes into ofile by serializing an in-memory JSON DOM root.
**
** NOTES:
*/
jsonerr jznoctSerInMemDomToOSON_WF(JsonDomDoc *oct, JsonDomDoc *doc,
JsonDomNode *root, jznosonFile *ofile,
ub4 flag);
jsonerr jznoctSerInMemDomToOSON(JsonDomDoc *oct, JsonDomDoc *doc,
JsonDomNode *root, jznosonFile *ofile);
/*
** Free the root after serialization
*/
/* GC field name first */
#define JZNOCT_SERINMEM_GC_FILED_NAMES 0x1
/* try to use ub2 offset to encode oson first */
#define JZNOCT_SERINMEM_TRY_UB2_OFF 0x2
/* one path to encode oson */
#define JZNOCT_SERINMEM_ONEPATH 0x4
/* using JZNOCT_SERINMEM_TRY_UB2_OFF is noop unless used in conjnction with
* JZNOCT_SERINMEM_ONEPATH.
* By default, JZNOCT_SERINMEM_ONEPATH does OSON encoding
* without analyzing if ub2 offset can be used. However, if users are aware
* that resulting OSON is small enough and can use ub2 offset encoding, then
* they may turn on JZNOCT_SERINMEM_TRY_UB2_OFF.
* Then oson encoding tries to use ub2 offset encoding first. If it fails, then
* it switches to ub4 encoding.
* Using this flag only if caller knows the
* resulting oson is most likely can be encoded use ub2 offset. Otherwise
* it will hurt encoding performance. This flag is most effectively used
* with JZNOCT_SERINMEM_ONEPATH.
*
* Common case when caller knows ub2 offset encoding ok is to evaaluate
* json_query(returning json) when input oson size to json_query() is less
* than ub2 size.
* Or json_table() json type column projection when inpu toson size to
* json_table() is less than ub2 size.
*/
/*------------------------- Error handling interfaces -----------------------*/
/*
** NAME:
** JsonDomGetError
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM to check error code for
**
** RETURNS:
** (jsonerr) error code, JZNERR_OK (0) for no error
**
** DESCRIPTION:
** Returns an error code for a DOM operation that failed (for example,
** an attempt to read an array out of bounds).
*/
#define JsonDomGetError(jdoc) \
((jdoc)->errcode_jznDomDoc)
/*
** NAME:
** JsonDomGetErrorMessage
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM to get message for
** jsonerr *err (OUT) - Error code or 0 for none
** boolean clear (IN) - TRUE to clear error after reading
**
** RETURNS:
** (oratext *) error message string, NULL on memory error.
**
** DESCRIPTION:
** Returns a rendered error message for the current DOM error code.
** Returns the empty string if there is no current error.
** Returns the current error code in the optional <err> argument.
** If <clear> is TRUE, the document's internal error is cleared.
*/
#define JsonDomGetErrorMessage(jdoc, err, clear) \
((jdoc)->mthds_jznDomDoc->jznDomGetError((jdoc),(err),(clear)))
/*
** NAME:
** JsonDomClearError
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM to check error code for
**
** RETURNS:
** (void)
**
** DESCRIPTION:
** Clear the error code for the DOM, e.g. to clear an array out of bounds
** error after reading it.
*/
#define JsonDomClearError(jdoc) \
((jdoc)->errcode_jznDomDoc = JZNERR_OK)
/*
** Get a rendered error message from the DOM. Returns an empty string
** if there is no error.
*/
oratext *jznDomGetErrorMessage(JsonDomDoc *doc, jsonerr *err, boolean clear);
/*
** NAME:
** JsonDomGetModifcations
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM to get modification count for
**
** RETURNS:
** (ub4) running count of mutation operations against the DOM
**
** DESCRIPTION:
** Return a count of modification operations against a DOM. This
** may be used by a caller to detect whether a DOM has been changed
** since a prior call to the interface. For example, a caller may
** use a change in the modification count to detect that an in-progress
** iteration over field or array items may be invalidated.
**
** NOTES:
** This interface will typically return 0 (for DOMs, such as OSON, that
** are read-only), or 1 for DOMs that have not been modified beyond setting
** the root node after creation (e.g. from an event source). Otherwise,
** the value monotonically increases for the life of the DOM, until
** reset or reused.
*/
#define JsonDomGetModifications(jdoc) \
((jdoc)->modcount_jznDomDoc)
/*
** NAME:
** JsonDomNodeVisitor
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - DOM doc to be visited
** jznDomNode *node (IN) - starting node to be visited
** JsonDomVisitorFunc func (IN) - callback func user supplied
** void *appctx (IN) - callback context user supplied
**
** RETURNS:
** void
**
** DESCRIPTION:
** walks through each DOM node and calls a user supplifed api function
** <func> with api specific application context <ctx>
*/
#define JsonDomNodeVisitor(jdoc, node, func, appctx) \
((jdoc)->mthds_jznDomDoc->jznDomNodeVisitor((jdoc),(node),(func),(appctx)))
/*
** NAME:
** JsonDomGetFieldPosition
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomObject *obj (IN) - Object node within the DOM
** oratext *fname (IN) - Field name string
** ub2 fnlen (IN) - Length of field name string in bytes
** ub4 *pos (OUT) - Position within object (optional)
**
** RETURNS:
** (jznDomNode *) the value of the field (may be any JSON node type)
**
** DESCRIPTION:
** Returns the value of a field within the object, retrieving it by matching
** the name string and length.
** Returns NULL if a matching field cannot be found.
**
** NOTES:
** Optionally returns the position of the field within the object's
** children, equivalent to the position within a batch get sequence.
** This will be UB4MAXVAL if the value is unavailable.
**
** ERROR HANDLING: It may return NULL in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomGetFieldPosition(jdoc, obj, fname, fnlen, pos) \
((jdoc)->mthds_jznDomDoc->jznDomGetFieldPos((jdoc),(obj), \
(fname),(fnlen),(pos)))
/*
** NAME:
** JsonDomSortArray
**
** PARAMETERS:
** JsonDomDoc *doc (IN) - DOM document
** JsonDomArray *arr (IN) - array node to sort
** uword flags (IN) - sort mode flags
**
** RETURNS:
** JSON status code
**
** DESCRIPTION:
** Sort the nodes within an array using AnyType comparisons.
** Flags govern the type of re-arrangement that is performed:
** - Unique : remove duplicates, doesn't re-order the elements
** - Unlink : unlink duplicates instead of reporting them
** - Delete : delete duplicates instead of reporting them
** - Ascending : re-order based on collation comparisons
** - Descending : re-order based on collation comparisons
**
** NOTES:
** The sort is inherently an order(n * log(n)) operation.
*/
#define JsonDomSortArray(jdoc, arr, flags) \
((jdoc)->mthds_jznDomDoc->jznDomSortArray((jdoc),(arr),(flags)))
#define JZNDOM_ARRAY_SORT_UNIQUE 0x0001
#define JZNDOM_ARRAY_SORT_UNLINK 0x0002 /* Unlink duplicates */
#define JZNDOM_ARRAY_SORT_DELETE 0x0004 /* Delete duplicates */
#define JZNDOM_ARRAY_SORT_COUNT 0x0008 /* Count duplicates */
#define JZNDOM_ARRAY_SORT_ASCENDING 0x0010
#define JZNDOM_ARRAY_SORT_DESCENDING 0x0020
/*
** NAME:
** JsonDomSortObject
**
** PARAMETERS:
** JsonDomDoc *doc (IN) - DOM document
** JsonDomObject *obj (IN) - object node to sort
** uword flags (IN) - sort mode flags
**
** RETURNS:
** JSON status code
**
** DESCRIPTION:
** Sort the fields of an object in either ascending or descending order.
** - Ascending : re-order based on collation comparisons
** - Descending : re-order based on collation comparisons
**
** NOTES:
** The sort is inherently an order(n * log(n)) operation.
*/
#define JsonDomSortObject(jdoc, obj, flags) \
((jdoc)->mthds_jznDomDoc->jznDomSortObject((jdoc),(obj),(flags)))
#define JZNDOM_SORT_FIELDS_ASCENDING 0x0010
#define JZNDOM_SORT_FIELDS_DESCENDING 0x0020
/*
** NAME:
** JsonDomKeepFields
**
** PARAMETERS:
** JsonDomDoc *doc (IN) - DOM document
** JsonDomObject *obj (IN) - object node to redact
** jzndomFldKeepS *fields (IN) - array of fields to keep
** ub4 nfields (IN) - number of fields
**
** RETURNS:
** JZNERR_NOT_MATCHED if none of the keep fields were matched and
** the object is now empty, JZNERR_OK if successful with at least one
** field matched, otherwise an error code.
**
** DESCRIPTION:
** Unlink fields not matching a specified list of fields given by the input
** argument <fields>[<numfields>]. The unlinked values become orphan nodes.
**
** NOTES:
** This may mutate the input array for bookkeeping purposes.
** The original field order may not be preserved by this operation.
*/
#define JsonDomKeepFields(jdoc, obj, flds, nflds) \
((jdoc)->mthds_jznDomDoc->jznDomKeepFields((jdoc),(obj),(flds),(nflds)))
/*
** NAME:
** JsonDomCastValue
**
** PARAMETERS:
** JsonDomDoc *doc (IN) - DOM document
** JsonDomScalar *snode (IN) - Scalar node in the DOM to be cast
** jznExtnType vtype (IN) - Destination type to cast scalar to
**
** RETURNS:
** JSON status code
**
** DESCRIPTION:
**
**
** NOTES:
** Supported only for mutable DOM.
*/
#define JsonDomCastValue(jdoc, snode, vtype) \
((jdoc)->mthds_jznDomDoc->jznDomCastValue((jdoc), (snode), (vtype)))
/*
** NAME:
** JsonDomClearWF
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** ub4 flag (IN) - flag
**
** RETURNS:
** (void)
**
** DESCRIPTION:
** Clears all state associated with a DOM, returning it to the "new"
** state and eliminating the root node (if any) and all descendants,
** as well as all orphan nodes.
**
** NOTES:
** This allows a DOM to be a reusable container into which a series
** of serialized JSON documents may be loaded, processed, and unloaded.
*/
/* flag passed into JsonDomClearWF() */
#define JSONDOM_CLR_NO_CLOSE_INPUT 0x1
/* flag relevant for oson dom to avoid closing the input oson for re-use*/
#define JsonDomClearWF(jdoc, flag) \
((jdoc)->mthds_jznDomDoc->jznDomDocResetWF(jdoc, flag))
/*
** NAME:
** JsonDomDecodeOSONBytesIntoNode
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** ub1 *oson_byte (IN) - OSON byte array[]
** ub4 oson_byte_len (IN) - OSON byte array length
** jsonerr *ojerr (OUT) - returned, error loading oson bytes
** jznDomDoc **out_jdoc (OUT) - OSON DomDoc loaded from the oson bytes
**
** RETURNS:
** (jznDomNode *)
**
** DESCRIPTION:
** This method decodes the input OSON bytes and returns the OSON DOM Node.
** The OSON decoder is cached inside jdoc for future use.
** It is used to decode oson bytes embedded as raw.
**
** NOTES:
*/
#define JsonDomDecodeOSONBytesIntoNode(jdoc, oson_byte, oson_byte_len, \
ojerr, out_jdoc) \
((jdoc)->mthds_jznDomDoc->jznDomDocDecodeOSONBytesIntoNode \
(jdoc, oson_byte, oson_byte_len, ojerr, out_jdoc))
/* Bug37204122: dom api to push down range cmp/in-clause */
/*
** NAME:
** JsonDomAryFilter
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *jary (IN) - JSON Node Array
** jznEng_RngCmpInf *filter(IN) - Filter Spec
**
** RETURNS:
** boolean: TRUE if evauation is successful, the filter
** result is in the filter spec
** FALSE if evauation fails.
**
** DESCRIPTION:
** evaluate range comp filter over array of elements to see if any array
** element of scalar value satisifies the filter
**
** NOTES:
*/
#define JsonDomAryFilter(jdoc, jary, filter) \
((jdoc)->mthds_jznDomDoc->jznDomAryFilter(jdoc, jary, filter))
/*
** NAME:
** JsonDomScalarFilter
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *jary (IN) - JSON Node Array
** jznEng_RngCmpInf *filter(IN) - Filter Spec
**
** RETURNS:
** boolean: TRUE if evauation is successful, the filter
** result is in the filter spec
** FALSE if evauation fails.
**
** DESCRIPTION:
** evaluate range comp filter over the scalar node to see if the scalar
** node of the scalar value satisifies the filter
**
** NOTES:
*/
#define JsonDomScalarFilter(jdoc, jsca, filter) \
((jdoc)->mthds_jznDomDoc->jznDomScalarFilter(jdoc, jsca, filter))
/*
** NAME:
** JsonDomAryInClauseMrgSort
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *jary (IN) - JSON Node Array
** jznEng_RngCmpInf *incI(IN) - in clause Spec
**
** RETURNS:
** boolean: TRUE if evauation is successful, the inclause eval
** result is in the output variable *rslt
** FALSE if evauation fails.
**
** DESCRIPTION:
** evaluate in clause path expr over array of sorted elements using preSorted
*** merge join eval approach.
*** Note the input array node of scalar values is sorted.
**
** NOTES:
*/
#define JsonDomAryInClauseMrgSort(jdoc, jary, incI, rslt) \
((jdoc)->mthds_jznDomDoc->jznDomAryInClauseMrgSort(jdoc, jary, incI, rslt))
/*
** NAME:
** JsonDomAryInClauseBinSrch
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *jary (IN) - JSON Node Array
** jznEng_RngCmpInf *incI(IN) - in clause Spec
**
** RETURNS:
** boolean: TRUE if evauation is successful, the inclause eval
** result is in the output variable *rslt
** FALSE if evauation fails.
**
** DESCRIPTION:
** evaluate in clause path expr over sorted inlist using binary search
*** Note the input array node of scalar values is NOT sorted.
**
** NOTES:
*/
#define JsonDomAryInClauseBinSrch(jdoc, jary, incI, rslt) \
((jdoc)->mthds_jznDomDoc->jznDomAryInClauseBinSrch(jdoc, jary, incI, rslt))
/*
** NAME:
** JsonDomAryMinMaxJt
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *jary (IN) - JSON Node Array
** jznpFunction *fdesc (IN) - capture JZNL_MIN or JZNL_MAX
** jznlitid funcType (IN) - JZNL_MIN or JZNL_MAX
**
** RETURNS:
** the array element node whose node is smallest (JZNL_MIN)
** or JZNL_MAX using
** json datatype range comparison (DeepDomNodesCompare) semantics
**
** DESCRIPTION:
** given a json array, it finds the min or max of the element node using
** json datatype range comparison (DeepDomNodesCompare) semantics
**
** ERROR HANDLING: It may return JZNDOM_SCALAR in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomAryMinMaxJt(jdoc, jary, fdesc)\
((jdoc)->mthds_jznDomDoc->jznDomAryMinMaxJt(jdoc, jary, fdesc))
/*
** NAME:
** JsonDomAryAggRetSca
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomArray *jary (IN) - JSON Node Array
** jznpFunction *fdesc (IN) - capture jznlitid funcType (with arguments)
** jznlitid funcType (IN) - JZNL_SUM, JZNL_AVG, JZNL_COUNT,
** JZNL_MINNUMBER, JZNL_MAXNUMBER,
** JZNL_MINSTRING, JZNL_MAXSTRING,
** JZNL_MINDATETIME, JZNL_MAXDATETIME,
** JZNL_VARIANCE, JZNL_STDDEV, JZNL_STDDEVP
** see JZN_PCODE_AGG_FUNC_RET_SVAL() macro
** ub4 modeFlags (IN) - Agg Mode control flags
** ub4 maxlen (OUT) - output buffer max length of (*valptr_o)
** jznvaltype *jtype_o (OUT) - aggregation value output with
** output jtype_o, valptr_o, vallen_o
** ub1 *valptr_o (OUT)
** ub4 *vallen_o (OUT)
**
** RETURNS:
** error code, JZNERR_OK means successful
**
** DESCRIPTION:
** given a json array, it runs agg function to return a scalar value
**
** ERROR HANDLING: It may return JZNDOM_SCALAR in case of error with errrcode
** obtaineable via JsonDomGetError(jdoc)
*/
#define JsonDomAryAggRetSca(jdoc,jary,fdesc, modeFlags,maxlen,jtype_o,valptr_o,\
vallen_o)\
((jdoc)->mthds_jznDomDoc->jznDomAryAggRetSca(jdoc, jary, fdesc, modeFlags,\
maxlen,jtype_o, valptr_o, vallen_o))
/* Bug37488368: JsonDomXXXSimPathRngFilter pred dom api */
/*
** NAME:
** JsonDomObjSimPathRngFilter
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** JsonDomObject *obj (IN) - JSON Object Node
** jznEng_SimPathRngCmpInf *simCmpI (IN/OUT) -
** ub4 flag (IN) - passing JZNENGDOM_NO_ARY_DRIL
** struct capturing simple path range pred eval
**
**
** RETURNS:
** TRUE if evaluation is feasible with result recorded in *simCmpI.
** FALSe if evaluation is NOT feasible.
**
** DESCRIPTION:
** evaluate simple path <rngCmp> <const/bindvar> for every object member of the
** input json object node.
** return TRUE if it is feasible to evaluate the filter, then output result
** is recorded in *cmpI.
**
** ERROR HANDLING:
*/
#define JsonDomObjSimPathRngFilter(jdoc,obj, simCmpI, flag)\
((jdoc)->mthds_jznDomDoc->jznDomObjSimPathRngFilter(jdoc, obj, simCmpI,flag))
/*
** NAME:
** JsonDomArySimPathRngFilter
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** JsonDomArray *ary (IN) - JSON Array Node
** jznEng_SimPathRngCmpInf *simCmpI (IN/OUT) -
** struct capturing simple path range pred eval
** ub4 flag (IN) - passing JZNENGDOM_NO_ARY_DRIL
**
**
** RETURNS:
** TRUE if evaluation is feasible with result recorded in *simCmpI.
** FALSe if evaluation is NOT feasible.
**
** DESCRIPTION:
** evaluate simple path <rngCmp> <const/bindvar> for every element of the
** input json array node
** return TRUE if it is feasible to evaluate the filter, then output result
** is recorded in *cmpI.
**
** ERROR HANDLING:
*/
#define JsonDomArySimPathRngFilter(jdoc,jarr, simCmpI, flag)\
((jdoc)->mthds_jznDomDoc->jznDomArySimPathRngFilter(jdoc, jarr, simCmpI,flag))
/* Bug37488368: JsonDomXXXSimPathRngFilter pred dom api */
/*
** NAME:
** JsonDomSimPathRngFilter
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *node (IN) - JSON Dom
** jznEng_SimPathRngCmpInf *simCmpI (IN/OUT) -
** ub4 flag (IN) - passing JZNENGDOM_NO_ARY_DRIL
** struct capturing simple path range pred eval
**
**
** RETURNS:
** TRUE if evaluation is feasible with result recorded in *simCmpI.
** FALSe if evaluation is NOT feasible.
**
** DESCRIPTION:
** evaluate simple path <rngCmp> <const/bindvar> via dom API
** return TRUE if it is feasible to evaluate the filter, then output result
** is recorded in *cmpI.
**
** ERROR HANDLING:
*/
boolean JsonDomSimPathRngFilter(JsonDomDoc *doc, JsonDomNode *node,
jznEng_SimPathRngCmpInf *simpCmpI /*IN/OUT */, ub4 flag);
/* Bug 38212527 JsonDomTxtContains(): recursive nodes down to scalar string
* node for full text eval
*/
/*
** NAME:
** JsonDomObjTxtContains
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** JsonDomObject *obj (IN) - JSON Object Node
** JsonDomTxtContains *simCmpI (IN/OUT) -
** ub4 flag (IN) -
** struct capturing simple path range pred eval
**
**
** RETURNS:
** TRUE if evaluation is feasible with result recorded in *simCmpI.
** FALSe if evaluation is NOT feasible.
**
** DESCRIPTION:
** evaluate simple path <rngCmp> <const/bindvar> for every object member of the
** input json object node.
** return TRUE if it is feasible to evaluate the filter, then output result
** is recorded in *cmpI.
**
** ERROR HANDLING:
*/
#define JsonDomObjTxtContains(jdoc,obj, simCmpI, flag)\
((jdoc)->mthds_jznDomDoc->jznDomObjTxtContains(jdoc, obj, simCmpI,flag))
/*
** NAME:
** JsonDomAryTxtContains
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** JsonDomArray *ary (IN) - JSON Array Node
** JsonDomTxtContains *simCmpI (IN/OUT) -
** struct capturing simple path range pred eval
** ub4 flag (IN) - passing JZNENGDOM_NO_ARY_DRIL
**
**
** RETURNS:
** TRUE if evaluation is feasible with result recorded in *simCmpI.
** FALSe if evaluation is NOT feasible.
**
** DESCRIPTION:
** evaluate simple path <rngCmp> <const/bindvar> for every element of the
** input json array node
** return TRUE if it is feasible to evaluate the filter, then output result
** is recorded in *cmpI.
**
** ERROR HANDLING:
*/
#define JsonDomAryTxtContains(jdoc,jarr, simCmpI, flag)\
((jdoc)->mthds_jznDomDoc->jznDomAryTxtContains(jdoc, jarr, simCmpI,flag))
/*
** NAME:
** JsonDomTxtContains
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** jznDomNode *node (IN) - JSON Dom
** jznEng_TxtContInf *evinf (IN/OUT) -
** struct capturing full text evaluation
** ub4 flag (IN) -
**
**
** RETURNS:
** TRUE if evaluation is TRUE with result recorded in *evinf
** FALSE otherwise
**
** DESCRIPTION:
** apply full text contains evaluation to each scalar text nodes by
** recursively traverse from the <node>
**
** ERROR HANDLING:
*/
boolean JsonDomTxtContains(JsonDomDoc *jdoc, JsonDomNode *node,
jznEng_TxtContInf *evinf /*IN/OUT */, ub4 flag);
/*
** NAME:
** JsonDomHash
**
** PARAMETERS:
** JsonDomDoc *doc (IN) - DOM document
** JsonDomNode *node (IN) - starting node to be hashed
** ub1 *outbuf (OUT) - result of the hash
** ub4 *outlen (OUT) - size of hash in bytes
**
** RETURNS:
** JSON status code
**
** DESCRIPTION:
** Computes a canonical hash for the DOM starting from a node
** (usually the root). Object fields are canonically ordered.
** Scalars are turned into canonical forms (number, date/time).
** outbuf is assumed large enough to hold the resulting hash (32 bytes).
**
** NOTES:
** This operates slightly differently for scalar nodes than the
** jznuToAnyType() function. They are hashed as nodes with a node type
** code. The unbounded values are not truncated but fully hashed
** (string, binary). Numeric types are converted to string format
** before hashing to avoid precision/scale loss that may occur with
** OraNum conversions. The ID types are treated as JZNVAL_ID, to
** distinguish them from RAW binary values. Only date/time/interval
** types are treated exactly the same.
*/
sword JsonDomHash(JsonDomDoc *doc, JsonDomNode *node,
ub1 *outbuf, ub4 *outlen);
#define JZNDOM_NODE_HASH_LENGTH 16 /* 128-bit output */
/*
** NAME:
** JsonDomAnyType
**
** PARAMETERS:
** JsonDomDoc *doc (IN) - DOM document
** JsonDomNode *node (IN) - starting node to be indexed
** ub1 *outbuf (OUT) - result comparable image
** ub4 *outlen (OUT) - size of image in bytes
** ub4 max_depth (IN) - beyond this depth use a hash
** ub4 max_size (IN) - larger containers use a hash
** uword flags (IN) - we love our flags
**
** RETURNS:
** JSON status code
**
** DESCRIPTION:
** Computes a memcmp-friendly image of a DOM node, similar to
** jznuAnyScalar but working on any type of DOM node including
** objects and arrays. Objects are stored with a start-container
** and end-container bookends, and fields are stored as field/value
** pairs with a special code for start-of-field-name. Fields names
** are just appended follwed by a [0x00,0xFF] terminator. The field
** names are sorted into a canonical order. Arrays are stored by just
** traversing their elements in linear order and appending them,
** however the end-of-array is marked with an end-container bookmark
** to ensure that duplicate-key situations don't arise.
**
** NOTES:
** Scalars are subjected to jznuAnyScalar. Fixed-length values
** are stored as-is (date/time values are 0-padded to make them
** 11 bytes). Strings are stored as-is with a [0x00,0xFF] terminator.
** Binaries including IDs are rounded to the nearest multiple of
** 16 bytes in size, then a length byte with the number of 16-byte
** units (0-255 chunks, e.g. 0-4080 bytes) prepended to the payload.
** Numbers are converted to Oracle Numbers and a 0x00 appended.
** Pass UB4MAXVAL for max_depth and max_size to get an unlimited
** traversal. Passing 0 for the max_size will force all objects/arrays
** including the start node to be similar to the hash of a node.
** Passing a 0 for max_depth causes all nodes to be rendered with a hash.
*/
sword JsonDomAnyType(JsonDomDoc *doc, JsonDomNode *node,
ub1 *outbuf, ub4 *outlen,
ub4 max_depth, ub4 max_size, uword flags);
#define JZNANY_FLAG_NUMBER_EXTENDED 0x0100 /* Merge Decimal128 values */
#define JZNANY_FLAG_NULL_ON_EMPTY 0x0200 /* Treat empty values as nulls */
#define JZNANY_FLAG_UTF16_STRINGS 0x0400 /* Strings are in UTF16 format */
#define JZNANY_FLAG_UTF8_STRINGS 0x0800 /* Strings are in UTF8 format */
#define JZNANY_FLAG_JSON_STRINGS 0x0C00 /* No string conversions */
#define JZNANY_FLAG_MATCH_NODE_TYPE 0x1000 /* Require matching node types */
#define JZNANY_FLAG_MATCH_DATA_TYPE 0x2000 /* Require matching scalar types */
#define JZNANY_FLAG_PRESERVE_TYPES 0x4000 /* Preserve scalar types */
#define JZNANY_FLAG_PRESERVE_ORDER 0x8000 /* Preserve field order */
#define JZNANY_FLAG_BINARY_ENDCAP 0x10000 /* Always terminate binaries */
#define JZNANY_FLAG_OSON_FID 0x20000 /* use oson field id as order */
/* Bug 38057189 fix, generating memcomparable bytes for OSON dom using stable
* oson dom field id based order. good for json type distinct, group by without
* requiring sorting field names based on field name order.
*/
/* Bug 38212507,37157467: jznDomFlattenNodeSeqAsAry */
/* takes an array of JsonDomNode * <node_ary> and then flattern it as
* an array anyType image.
* Primary usecase, result of json path evaluation is a sequence of nodes,
* we create anyType image by logically converting the sequence of nodes
* into an array of nodes without explicitly converting the sequence of nodes
* into an array of nodes.
*/
sword JsonDomNodeSeqAsAryAnyType(JsonDomDoc *doc, JsonDomNode **node_ary,
ub4 arysz,
ub1 *outbuf, ub4 *outlen,
ub4 max_depth, ub4 max_size, uword flags);
/*
** This is similar to JsonDomAnyType, but instead of rendering an image,
** this performs an on-the-fly render-and-compare against an existing
** image <buf> of length <buflen>. The result of the comparison is returned
** in <result>. Returns 0 if the values are the same, > 0 if <node> is
** greater than the old image, < 0 if <node> is less than the old image.
** The status is JZNERR_OK, or an error if the operation failed (e.g.
** due to out-of-memory conditions, type conversion failures, etc.).
*/
sword JsonDomAnyCompare(JsonDomDoc *doc, JsonDomNode *node,
ub1 *buf, ub4 buflen, sb4 *result,
ub4 max_depth, ub4 max_size, uword flags);
typedef struct jznAnyTypeReader
{
ub1 *buf; /* Pointer to serialized image */
ub4 buflen; /* Length of serialized image */
ub4 offset; /* Offset of reader in image buffer */
uword depth; /* Recursive container depth */
uword flags; /* Mode flags */
ub1 arr[JZN_MAX_DEPTH]; /* Container types */
ub1 tmp[JZN_BINFMT_LEN]; /* Staging buffer */
ub1 dummy[16]; // ### Remove later
jznEventRecord rec; /* Most recent event (OUT) */
jznEventSource source; /* Event source */
} jznAnyTypeReader;
/*
** Reads an event from an anyNode binary image. The current state of the
** reader is maintained in a reader context structure exposed to the caller
** to avoid the need for heap allocations. This structure should be
** initialized to point to the image/length, and the read offset to 0
** before starting to read. The flags should be set to the same as
** they were for the encoder, especially the value of the numeric padding.
*/
sword JsonDomReadAnyType(jznAnyTypeReader *reader);
/*
** Bug 37841761:
** In order to be able to use the AnyType Reader as input to the OSON
** decoder, it needs to behave as an event source. This function will
** initialize the reader's event source side with the right callbacks.
*/
void JsonDomInitAnyTypeReaderEvtSrc(jznAnyTypeReader *reader);
/*--------------------------- Deprecated interfaces -------------------------*/
/*
** Users are not encouraged to use the following deprecated interfaces.
*/
/*
** NAME:
** JsonDomLoadAndEncodeImage
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - document to load events into
** jznEventSource *evtsrc (IN) - event source (such as the JSON parser)
** jznosonFile *ofile (OUT) - OSON file (or NULL)
**
** RETURNS:
** (jznDomNode *) the root node of the DOM, or NULL on error.
**
** DESCRIPTION:
** After constructing an empty jznDomDoc, it can be loaded from an existing
** object in two ways.
**
** When jznDomDoc is JZN_INMEM_DOM type, this method loads a JSON document
** input from a JSON event stream (typically the JSON parser, or a source
** such as the BSON decoder). The ofile parameter can be ignored.
**
** When jznDomDoc is JZN_OSON_DOM type, this method encodes the event
** stream in OSON serialized format and writes the bytes to a file stream
** (the ofile parameter)
**
** NOTES:
** Always check the error code by calling JsonDomGetGetError before proceeding.
**
** ### Legacy interface for compatibility.
*/
jznDomNode *jznDomLoadAndEncodeImage(jznDomDoc *jdoc,
jznEventSource *evtsrc,
jznosonFile *ofile);
/*
** NAME:
** JsonDomGetXmlContext
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (xmlctx *) the XML context underlying this DOM
**
** DESCRIPTION:
** Get the original enviroment context, xmlctx that was used
** to create this jznDomDoc.
*/
#define JsonDomGetXmlContext(jdoc) \
((jdoc)->xctx_jznDomDoc)
/*
** NAME:
** JsonDomSetXmlContext
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** xmlctx *xctx (IN) - New XML context to use for DOM operations
**
** RETURNS:
** (void)
**
** DESCRIPTION:
** Set (override) the XML context for this DOM.
*/
void JsonDomSetXmlContext(jznDomDoc *jdoc, xmlctx *xctx);
/*
** NAME:
** JsonDomGetUserContext
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
**
** RETURNS:
** (void *)
**
** DESCRIPTION:
** Return the user context for this DOM, or NULL if none has been set.
*/
void *JsonDomGetUserContext(JsonDomDoc *doc);
/*
** NAME:
** JsonDomSetUserContext
**
** PARAMETERS:
** jznDomDoc *jdoc (IN) - JSON DOM
** void *usrctx (IN) - User context pointer
**
** RETURNS:
** (void)
**
** DESCRIPTION:
** Set (override) the user defined context pointer for this DOM.
*/
void JsonDomSetUserContext(JsonDomDoc *doc, void *usrctx);
/*
** Internal interface for unwrapping a document that is an array
** with a single element. Returns JZNERR_OK if successful.
*/
sword jznDomUnwrapRootArray(JsonDomDoc *doc);
/*****************************************************************************
* Working with DOM strings in a non-Unicode character set
*****************************************************************************/
/*
** Create a DOM string scalar node given a string in the working character
** set for the associated XmlCtx. Converts the string to UTF-8 if necessary.
*/
JsonDomScalar *jznDomCreateStringNative(JsonDomDoc *doc,
oratext *str, ub4 len);
/*
** Get information about a scalar node. If the node type is a string,
** the value is converted to the working character set for the
** associated XmlCtx. If a conversion is necessary, the returned
** string pointer points to an internal conversion buffer that is
** reused on any similar call. Callers should consume the returned
** value before making any other calls to conversion support methods.
*/
sword jznDomScalarInfoNative(JsonDomDoc *doc,
JsonDomScalar *snode,
jznScalarVal *sinfo);
/*
** Convert a DOM field name to the working character set of the
** associated XmlCtx. This allows callers to retrieve field name/value
** pairs and read the name portion in a non-UTF-8 character set. If
** a conversion is performed, the name string points to an internal
** conversion buffer that is reused on any similar call. Callers should
** consume the returned value before making any other calls to
** conversion support methods.
*/
sword jznDomFieldNameNative(JsonDomDoc *doc, jznDomObjFieldName *name);
/*
** Find a node in the DOM given a name string in the working character set
** of the associated XmlCtx. The node is returned in <node>, or NULL if
** not found. Returns JZNERR_OK on success, otherwise an error code.
** If a conversion is performed, it will reuse an internal conversion
** associated with the document.
*/
sword jznDomGetFieldNative(JsonDomDoc *doc, JsonDomObject *obj,
oratext *name, ub2 len, JsonDomNode **node);
#define jznDomM_LoadFromInputEventSrc(jdoc, evtsrc, ofile) \
jznDomLoadAndEncodeImage((jdoc), (evtsrc), (ofile))
#define jznDomM_LoadFromInputOSON JsonDomLoadImage
#define jznDomM_GetEnvCtx JsonDomGetXmlContext
#define jznDomM_GetNodeType JsonDomGetNodeType
#define jznDomM_GetScalarInfo JsonDomGetScalarInfo
#define jznDomM_GetRootNode JsonDomGetRoot
#define jznDomM_GetNumObjField JsonDomGetNumFields
#define jznDomM_GetFieldVal JsonDomGetFieldValue
#define jznDomM_GetFieldByName JsonDomGetFieldByName
#define jznDomM_GetAllFieldNamesAndVals JsonDomGetAllFields
#define jznDomM_GetFieldNamesAndValsBatch JsonDomGetFields
#define jznDomM_GetArraySize JsonDomGetArraySize
#define jznDomM_GetArrayElem JsonDomGetArrayElement
#define jznDomM_GetArrayElemBatch JsonDomGetElements
#define jznDomM_SetRootNode JsonDomSetRoot
#define jznDomM_PutFieldValue JsonDomSetField
#define jznDomM_PutItem JsonDomAddElement
#define jznDomM_AppendItem JsonDomAppendElement
#define jznDomM_ReplaceItem JsonDomReplaceElement
#define jznDomM_DeleteField JsonDomDeleteField
#define jznDomM_UnlinkField JsonDomUnlinkField
#define jznDomM_RenameField JsonDomRenameField
#define jznDomM_DeleteItem JsonDomDeleteElement
#define jznDomM_UnlinkItem JsonDomUnlinkElement
#define jznDomM_DeleteItemBatch JsonDomDeleteElementRange
#define jznDomM_NewObject JsonDomCreateObject
#define jznDomM_NewArray JsonDomCreateArray
#define jznDomM_NewScalar JsonDomCreateScalar
#define jznDomM_DocReset JsonDomClear
#define jznDomM_DocFree JsonDomFree
#define jznDomM_Equals JsonDomEquals
#define jznDomM_Copy JsonDomCopy
#define jznDomM_GetOutputEventSrc JsonDomToEventSource
#define jznDomM_ValidFid JsonDomCheckFieldKeys
#define jznDomM_Print JsonDomPrintDocument
#define jznDomM_GetError JsonDomGetError
/* ### DEPRECATED interface used by clsjson.c ### */
#define jznDomM_SetError(doc, err) \
((doc)->errcode_jznDomDoc = (err))
/* ### DEPRECATED interface used by clsjson.c ### */
#define jznDomM_PrintNode(jd, pc, nd) \
JsonDomPrintNode((jd),(nd),jznuPrintToWriter((pc)))
/* ### DEPRECATED interface, drop it later ### */
#define jznDomM_SerializeNode(jd, wt, nd) \
JsonDomPrintNode((jd),(nd),(wt))
#ifdef JUST_AN_EXAMPLE
/*
* Following is an example to show how to use JSON DOM APIs to
* write a recursive function jznDomPrint() that navigates the
* JSON DOM tree to print it into JSON text.
*/
STATICF jsonerr jznCheckReportErr(JsonDomDoc *doc)
{
jsonerr err;
oratext *msg;
if ((err = JsonDomGetError(doc)) != JZNERR_OK)
{
msg = jznDomGetErrorMessage(doc, &err, TRUE);
printf("%.*s", (char *)msg);
return err;
}
else
return JZNERR_OK; /* no error */
}
STATICF jsonerr jznDomPrint(JsonDomDoc *doc, JsonDomNode *node)
{
JsonDomNode *np;
jznnodetype ndt = JsonDomGetNodeType(doc, node);
ub4 sz, i;
jsonerr err;
switch (ndt)
{
case JZNDOM_SCALAR:
{
jznScalarVal val;
oratext buf[JZN_SCALAR_VAL_SZ];
ub4 buflen = (ub4)sizeof(buf);
JsonDomGetScalarInfo(doc, (JsonDomScalar *)node, &val);
err = jznCheckReportErr(doc);
if (err != JZNERR_OK)
return err;
jznuScalarToString(JsonDomGetXmlContext(doc),
val.type_jznScalarVal,
&val.uval_jznScalarVal,
buf, &buflen);
printf("%.*s", (int)buflen, buf);
}
break;
case JZNDOM_OBJECT:
{
jznDomNameValuePair *fnma;
ub4 sz = JsonDomGetNumFields(doc, (JsonDomObject *)node);
err = jznCheckReportErr(doc);
if (err != JZNERR_OK)
return err;
fnma = (jznDomNameValuePair *)malloc(sz * sizeof(*fnma));
JsonDomGetAllFields(doc, (JsonDomObject *)node, fnma);
err = jznCheckReportErr(doc);
if (err != JZNERR_OK)
return err;
printf("{");
for (i = 0; i < sz; ++i)
{
jznDomObjFieldName *nmp = &(fnma[i].name_jznDomNameValuePair);
np = JsonDomGetFieldValue(doc, (JsonDomObject *)node, nmp);
err = jznCheckReportErr(doc);
if (err != JZNERR_OK)
return err;
if (i > 0)
printf(",");
printf("\"%.*s\":", nmp->len_jznDomObjFieldName,
nmp->fnm_jznDomObjFieldName);
err = jznDomPrint(doc, np);
if (err != JZNERR_OK)
return err;
}
printf("}");
free(fnma);
}
break;
case JZNDOM_ARRAY:
{
printf("[");
#ifdef SINGLE_ARRAY_API
{
ub4 sz = JsonDomGetArraySize(doc, (JsonDomArray *)node);
err = jznCheckReportErr(doc);
if (err != JZNERR_OK)
return err;
for (i = 0; i < sz; ++i)
{
np = JsonDomGetArrayElement(doc, (JsonDomArray *)node, i);
err = jznCheckReportErr(doc);
if (err != JZNERR_OK)
return err;
err = jznDomPrint(doc, np);
if (err != JZNERR_OK)
return err;
if (i != (sz -1))
printf(",");
}
}
#else
{
// use array batch fetch api, shall be more efficient
JsonDomNode *ndAry[256];
ub4 startpos = 0;
ub4 numfetched = (ub4)(sizeof(ndAry)/sizeof(*ndAry));
boolean first = TRUE;
while (numfetched = JsonDomGetElements(doc, (JsonDomArray *)node,
startpos, numfetched, ndAry))
{
err = jznCheckReportErr(doc);
if (err != JZNERR_OK)
return err;
for (i = 0; i < numfetched; ++i)
{
if (!first)
printf(",");
else
first = FALSE;
np = ndAry[i];
err = jznDomPrint(doc, np);
if (err != JZNERR_OK)
return err;
}
// increment startpos
startpos += numfetched;
}
}
#endif
printf("]");
}
break;
default:
break;
return JZNERR_OK;
}
}
#endif /* JUST_AN_EXAMPLE */
/*****************************************************************************
* DOM Event writer interface - write events to a builder to create a DOM.
*****************************************************************************/
/*
** Stateful DOM builder/writer. This object can be used to
** build a DOM from events.
*/
typedef struct jznDomWriter jznDomWriter;
/*
** Create a stateful context to serve as DOM builder from events.
** This uses memory from the input XML context.
*/
jznDomWriter *jznDomWriterCreate(xmlctx *xctx);
/*
** Create writer with dedicated memory.
*/
jznDomWriter *jznDomWriterCreateEx(xmlctx *xctx, oramemctx *omctx);
/*
** Destroy a stateful DOM writer.
*/
void jznDomWriterDestroy(jznDomWriter *writer);
/*
** Set a specific DOM document to be the writer destination
** This is useful if using a writer to copy a set of events
** into an existing DOM. Use jznWriterGetTree to get the result.
*/
sword jznDomWriterSetDoc(jznDomWriter *writer,
JsonDomDoc *doc, ub4 flags);
/*
** Clear and initialize the writer for a new operation.
** This is necessary if the prior operation wasn't completed or
** ended in an error condition.
** If a target document remained from the prior operation, it's returned
** and the writer's internal target is cleared.
*/
jznDomDoc *jznDomWriterClear(jznDomWriter *writer);
/*
** Get a handle to an event writer from the stateful DOM writer.
*/
jznEventWriter *jznDomWriterGetSink(jznDomWriter *writer);
/*
** The flags that are relevant are DOM-related creation flags
*/
void jznDomWriterSetFlags(jznDomWriter *ctx, ub4 flags);
/*
** Get the count of events written to the DOM under construction
** from the DOM writer.
*/
ub4 jznDomWriterGetWrtCnt(jznDomWriter *writer);
/*
** Write a textual JSON into the target DOM for this writer.
** The text needs to be in a Unicode format (UTF-8 or UTF-16).
** The length is in bytes.
** This is useful as a convenience for creating a DOM from a string.
*/
sword jznDomWriterParse(jznDomWriter *writer, void *buf, ub4 buflen);
/*
** Consume events from a source and send them to the DOM writer.
** This interface will stop when it has consumed an entire JSON
** item, such as an object or array. It will not read until the
** JZNEV_END event occurs. It can therefore be used to read/load
** sub-objects.
*/
sword jznDomWriterReadSource(jznDomWriter *writer,
jznEventSource *eventSource);
/*
** Consume all events remaining in a source and put them to the writer.
** This interface continues to read until a JZNEV_END event is delievered.
** It's designed to load an entire JSON document.
*/
sword jznDomWriterReadAll(jznDomWriter *writer,
jznEventSource *eventSource);
/*
** Returns the DOM node at the root of the subtree built by this writer.
** The caller is assumed to have the document, e.g. by calling
** jznDomWriterSetDoc() first.
** Returns NULL if there's an error or if the tree is incomplete.
*/
JsonDomNode *jznDomWriterGetTree(jznDomWriter *writer);
/*
** Returns the DOM built by this writer.
** Internally, the root node is set to the top of the tree built
** by the events, and the document is detached and returned from
** the writer.
** Returns NULL if there's an error or if the DOM is incomplete.
*/
JsonDomDoc *jznDomWriterBuild(jznDomWriter *writer);
/*
** Returns the orphan node subtree built by this writer.
** The document is detached from the writer internally;
** the caller is assumed to have a reference to it.
*/
JsonDomNode *jznDomWriterBuildTree(jznDomWriter *writer);
/*
** Get the document under construction, if any. This returns
** the document node even if it's incomplete and/or hasn't yet
** had the root set (which Build does). Leaves the in-process
** construction unchanged. Internal use only!
*/
JsonDomDoc *jznDomWriterGetDoc(jznDomWriter *writer);
/*
** Get a count of events written so far to the writer.
** In the reset state, this is 0.
*/
ub4 jznDomWriterGetCount(jznDomWriter *writer);
/*
** Release a DOM back to the writer for reuse.
*/
void jznDomWriterRelease(jznDomWriter *writer, JsonDomDoc *doc);
void jznDomWriterSetXmlCtx(jznDomWriter *writer, xmlctx *xctx);
/*****************************************************************************
* DOM Event source interface - pull events from a DOM node tree
*****************************************************************************/
/*
** Stateful DOM reader/eventer.
** This object can be used to set up an event source starting from
** any node in the DOM. This object is stateful; it can provide one
** event source at a time. The source is backed by the DOM, which
** should not be changed during event production.
*/
typedef struct jznDomReader jznDomReader;
/*
** Create a reader context to serve as source of DOM events.
** This uses memory from the input XML context.
*/
jznDomReader *jznDomReaderCreate(xmlctx *xctx);
/*
** Create reader with dedicated memory.
*/
jznDomReader *jznDomReaderCreateEx(xmlctx *xctx, oramemctx *omctx);
/*
** Set up a handle to an event source given a DOM and optional start node.
** If the input node is NULL, events start at the DOM root node.
*/
jznEventSource *jznDomReaderInit(jznDomReader *reader,
JsonDomDoc *doc, JsonDomNode *node);
/*
** Destroy a DOM reader.
*/
void jznDomReaderDestroy(jznDomReader *reader);
/*
** Set mode flags such as:
** JZN_USE_EXTENSION_TYPES
*/
void jznDomReaderSetFlags(jznDomReader *reader, ub4 flags);
void jznDomReaderSetXmlCtx(jznDomReader *reader, xmlctx *xctx);
/*
** SAX traversal of a DOM from a given node
*/
sword JsonSaxDom(JsonDomDoc *doc, JsonDomNode *node,
JsonSaxHandler cb, void *cbctx);
/*
** Render the JSON column modifier <jtmf> as a string.
** Output string is to <jtms>[<jtmslen>] up to <maxlen> bytes.
*/
jsonerr jznDomRenderModifier(jznComplexAttributes *jtmf,
char *jtms, ub4 *jtmslen, ub4 maxlen,
boolean check, boolean modifierOnly);
void jznDom_jtmStr(jznComplexAttributes *jtmf,
jsonerr *errp, char *jtms, ub4 *jtmslen, ub4 maxlen,
boolean check, boolean modifierOnly);
/*
** JSON type modifier check against DOM
** bug fix 36817752
*/
#define JZNDOM_CHK_STR_SZ 128
typedef struct jznDomModChkCx
{
jznComplexAttributes mod_jznDomModChkCx;
char *str_jznDomModChkCx;
ub4 len_str_jznDomModChkCx;
ub4 osonlim_jznDomModChkCx; /* oson size limit */
char inst_jznDomModChkCx[JZNDOM_CHK_STR_SZ];
ub1 flag_jznDomModChkCx; /* input flag */
#define JZNDOMCHK_ALLOW_SAME_FAM 0x01
/* array of same scalar value family is allowed. for example, all numbers
* in number family, all date, timestamp, timeestamp with timezone are
* allowed during json type modifier check
*/
ub1 oflag_jznDomModChkCx; /* output flag */
#define JZNDOMCHK_SORT_FAILED 0x01
/* array element value is out of order (not sorted) */
#define JZNDOMCHK_SORT_FAILED_ONLY 0x2
/* the only failure is due to array element value is out of order */
ub1 spare_jznDomModChkCx[6];
} jznDomModChkCx;
#define JZNDOM_INIT_MODCHK(ctxp)\
do{\
CLRSTRUCT(ctxp->mod_jznDomModChkCx);\
ctxp->str_jznDomModChkCx = NULL;\
ctxp->len_str_jznDomModChkCx = 0;\
ctxp->osonlim_jznDomModChkCx = 0;\
ctxp->inst_jznDomModChkCx[0];\
ctxp->inst_jznDomModChkCx[1];\
ctxp->flag_jznDomModChkCx = 0;\
ctxp->oflag_jznDomModChkCx = 0;\
memset(ctxp->spare_jznDomModChkCx, 0, 6);\
} while (0)
/* check json modifier against a DOM */
jsonerr jznDomChkJModifier(JsonDomDoc *srcDoc, JsonDomNode *node,
jznDomModChkCx *mod);
sword jznDomFlattenScalar(jznScalarVal *sinfo, uword flags,
ub1 *outbuf, ub4 outsz, ub4 *outlen);
#define JZNDOM_FIELD_CASE_NONE 0x0000
#define JZNDOM_FIELD_CASE_UPPER 0x0001
#define JZNDOM_FIELD_CASE_LOWER 0x0002
/*
** Convert the fields of a JSON document node to upper or lower case.
** Returns JZNERR_OK if successful, JZNERR_NO_DIFFERENCES if no changes
** were made, otherwise an error code. The caller must pass a scratch
** buffer of 32K size to support case conversions.
*/
sword JsonDomFieldCase(JsonDomDoc *doc, JsonDomNode *node,
oratext *scratch, uword flags);
/*
* This function constructs
* {"key" : "keystring", "value": <input_val_node>, "id" : idval }
* as result of keyvalue() func.
* "keystring" and idval are stored in jzntypes_KVInf.
* <input_val_node> is a json dom node under <input_doc>
*/
jznDomObject *JsonDomConsKeyValueObj(
jznDomDoc *target_doc, jzntypes_KVInf *kvinf,
jznDomDoc *input_doc, jznDomNode *input_val_node, jsonerr *err);
/*
* This function constructs an array of kv objects
* {"key" : "keystring", "value": <input_val_node>, "id" : idval }
* as result of keyvalue() func.
* "keystring" and idval are stored in *jzntypes_KVInf.
* *<input_val_node> is json dom nodes under <input_doc>
*/
jznDomArray *JsonDomConsKeyValueObjAry(
jznDomDoc *target_doc,
jzntypes_KVInf kvinf[], /* it is an array of struct jzntypes_KVInf */
ub4 num_kv, /* array size of kvinf */
jznDomDoc *input_doc,
jznDomNode *input_val_node[],/*its array size is the input <num_kv> param*/
jsonerr *err);
#endif /* JZNDOM_ORACLE */