Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# ext/syck/yamlbyte.h

Go to the documentation of this file.

    00001 /*  yamlbyte.h
    00002  *
    00003  *  The YAML bytecode "C" interface header file.   See the YAML bytecode
    00004  *  reference for bytecode sequence rules and for the meaning of each
    00005  *  bytecode.
    00006  */
    00007
    00008 #ifndef YAMLBYTE_H
    00009 #define YAMLBYTE_H
    00010 #include <stddef.h>
    00011
    00012 /* define what a character is */
    00013 typedef unsigned char yamlbyte_utf8_t;
    00014 typedef unsigned short yamlbyte_utf16_t;
    00015 #ifdef YAMLBYTE_UTF8
    00016   #ifdef YAMLBYTE_UTF16
    00017     #error Must only define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
    00018   #endif
    00019   typedef yamlbyte_utf8_t yamlbyte_char_t;
    00020 #else
    00021   #ifdef YAMLBYTE_UTF16
    00022     typedef yamlbyte_utf16_t yamlbyte_char_t;
    00023   #else
    00024     #error Must define YAMLBYTE_UTF8 or YAMLBYTE_UTF16
    00025   #endif
    00026 #endif
    00027
    00028 /* specify list of bytecodes */
    00029 #define YAMLBYTE_FINISH          ((yamlbyte_char_t) 0)
    00030 #define YAMLBYTE_DOCUMENT        ((yamlbyte_char_t)'D')
    00031 #define YAMLBYTE_DIRECTIVE       ((yamlbyte_char_t)'V')
    00032 #define YAMLBYTE_PAUSE           ((yamlbyte_char_t)'P')
    00033 #define YAMLBYTE_MAPPING         ((yamlbyte_char_t)'M')
    00034 #define YAMLBYTE_SEQUENCE        ((yamlbyte_char_t)'Q')
    00035 #define YAMLBYTE_END_BRANCH      ((yamlbyte_char_t)'E')
    00036 #define YAMLBYTE_SCALAR          ((yamlbyte_char_t)'S')
    00037 #define YAMLBYTE_CONTINUE        ((yamlbyte_char_t)'C')
    00038 #define YAMLBYTE_NEWLINE         ((yamlbyte_char_t)'N')
    00039 #define YAMLBYTE_NULLCHAR        ((yamlbyte_char_t)'Z')
    00040 #define YAMLBYTE_ANCHOR          ((yamlbyte_char_t)'A')
    00041 #define YAMLBYTE_ALIAS           ((yamlbyte_char_t)'R')
    00042 #define YAMLBYTE_TRANSFER        ((yamlbyte_char_t)'T')
    00043 /* formatting bytecodes */
    00044 #define YAMLBYTE_COMMENT         ((yamlbyte_char_t)'c')
    00045 #define YAMLBYTE_INDENT          ((yamlbyte_char_t)'i')
    00046 #define YAMLBYTE_STYLE           ((yamlbyte_char_t)'s')
    00047 /* other bytecodes */
    00048 #define YAMLBYTE_LINE_NUMBER     ((yamlbyte_char_t)'#')
    00049 #define YAMLBYTE_WHOLE_SCALAR    ((yamlbyte_char_t)'<')
    00050 #define YAMLBYTE_NOTICE          ((yamlbyte_char_t)'!')
    00051 #define YAMLBYTE_SPAN            ((yamlbyte_char_t)')')
    00052 #define YAMLBYTE_ALLOC           ((yamlbyte_char_t)'@')
    00053
    00054 /* second level style bytecodes, ie "s>" */
    00055 #define YAMLBYTE_FLOW            ((yamlbyte_char_t)'>')
    00056 #define YAMLBYTE_LITERAL         ((yamlbyte_char_t)'|')
    00057 #define YAMLBYTE_BLOCK           ((yamlbyte_char_t)'b')
    00058 #define YAMLBYTE_PLAIN           ((yamlbyte_char_t)'p')
    00059 #define YAMLBYTE_INLINE_MAPPING  ((yamlbyte_char_t)'{')
    00060 #define YAMLBYTE_INLINE_SEQUENCE ((yamlbyte_char_t)'[')
    00061 #define YAMLBYTE_SINGLE_QUOTED   ((yamlbyte_char_t)39)
    00062 #define YAMLBYTE_DOUBLE_QUOTED   ((yamlbyte_char_t)'"')
    00063
    00064 /*
    00065  * The "C" API has two variants, one based on instructions,
    00066  * with events delivered via pointers; and the other one
    00067  * is character based where one or more instructions are
    00068  * serialized into a buffer.
    00069  *
    00070  * Note: In the instruction based API, WHOLE_SCALAR does
    00071  *       not have the '<here' marshalling stuff.
    00072  */
    00073
    00074 typedef void * yamlbyte_consumer_t;
    00075 typedef void * yamlbyte_producer_t;
    00076
    00077 /* push and pull APIs need a way to communicate results */
    00078 typedef enum {
    00079     YAMLBYTE_OK          = 0,     /* proceed                        */
    00080     YAMLBYTE_E_MEMORY    = 'M',   /* could not allocate memory      */
    00081     YAMLBYTE_E_READ      = 'R',   /* input stream read error        */
    00082     YAMLBYTE_E_WRITE     = 'W',   /* output stream write error      */
    00083     YAMLBYTE_E_OTHER     = '?',   /* some other error condition     */
    00084     YAMLBYTE_E_PARSE     = 'P',   /* parse error, check bytecodes   */
    00085     YAMLBYTE_MAX
    00086 } yamlbyte_result_t;
    00087
    00088 typedef const yamlbyte_char_t *yamlbyte_buff_t;
    00089
    00090 /*
    00091  *  The "Instruction" API
    00092  */
    00093
    00094 typedef struct yaml_instruction {
    00095     yamlbyte_char_t bytecode;
    00096     yamlbyte_buff_t start;
    00097     yamlbyte_buff_t finish;  /* open range, *finish is _not_ part */
    00098 } *yamlbyte_inst_t;
    00099
    00100 /* producer pushes the instruction with one bytecode event to the
    00101  * consumer; if the consumer's result is not YAMLBYTE_OK, then
    00102  * the producer should stop */
    00103 typedef
    00104   yamlbyte_result_t
    00105    (*yamlbyte_push_t)(
    00106      yamlbyte_consumer_t self,
    00107      yamlbyte_inst_t  inst
    00108    );
    00109
    00110 /* consumer pulls a bytecode instruction from the producer; in this
    00111  * case the instruction (and is buffer) are owned by the producer and
    00112  * will remain valid till the pull function is called once again;
    00113  * if the instruction is NULL, then there are no more results; and
    00114  * it is important to call the pull function till it returns NULL so
    00115  * that the producer can clean up its memory allocations */
    00116 typedef
    00117    yamlbyte_result_t
    00118     (*yamlbyte_pull_t)(
    00119       yamlbyte_producer_t self,
    00120       yamlbyte_inst_t *inst   /* to be filled in by the producer */
    00121     );
    00122
    00123 /*
    00124  *  Buffer based API
    00125  */
    00126
    00127 /* producer pushes a null terminated buffer filled with one or more
    00128  * bytecode events to the consumer; if the consumer's result is not
    00129  * YAMLBYTE_OK, then the producer should stop */
    00130 typedef
    00131   yamlbyte_result_t
    00132    (*yamlbyte_pushbuff_t)(
    00133      yamlbyte_consumer_t self,
    00134      yamlbyte_buff_t  buff
    00135    );
    00136
    00137 /* consumer pulls bytecode events from the producer; in this case
    00138  * the buffer is owned by the producer, and will remain valid till
    00139  * the pull function is called once again; if the buffer pointer
    00140  * is set to NULL, then there are no more results; it is important
    00141  * to call the pull function till it returns NULL so that the
    00142  * producer can clean up its memory allocations */
    00143 typedef
    00144    yamlbyte_result_t
    00145     (*yamlbyte_pullbuff_t)(
    00146       yamlbyte_producer_t self,
    00147       yamlbyte_buff_t *buff   /* to be filled in by the producer */
    00148     );
    00149
    00150 /* convert a pull interface to a push interface; the reverse process
    00151  * requires threads and thus is language dependent */
    00152 #define YAMLBYTE_PULL2PUSH(pull,producer,push,consumer,result)       \
    00153     do {                                                         \
    00154         yamlbyte_pullbuff_t _pull = (pull);                              \
    00155         yamlbyte_pushbuff_t _push = (push);                              \
    00156         yamlbyte_result_t _result = YAMLBYTE_OK;                         \
    00157         yamlbyte_producer_t _producer = (producer);                  \
    00158         yamlbyte_consumer_t _consumer = (consumer);                  \
    00159         while(1) {                                               \
    00160             yamlbyte_buff_t buff = NULL;                           \
    00161             _result = _pull(_producer,&buff);                    \
    00162             if(YAMLBYTE_OK != result || NULL == buff)                \
    00163                 break;                                           \
    00164             _result = _push(_consumer,buff);                     \
    00165             if(YAMLBYTE_OK != result)                                \
    00166                 break;                                           \
    00167         }                                                        \
    00168         (result) = _result;                                      \
    00169     } while(0)
    00170
    00171 #endif
    00172