Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

dt_stream_validator.c

Go to the documentation of this file.
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; /*throw invalid data pointers */
00063 
00064    enclosure = o->buf.strEnd[-1];
00065    switch( enclosure )
00066    {
00067    case 'I':   o->buf.begin[0] = 'B'; /* initialization --> mark Bottom of stack */
00068                break;
00069 
00070    case 'B':   if ( step->kind != dt_end )
00071                   return 0;/*throw("Received new data while expecting end of visit."); */
00072                break;
00073    
00074    case 'X':   return 0;/*throw("Unexpected visitor call after end of visit."); */
00075 
00076    default:    assert( enclosure=='A' || enclosure=='R' );
00077    }
00078 
00079 
00080    switch( step->kind )
00081    {
00082    default:          return 0;/*throw("ValidationVisitor::visit : unknown data type"); */
00083 
00084    case dt_leaf:     if( ! step->val )
00085                         return 0;/*throw("Missing data value while visiting a leaf node"); */
00086                      break;
00087 
00088    case dt_rec_in:   if( ! dt_buf_append(& o->buf, 'R') ) return 0;/*OUT OF MEM */
00089                         break;
00090 
00091    case dt_rec_out:  if( 'R' != enclosure )
00092                         return 0;/*throw("Unexpected end of record"); */
00093                      -- o->buf.strEnd;
00094                      enclosure = '?';  /* key (re)transmission is not expected */
00095                      break;
00096 
00097    case dt_arr_in:   if( ! dt_buf_append(& o->buf, 'A') ) return 0;/*OUT OF MEM */
00098                         break;
00099 
00100    case dt_arr_out:  if( 'A' != enclosure )
00101                         return 0;/*throw("Unexpected end of array"); */
00102                      -- o->buf.strEnd;
00103                      enclosure = '?';  /* key (re)transmission is not expected */
00104                      break;
00105 
00106    case dt_end:      if( 'B' != enclosure && 'I' != enclosure )
00107                         return 0;/*throw("Unexpected end of visit"); */
00108                      o->buf.begin[0] = 'X';
00109                      break;
00110    }
00111 
00112 
00113    if( !! step->key )
00114    {
00115       if( 'R' != enclosure  &&  '?' != enclosure )
00116          return 0;/*throw("Unexpected key received out of a record."); */
00117    }
00118    else
00119    {
00120       if( 'R' == enclosure )
00121          return 0;/*throw("Key identifier missing within a record."); */
00122    }
00123 
00124 
00125    if( !! step->val  &&  step->kind != dt_leaf )
00126       return 0;/*throw("Unexpected data value while not visiting a leaf node."); */
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 /* type-check */
00137          && o->buf.begin[0] == 'X';
00138 }
00139 
00140 

Generated on Sun Jun 1 16:35:38 2003 for datatree by doxygen 1.3.1