00001
00004 #include "dt_stream_validator.h"
00005
00006 #include "dt_stream_base.h"
00007 #include "dt_buf.h"
00008
00009 #include <assert.h>
00010 #include <stdlib.h>
00011
00012
00014 typedef struct
00015 {
00016 dt_writer base;
00017 dt_buf buf;
00018 dt_writer* delegate;
00019 } dt_writer_validator;
00020
00022 static void dt_writer_validator_free( dt_writer* obj );
00024 static dt_bool dt_writer_validator_write( dt_writer* obj, dt_stream_step const* step );
00025
00026
00027 dt_writer* dt_create_validator_writer( dt_writer* delegate )
00028 {
00029 dt_writer_validator* ans
00030 = (dt_writer_validator*)malloc(sizeof(dt_writer_validator));
00031 if( ans )
00032 {
00033 dt_init_writer_base( & ans->base, & dt_writer_validator_free, & dt_writer_validator_write );
00034 ans->delegate = delegate;
00035 if( dt_buf_init( & ans->buf ) )
00036 {
00037 if( dt_buf_append( & ans->buf, 'I' ) )
00038 return & ans->base;
00039 dt_buf_free( & ans->buf );
00040 }
00041 free( ans );
00042 }
00043 return 00;
00044 }
00045
00046 static void dt_writer_validator_free(dt_writer* obj)
00047 {
00048 dt_writer_validator* o = (dt_writer_validator*)obj;
00049 dt_buf_free( & o->buf );
00050 free( o );
00051 }
00052
00053 static dt_bool dt_writer_validator_write(dt_writer* obj, dt_stream_step const* step)
00054 {
00055 dt_writer_validator* o = (dt_writer_validator*)obj;
00056 dt_byte enclosure;
00057
00058 assert( o->buf.strEnd > o->buf.begin );
00059
00060 if( ( ! step->key && !! step->key_len )
00061 || ( ! step->val && !! step->val_len )
00062 ) return 0;
00063
00064 enclosure = o->buf.strEnd[-1];
00065 switch( enclosure )
00066 {
00067 case 'I': o->buf.begin[0] = 'B';
00068 break;
00069
00070 case 'B': if ( step->kind != dt_end )
00071 return 0;
00072 break;
00073
00074 case 'X': return 0;
00075
00076 default: assert( enclosure=='A' || enclosure=='R' );
00077 }
00078
00079
00080 switch( step->kind )
00081 {
00082 default: return 0;
00083
00084 case dt_leaf: if( ! step->val )
00085 return 0;
00086 break;
00087
00088 case dt_rec_in: if( ! dt_buf_append(& o->buf, 'R') ) return 0;
00089 break;
00090
00091 case dt_rec_out: if( 'R' != enclosure )
00092 return 0;
00093 -- o->buf.strEnd;
00094 enclosure = '?';
00095 break;
00096
00097 case dt_arr_in: if( ! dt_buf_append(& o->buf, 'A') ) return 0;
00098 break;
00099
00100 case dt_arr_out: if( 'A' != enclosure )
00101 return 0;
00102 -- o->buf.strEnd;
00103 enclosure = '?';
00104 break;
00105
00106 case dt_end: if( 'B' != enclosure && 'I' != enclosure )
00107 return 0;
00108 o->buf.begin[0] = 'X';
00109 break;
00110 }
00111
00112
00113 if( !! step->key )
00114 {
00115 if( 'R' != enclosure && '?' != enclosure )
00116 return 0;
00117 }
00118 else
00119 {
00120 if( 'R' == enclosure )
00121 return 0;
00122 }
00123
00124
00125 if( !! step->val && step->kind != dt_leaf )
00126 return 0;
00127
00128
00129 return (! o->delegate) || dt_write( o->delegate, step );
00130 }
00131
00132
00133 dt_bool dt_validator_writer_completed( dt_writer* validator )
00134 {
00135 dt_writer_validator* o = (dt_writer_validator*)validator;
00136 return o->base.free_impl == & dt_writer_validator_free
00137 && o->buf.begin[0] == 'X';
00138 }
00139
00140