/* ---------------------------------------------------------------------- Oracle Data Structures. Copyright (c) 2003, 2008, Oracle. All rights reserved. ---------------------------------------------------------------------- */ #ifndef ORASTRUC # define ORASTRUC # ifndef ORATYPES # include # endif typedef ub4 oraerr; /* Error code: 0 is success, non-0 is failure */ #define ORAERR_OK 0 /* Universal success code */ typedef ub4 oracheck; /* Checkword for validating data structures */ #if 0 /* COMMENT */ -------------------------------------------------------------------------- Hooked Memory Allocation Covers for the standard memory allocation functions that allow user hooks to replace standard calls. Use the function prototype macros ORAMEM_ALLOC_F and ORAMEM_FREE_F to declare callbacks; if neither is provided, malloc() and free() are used. Either both or neither must be given, you cannot mix them. STATICF ORAMEM_ALLOC_F(my_alloc, mctx, size) { mycontext *myctx = mctx; void *ptr; /* return value */ ... return _my_funky_alloc(myctx, size); } STATICF ORAMEM_FREE_F(my_free, mctx, ptr) { mycontext *myctx = mctx; ... _my_funky_free(myctx, ptr); } main() { oramemctx *memctx; mycontext myctx; ... /* initialize myctx here */ memctx = OraMemInit(&myctx, my_alloc, my_free); a = OraMemAlloc(memctx, 1000); b = OraMemAlloc(memctx, sizeof(double)); ... OraMemFree(memctx, a); OraMemFree(memctx, b); OraMemTerm(memctx); ... } -------------------------------------------------------------------------- #endif /* if 0 COMMENT */ /* Opaque memory context */ struct oramemctx; typedef struct oramemctx oramemctx; /* Function prototype macros */ #define ORAMEM_ALLOC_F(func, mctx, size) void *func(void *mctx, size_t size) #define ORAMEM_FREE_F(func, mctx, ptr) void func(void *mctx, void *ptr) /* Create & Destroy memory context */ oramemctx *OraMemInit(void *mctx, ORAMEM_ALLOC_F((*alloc), mctx, size), ORAMEM_FREE_F((*free), mctx, ptr)); void OraMemTerm(oramemctx *memctx); /* Allocate & Free memory */ void *OraMemAlloc(oramemctx *memctx, size_t size); void *OraMemCalloc(oramemctx *memctx, size_t size); void OraMemFree(oramemctx *memctx, void *ptr); /*-------------------------------------------------------------------------- Named Properties Some complex top-level APIs take variable-argument name-value pairs instead of a fixed set of arguments, to increase flexibility. Properties of this sort are defined by a name, a type, and an enum ID. When multiple sets of pairs is needed, separate them with ORAPROP_SEP. -------------------------------------------------------------------------- */ #define ORAPROP_SEP "__PROPERTY_SEPARATOR__" typedef sb2 oraprop_id; /* >= 0 valid, < 0 invalid */ /* type: property value type */ typedef enum { ORAPROP_TYPE_BOOLEAN, /* (boolean) */ ORAPROP_TYPE_SIGNED, /* (sb4) */ ORAPROP_TYPE_UNSIGNED, /* (ub4) */ ORAPROP_TYPE_POINTER /* (void *) */ } oraprop_t; /* value: union of storage for all data types */ typedef union oraprop_v { boolean b_oraprop_v; /* boolean */ sb4 s_oraprop_v; /* signed scalar */ ub4 u_oraprop_v; /* unsigned scalar */ void *p_oraprop_v; /* pointer */ } oraprop_v; /* property */ typedef struct oraprop { oratext *name_oraprop; /* name of property [compiler enc.] */ oraprop_id id_oraprop; /* unique numeric ID for property */ oraprop_t type_oraprop; /* value type */ oraprop_v value_oraprop; /* value storage */ } oraprop; /* convenient macro for constructing property tables */ #define ORAPROP(name, id, type) \ { (oratext *) name, (oraprop_id) id, ORAPROP_TYPE_##type } #define ORAPROP_ERR_NULL_PTR 1 /* NULL pointer argument */ #define ORAPROP_ERR_NO_PROPERTY 2 /* no such named property */ /* given a property table and a property name, look it up it table */ oraprop *OraPropGet(oraprop *proptab, oratext *name); /* look up property by name and return it's value (if type is known) */ oraerr OraPropGetBoolean(oraprop *proptab, oratext *name, boolean *value); oraerr OraPropGetSigned(oraprop *proptab, oratext *name, sb4 *value); oraerr OraPropGetUnsigned(oraprop *proptab, oratext *name, ub4 *value); oraerr OraPropGetPointer(oraprop *proptab, oratext *name, void **value); /*-------------------------------------------------------------------------- Streaming data Generic streaming data/chunking API. All functions return an error code, zero on success. All functions take a user-defined context pointer and a user-defined stream identifier . ---------------- Creation properties (OraStreamInit) -------------------- Creation properties (OraStreamInit) are: PROPERTY NAME PROPERTY VALUE "oramem_context" (oramemctx *) Where to allocate memory for stream object (default: malloc) PROPERTY NAME PROPERTY VALUE "open" ORASTREAM_OPEN_F((*), sctx, sid, hdl, length) Open function. Not required. PROPERTY NAME PROPERTY VALUE "close" ORASTREAM_CLOSE_F((*), sctx, sid, hdl) Close function. Not required. PROPERTY NAME PROPERTY VALUE "read" ORASTREAM_READ_F((*), sctx, sid, hdl, dest, size, start, nread, eoi) Read byte data from stream to buf. nread returns number of bytes actually read. PROPERTY NAME PROPERTY VALUE "write" ORASTREAM_WRITE_F((*), sctx, sid, hdl, src, size, written) Write byte data from buf to stream. Number of bytes actually written is returned through . PROPERTY NAME PROPERTY VALUE "read_char" ORASTREAM_READ_F((*), sctx, sid, hdl, dest, size, start, nread, eoi) Read character data from stream to buf. nread returns number of chars actually read. PROPERTY NAME PROPERTY VALUE "write_char" ORASTREAM_WRITE_F((*), sctx, sid, hdl, src, size, written) Write character data from buf to stream. Number of chars actually written is returned through . Streams are byte or character mode: If "read" or "write" is provided, the stream operates in byte mode using OraStreamRead() and OraStreamWrite(). If "read_char" or "write_char" is provided, the stream operates in character mode using OraStreamReadChar() and OraStreamWriteChar(). In char mode, only complete chars are read/written, and are never split over buffer boundaries. Streams are unidirectional: Only one read or write function must be provided, but not both. ------------------ Storage for file handles, etc ----------------------- */ typedef union orastreamhdl { void *ptr_orastreamhdl; /* generic pointer stream/file/etc */ struct { sb4 fd_orastreamhdl; /* file descriptor(s) [FTP needs all 3!] */ sb4 fd2_orastreamhdl; sb4 fd3_orastreamhdl; } fds_lpihdl; } orastreamhdl; /* ----------------- Accessor macros for stream handles ------------------ */ #define ORASTREAM_PTR(hdl) hdl->ptr_orastreamhdl #define ORASTREAM_FD(hdl) hdl->fds_lpihdl.fd_orastreamhdl #define ORASTREAM_FD2(hdl) hdl->fds_lpihdl.fd2_orastreamhdl #define ORASTREAM_FD3(hdl) hdl->fds_lpihdl.fd3_orastreamhdl /* ------------------- Stream Function Prototype Macros ------------------- */ /* Open stream ; if total size of data is known, is set (if not NULL). */ #define ORASTREAM_OPEN_F(func, sctx, sid, hdl, length) \ oraerr func(void *sctx, void *sid, orastreamhdl *hdl, ubig_ora *length) /* Close stream */ #define ORASTREAM_CLOSE_F(func, sctx, sid, hdl) \ oraerr func(void *sctx, void *sid, orastreamhdl *hdl) /* Read from stream into buffer which is of size bytes; is set to the # of bytes or characters read, and set to TRUE if this is the last chunk of data. is updated to point to the first actual data bytes in the buffer (e.g. first HTTP buffer contains a header which is skipped over). */ #define ORASTREAM_READ_F(func, sctx, sid, hdl, dest, size, start, nread, eoi) \ oraerr func(void *sctx, void *sid, orastreamhdl *hdl, oratext *dest, \ ubig_ora size, oratext **start, ubig_ora *nread, ub1 *eoi) /* Write to stream the bytes of data at ; the number of bytes or characters successfully written is returned through */ #define ORASTREAM_WRITE_F(func, sctx, sid, hdl, src, size, written) \ oraerr func(void *sctx, void *sid, orastreamhdl *hdl, \ oratext *src, ubig_ora size, ubig_ora *written) /* ------------------------ Opaque Stream Object ------------------------ */ struct orastream; typedef struct orastream orastream; /* -------------------------- Stream Functions -------------------------- */ /* Initialize & Destroy stream object */ orastream *OraStreamInit(void *sctx, void *sid, oraerr *err, ...); oraerr OraStreamTerm(orastream *stream); /* [Re]Set SID for stream (returns old SID through )*/ oraerr OraStreamSid(orastream *stream, void *sid, void **osid); /* Is a stream readable or writable? */ boolean OraStreamReadable(orastream *stream); boolean OraStreamWritable(orastream *stream); /* DEPRECATED DUE TO TYPO IN FUNCTION NAME; USE OraStreamWritable() INSTEAD */ boolean OraStreamWriteable(orastream *stream); /* Open & Close stream */ oraerr OraStreamOpen(orastream *stream, ubig_ora *length); oraerr OraStreamClose(orastream *stream); /* Read | Write byte stream */ oraerr OraStreamRead(orastream *stream, oratext *dest, ubig_ora size, oratext **start, ubig_ora *nread, ub1 *eoi); oraerr OraStreamWrite(orastream *stream, oratext *src, ubig_ora size, ubig_ora *nwrote); /* Read | Write char stream */ oraerr OraStreamReadChar(orastream *stream, oratext *dest, ubig_ora size, oratext **start, ubig_ora *nread, ub1 *eoi); oraerr OraStreamWriteChar(orastream *stream, oratext *src, ubig_ora size, ubig_ora *nwrote); /* Return handles for stream */ orastreamhdl *OraStreamHandle(orastream *stream); /* Return the cloned stream object */ orastream *OraStreamClone(oramemctx *mem, void *sid, orastream *source, oraerr *errcode); /* Returns status if the stream object is currently opened */ boolean OraStreamIsOpen(orastream *stream); /* -------------------------- Stream Error Codes ------------------------- */ #define ORASTREAM_ERR_NULL_POINTER 1 /* NULL pointer given */ #define ORASTREAM_ERR_BAD_STREAM 2 /* invalid stream object */ #define ORASTREAM_ERR_WRONG_DIRECTION 3 /* tried wrong-direction I/O */ #define ORASTREAM_ERR_UNKNOWN_PROPERTY 4 /* unknown creation prop */ #define ORASTREAM_ERR_NO_DIRECTION 5 /* neither read nor write? */ #define ORASTREAM_ERR_BI_DIRECTION 6 /* both read any write? */ #define ORASTREAM_ERR_NOT_OPEN 7 /* stream not open */ #define ORASTREAM_ERR_WRONG_MODE 8 /* wrote byte/char mode */ /* --- Open errors --- */ #define ORASTREAM_ERR_CANT_OPEN 10 /* can't open stream */ /* --- Close errors --- */ #define ORASTREAM_ERR_CANT_CLOSE 20 /* can't close stream */ #endif /* ifndef ORASTRUC */