Polaris: BinRep.cc Source File

BinRep.cc

Go to the documentation of this file.
00001 ///
00002 #include "define.h"
00003 
00004 #ifdef POLARIS_GNU_PRAGMAS
00005 #pragma implementation
00006 #endif
00007 
00008 #include <stdio.h>
00009 #include <memory.h>
00010 
00011 #include "BinRep.h"
00012 #include "BinPtr.h"
00013 #include "MemBuf.h"
00014 #include "debug.h"
00015 #include "String.h"
00016 #include "IntElem.h"
00017 #include "Collection/Iterator.h"
00018 #include "Collection/Mutator.h"
00019 #include "Collection/KeyIterator.h"
00020 #include "macros.h"
00021 
00022 /// Return the number of bytes needed to represent the value x.
00023 
00024 static int
00025 bytes_per_value( int x )
00026 {
00027     if (x >= -128 && x <= 127)
00028         return 1;
00029     else if (x >= -32768 && x <= 32767)
00030         return 2;
00031     return 4;
00032 }
00033 
00034 inline BINSTR_TYPE
00035 select_type( int size, BINSTR_TYPE t1, BINSTR_TYPE t2, BINSTR_TYPE t3 )
00036 {
00037     if (size == 1)
00038         return t1;
00039     else if (size == 2)
00040         return t2;
00041     return t3;
00042 }
00043 
00044 /// Create an uninitialized BinRep object.
00045 
00046 BinRep::BinRep()
00047 {
00048     #ifdef CLASS_INSTANCE_REGISTRY
00049     register_instance(BIN_REP, sizeof(BinRep), this);
00050     #endif
00051 
00052     _fc = _ILLEGAL_TYPES;
00053     _len = 0;
00054 }
00055 
00056 
00057 BinRep::BinRep(const BinRep &br) 
00058 {
00059     #ifdef CLASS_INSTANCE_REGISTRY
00060     register_instance(BIN_REP, sizeof(BinRep), this);
00061     #endif
00062 
00063     _fc  = br._fc;
00064     _len = br._len;
00065 
00066     if (br.is_tuple()) 
00067         _u.L = new List<BinRep>( *br._u.L );
00068     else if (br.is_set()) 
00069         _u.S =  new Set<BinRep>( *br._u.S );
00070     else if (br.is_map()) 
00071         _u.D =  new Database<String,BinRep>( *br._u.D );
00072     else {
00073         _u.C = malloc(_len*sizeof(char));
00074         memcpy( _u.C, br._u.C, _len );
00075     }
00076 }
00077 
00078 
00079 BinRep & 
00080 BinRep::operator = (const BinRep &br)
00081 {
00082     _fc  = br._fc;
00083     _len = br._len;
00084 
00085     if (br.is_tuple()) 
00086         _u.L = new List<BinRep>( *br._u.L );
00087     else if (br.is_set()) 
00088         _u.S =  new Set<BinRep>( *br._u.S );
00089     else if (br.is_map()) 
00090         _u.D =  new Database<String,BinRep>( *br._u.D );
00091     else {
00092         _u.C = malloc(_len*sizeof(char));
00093         memcpy( _u.C, br._u.C, _len );
00094     }
00095 
00096     return (*this);
00097 }
00098 
00099 BinRep::BinRep(const void *binstr)
00100 {
00101     #ifdef CLASS_INSTANCE_REGISTRY
00102     register_instance(BIN_REP, sizeof(BinRep), this);
00103     #endif
00104 
00105     _fc = _ILLEGAL_TYPES;
00106     _len = 0;
00107 
00108     _parse( binstr );
00109 }
00110 
00111 BinRep::~BinRep()
00112 {
00113     #ifdef CLASS_INSTANCE_REGISTRY
00114     unregister_instance(BIN_REP, this);
00115     #endif
00116 
00117     _destroy();
00118 }
00119 
00120 BinRep &
00121 BinRep::_omega() const
00122 {
00123     static BinRep *om = 0;
00124 
00125     if (om == 0) {
00126         om = new BinRep;
00127         om->_fc  = IEF_OMEGA;
00128         om->_len = 0;
00129         om->_u.C = 0;
00130     }
00131 
00132     return *om;
00133 }
00134 
00135 void
00136 BinRep::_parse( const void *binstr )
00137 {
00138     _destroy();
00139 
00140     char    *s = (char *) binstr;
00141 
00142     if (*s == IEF_HEADER)
00143         _ief_parse( binstr, 0 );
00144     else
00145         _setl_parse( binstr );
00146 }
00147 
00148 void
00149 BinRep::_parse( istream & ifs )
00150 {
00151     char ch;
00152 
00153     _destroy();
00154 
00155     ifs.get( ch );
00156 
00157     if (ifs.eof())
00158         return;
00159 
00160     ifs.putback( ch );
00161 
00162     if (ch == IEF_HEADER)
00163         _ief_parse( ifs );
00164     else
00165         _setl_parse( ifs );
00166 }
00167 
00168 static void
00169 aux_ief_parse( Database<int,BinRep> &dict, BinRep &br, BinPtr &p )
00170 {
00171     binptr_1    form_code;
00172 
00173     p.fetch( form_code );
00174 
00175     switch ( form_code ) {
00176     case IEF_OMEGA:
00177         br.put_omega();
00178         break;
00179 
00180     case IEF_TRUE:
00181         br.put_boolean( True );
00182         break;
00183 
00184     case IEF_FALSE:
00185         br.put_boolean( False );
00186         break;
00187 
00188     case IEF_REAL:
00189         {
00190             double  x;
00191             p.fetch( x );
00192             br.put_double( x );
00193         }
00194         break;
00195 
00196     case IEF_INTEGER_1:
00197         {
00198             binptr_1 x;
00199             p.fetch( x );
00200             br.put_integer( x );
00201         }
00202         break;
00203         
00204     case IEF_INTEGER_2:
00205         {
00206             binptr_2 x;
00207             p.fetch( x );
00208             br.put_integer( x );
00209         }
00210         break;
00211 
00212     case IEF_INTEGER_4:
00213         {
00214             binptr_4 x;
00215             p.fetch( x );
00216             br.put_integer( x );
00217         }
00218         break;
00219 
00220     case IEF_STRING_1:
00221         {
00222             binptr_1 size;
00223             p.fetch( size );
00224 
00225             char *buffer = new char[ size+1 ];
00226 
00227             p.fetch( buffer, size );
00228 
00229             br.put_string( buffer, size );
00230 
00231             delete [] buffer;
00232         }
00233         break;
00234 
00235     case IEF_STRING_2:
00236         {
00237             binptr_2 size;
00238             p.fetch( size );
00239 
00240             char *buffer = new char[ size+1 ];
00241 
00242             p.fetch( buffer, size );
00243             br.put_string( buffer, size );
00244 
00245             delete [] buffer;
00246         }
00247         break;
00248 
00249     case IEF_STRING_4:
00250         {
00251             binptr_4   size;
00252             p.fetch( size );
00253 
00254             char *buffer = new char[ size+1 ];
00255 
00256             p.fetch( buffer, size );
00257             br.put_string( buffer, size );
00258 
00259             delete [] buffer;
00260         }
00261         break;
00262 
00263     case IEF_TUPLE_1:
00264         {
00265             binptr_1 size;
00266             p.fetch( size );
00267             List<BinRep> *L = new List<BinRep>;
00268             for (int i = 0; i < size; ++i) {
00269                 BinRep  *b = new BinRep;
00270                 aux_ief_parse( dict, *b, p );
00271                 L->ins_last( b );
00272             }
00273             br.put_tuple( L );
00274         }
00275         break;
00276 
00277     case IEF_TUPLE_2:
00278         {
00279             binptr_2 size;
00280             p.fetch( size );
00281             List<BinRep> *L = new List<BinRep>;
00282             for (int i = 0; i < size; ++i) {
00283                 BinRep  *b = new BinRep;
00284                 aux_ief_parse( dict, *b, p );
00285                 L->ins_last( b );
00286             }
00287             br.put_tuple( L );
00288         }
00289         break;
00290 
00291     case IEF_TUPLE_4:
00292         {
00293             binptr_4  size;
00294             p.fetch( size );
00295             List<BinRep> *L = new List<BinRep>;
00296             for (int i = 0; i < size; ++i) {
00297                 BinRep  *b = new BinRep;
00298                 aux_ief_parse( dict, *b, p );
00299                 L->ins_last( b );
00300             }
00301             br.put_tuple( L );
00302         }
00303         break;
00304 
00305     case IEF_SET_1:
00306     case IEF_MAP_1:
00307         {
00308             binptr_1 size;
00309             p.fetch( size );
00310             Set<BinRep> *S = new Set<BinRep>;
00311             for (int i = 0; i < size; ++i) {
00312                 BinRep  *b = new BinRep;
00313                 aux_ief_parse( dict, *b, p );
00314                 S->ins( b );
00315             }
00316             br.put_set( S );
00317         }
00318         break;
00319 
00320     case IEF_SET_2:
00321     case IEF_MAP_2:
00322         {
00323             binptr_2 size;
00324             p.fetch( size );
00325             Set<BinRep> *S = new Set<BinRep>;
00326             for (int i = 0; i < size; ++i) {
00327                 BinRep  *b = new BinRep;
00328                 aux_ief_parse( dict, *b, p );
00329                 S->ins( b );
00330             }
00331             br.put_set( S );
00332         }
00333         break;
00334 
00335     case IEF_SET_4:
00336     case IEF_MAP_4:
00337         {
00338             binptr_4  size;
00339             p.fetch( size );
00340             Set<BinRep> *S = new Set<BinRep>;
00341             for (int i = 0; i < size; ++i) {
00342                 BinRep  *b = new BinRep;
00343                 aux_ief_parse( dict, *b, p );
00344                 S->ins( b );
00345             }
00346             br.put_set( S );
00347         }
00348         break;
00349 
00350     case IEF_DICT_1:
00351         {
00352             binptr_1 x;
00353             p.fetch( x );
00354             BinRep *b = dict.find_ref( (int) x );
00355             p_assert( b, "Error: unknown dictionary entry" );
00356             br = *b;
00357         }
00358         break;
00359 
00360     case IEF_DICT_2:
00361         {
00362             binptr_2 x;
00363             p.fetch( x );
00364             BinRep *b = dict.find_ref( (int) x );
00365             p_assert( b, "Error: unknown dictionary entry" );
00366             br = *b;
00367         }
00368         break;
00369 
00370     case IEF_DICT_4:
00371         {
00372             binptr_4 x;
00373             p.fetch( x );
00374             BinRep *b = dict.find_ref( (int) x );
00375             p_assert( b, "Error: unknown dictionary entry" );
00376             br = *b;
00377         }
00378         break;
00379     }
00380 }
00381 
00382 
00383 void
00384 BinRep::_ief_parse( const void *bin_header, const void *bin_body )
00385 {
00386     Database<int,BinRep>    dict;
00387 
00388 
00389     BinPtr      p( bin_header );
00390     binptr_4    header_version, header_length;
00391 
00392     binptr_1    form_code;
00393     p.fetch( form_code );
00394     
00395     p_assert( form_code == IEF_HEADER, "not the IEF_HEADER code" );
00396 
00397     p.fetch( header_version );
00398     p.fetch( header_length );
00399 
00400     int count = 0;
00401 
00402     p.fetch( form_code );
00403 
00404     switch ( form_code ) {
00405     case IEF_TUPLE_1:
00406         {
00407             binptr_1    x;
00408             p.fetch( x );
00409             count = x;
00410             break;
00411         }
00412     case IEF_TUPLE_2:
00413         {
00414             binptr_2    x;
00415             p.fetch( x );
00416             count = x;
00417             break;
00418         }
00419     case IEF_TUPLE_4:
00420         {
00421             binptr_4    x;
00422             p.fetch( x );
00423             count = x;
00424             break;
00425         }
00426     }
00427 
00428     for (int i = 1; i <= count; ++i) {
00429         BinRep  *br = new BinRep;
00430         aux_ief_parse( dict, *br, p );
00431         dict.ins( i, br );
00432     }
00433 
00434     if (bin_body != 0)
00435         p.reset( bin_body );
00436 
00437     binptr_4    body_version, body_length;
00438 
00439     p.fetch( form_code );
00440     p_assert( form_code == IEF_BODY, "not the IEF_BODY code" );
00441 
00442     p.fetch( body_version );
00443     p.fetch( body_length ); 
00444 
00445     aux_ief_parse( dict, (*this), p );
00446 }
00447 
00448 void
00449 BinRep::_ief_parse( istream &ifs )
00450 {
00451     Database<int,BinRep>    dict;
00452 
00453     BinPtr      p( ifs );
00454 
00455     binptr_4    header_version, header_length;
00456     binptr_1    form_code;
00457 
00458     p.fetch( form_code );
00459     
00460     p_assert( form_code == IEF_HEADER, "not the IEF_HEADER code" );
00461 
00462     p.fetch( header_version );
00463     p.fetch( header_length );
00464 
00465     int count = 0;
00466 
00467     p.fetch( form_code );
00468 
00469     switch ( form_code ) {
00470     case IEF_TUPLE_1:
00471         {
00472             binptr_1    x;
00473             p.fetch( x );
00474             count = x;
00475             break;
00476         }
00477     case IEF_TUPLE_2:
00478         {
00479             binptr_2    x;
00480             p.fetch( x );
00481             count = x;
00482             break;
00483         }
00484     case IEF_TUPLE_4:
00485         {
00486             binptr_4    x;
00487             p.fetch( x );
00488             count = x;
00489             break;
00490         }
00491     }
00492 
00493     for (int i = 1; i <= count; ++i) {
00494         BinRep  *br = new BinRep;
00495         aux_ief_parse( dict, *br, p );
00496         dict.ins( i, br );
00497     }
00498 
00499     binptr_4    body_version, body_length;
00500 
00501     p.fetch( form_code );
00502     p_assert( form_code == IEF_BODY, "not the IEF_BODY code" );
00503 
00504     p.fetch( body_version );
00505     p.fetch( body_length ); 
00506 
00507     aux_ief_parse( dict, (*this), p );
00508 }
00509 
00510 
00511 static void 
00512 aux_setl_parse( BinRep &br, BinPtr &p )
00513 {
00514     binptr_4    form_code;
00515 
00516     p.fetch( form_code );
00517 
00518     switch ( form_code ) {
00519     case FT_ALT_OMEGA:
00520         {
00521             binptr_4        extra;
00522 
00523             p.fetch( extra );
00524             br.put_omega();
00525         }
00526         break;
00527 
00528     case FT_OMEGA:
00529         br.put_omega();
00530         break;
00531 
00532     case FT_ATOM:
00533         {
00534             binptr_4             atom_value, pointer;
00535 
00536             p.fetch( atom_value );
00537             p.fetch( pointer );
00538             br.put_boolean( (atom_value != 0) );
00539         }
00540         break;
00541 
00542     case FT_SHORT:
00543         {
00544             binptr_4 int_value;
00545 
00546             p.fetch( int_value );
00547             br.put_integer( int_value );
00548         }
00549         break;
00550 
00551     case FT_DOUBLE:
00552         {
00553             double real_value;
00554 
00555             p.fetch( real_value );
00556             br.put_double( real_value );
00557         }
00558         break;
00559 
00560     case FT_LONGINT:
00561         {
00562             binptr_4 long_length, digit;
00563             int      long_value, sign, pos;
00564 
00565             p.fetch( long_length );
00566 
00567             if (long_length >= 0)
00568                 sign =  1;
00569             else {
00570                 sign = -1;
00571                 long_length = -long_length;
00572             }
00573 
00574             for (long_value = pos = 0; long_length > 0; --long_length) {
00575                 p.fetch( digit );
00576                 long_value |= (digit << (pos++ * 15));
00577             }
00578             long_value = sign * long_value;
00579 
00580             br.put_integer( long_value );
00581         }
00582         break;
00583 
00584     case FT_STRING:
00585         {
00586             binptr_4    len;
00587 
00588             p.fetch( len );
00589 
00590             char *buffer = new char[ len+1 ];
00591 
00592             p.fetch( buffer, len );
00593             br.put_string( buffer, len );
00594 
00595             delete [] buffer;
00596         }
00597         break;
00598 
00599     case FT_TUPLE:
00600         {
00601             binptr_4    tuple_length;
00602 
00603             p.fetch( tuple_length );
00604 
00605             List<BinRep> *L = new List<BinRep>;
00606 
00607             for (int i = 0; i < tuple_length; ++i) {
00608                 BinRep *b = new BinRep;
00609                 aux_setl_parse( *b, p );
00610                 L->ins_last( b );
00611             }
00612 
00613             br.put_tuple( L );
00614         }
00615         break;
00616     case FT_SET:
00617         {
00618             binptr_4    set_length;
00619 
00620             p.fetch( set_length );
00621 
00622             Set<BinRep> *S = new Set<BinRep>;
00623 
00624             for (int i = 0; i < set_length; ++i) {
00625                 BinRep *b = new BinRep;
00626                 aux_setl_parse( *b, p );
00627                 S->ins( b );
00628             }
00629 
00630             br.put_set( S );
00631         }
00632         break;
00633 
00634     default:
00635         p_abort( "unknown form_code" );
00636         break;
00637     }
00638 }
00639 
00640 void
00641 BinRep::_setl_parse( const void *binstr )
00642 {
00643     BinPtr  p( binstr );
00644     aux_setl_parse( *this, p );
00645 }
00646 
00647 void
00648 BinRep::_setl_parse( istream &ifs )
00649 {
00650     BinPtr  p( ifs );
00651     aux_setl_parse( *this, p );
00652 }
00653 
00654 void
00655 BinRep::_init()
00656 {
00657     _fc = _ILLEGAL_TYPES;
00658     _len = 0;
00659 }
00660 
00661 
00662 void
00663 BinRep::_destroy()
00664 {
00665     switch ( _fc ) {
00666     case _ILLEGAL_TYPES:
00667         /// ...  nothing to do
00668         break;
00669 
00670     case FT_TUPLE:
00671     case IEF_TUPLE_1:
00672     case IEF_TUPLE_2:
00673     case IEF_TUPLE_4:
00674         delete _u.L;
00675         _u.L = 0;
00676         break;
00677 
00678     case FT_SET:
00679     case IEF_SET_1:
00680     case IEF_SET_2:
00681     case IEF_SET_4:
00682         delete _u.S;
00683         _u.S = 0;
00684         break;
00685 
00686     case IEF_MAP_1:
00687     case IEF_MAP_2:
00688     case IEF_MAP_4:
00689         p_abort( "not supported" );
00690 
00691         delete _u.D;
00692         _u.D = 0;
00693         break;
00694     
00695     default:
00696         free(_u.C);
00697         _u.C = 0;
00698         break;
00699     }
00700 
00701     _fc = _ILLEGAL_TYPES;
00702     _len = 0;
00703 }
00704 
00705 BinRep &
00706 BinRep::operator = (const void *binstr) 
00707 {
00708     _destroy();
00709     _parse( binstr );
00710 
00711     return (*this);
00712 }
00713 
00714 void
00715 BinRep::ascii_format(String & str) const
00716 {
00717     str = "";
00718     _ascii_format( str );
00719 }
00720 
00721 void
00722 BinRep::_ascii_format(String & str) const
00723 {
00724     if ( is_omega() )
00725         str += "OM";
00726     else if (is_boolean())
00727         str += ( to_boolean() ? "TRUE" : "FALSE" );
00728     else if (is_integer()){
00729         char    buffer[32];
00730         sprintf( buffer, "%d", to_integer() );
00731         str += buffer;
00732     }
00733     else if (is_double()) {
00734         char    buffer[32];
00735         sprintf( buffer, "%f", to_double() );
00736         str += "(double)";
00737         str += buffer;
00738     }
00739     else if (is_string()) {
00740         String  s;
00741         to_string( s );
00742 
00743         str += "\"";
00744         str += s;
00745         str += "\"";
00746     }
00747     else if (is_tuple()) {
00748         str += "[";
00749         Iterator<BinRep> iter = to_tuple(); 
00750         if (iter.valid()) {
00751             iter.current()._ascii_format( str );
00752             for (++iter; iter.valid(); ++iter) {
00753                 str += ",";
00754                 iter.current()._ascii_format( str );
00755             }
00756         }
00757         str += "]";
00758     }
00759     else if (is_set()) {
00760         str += "{";
00761         Iterator<BinRep> iter = to_set(); 
00762         if (iter.valid()) {
00763             iter.current()._ascii_format( str );
00764             for (++iter; iter.valid(); ++iter) {
00765                 str += ",";
00766                 iter.current()._ascii_format( str );
00767             }
00768         }
00769         str += "}";
00770     }
00771     else if (is_map()) {
00772         str += "{";
00773         KeyIterator<String,BinRep> iter = to_map(); 
00774         if (iter.valid()) {
00775             str += "[";
00776             str += iter.current_key();
00777             str += ",";
00778             iter.current_data()._ascii_format( str );
00779             str += "]";
00780 
00781             for (++iter; iter.valid(); ++iter) {
00782                 str += ", [";
00783                 str += iter.current_key();
00784                 str += ",";
00785                 iter.current_data()._ascii_format( str );
00786                 str += "]";
00787             }
00788         }
00789         str += "}";
00790     }
00791 }
00792 
00793 int
00794 BinRep::_setl_length() const
00795 {
00796     int     size = sizeof( binptr_4 );
00797 
00798     switch( _fc ) {
00799     case FT_OMEGA:
00800     case IEF_OMEGA:
00801         break;
00802 
00803     case FT_ATOM:
00804     case IEF_TRUE:
00805     case IEF_FALSE:
00806         size += 2 * sizeof( binptr_4 );
00807         break;
00808 
00809     case FT_DOUBLE:
00810     case IEF_REAL:
00811         size += sizeof( binptr_8 );
00812         break;
00813 
00814     case FT_LONGINT:
00815     case FT_SHORT:
00816     case IEF_INTEGER_1:
00817     case IEF_INTEGER_2:
00818     case IEF_INTEGER_4:
00819         {
00820             int x = to_integer();
00821 
00822             if (bytes_per_value(x) <= 2)
00823                 size += sizeof( binptr_4 );
00824             else 
00825                 size += sizeof( binptr_4 ) + 3*sizeof( binptr_4 );
00826         }
00827         break;
00828 
00829     case FT_STRING:
00830     case IEF_STRING_1:
00831     case IEF_STRING_2:
00832     case IEF_STRING_4:
00833         size += sizeof( binptr_4 ) + _len;
00834         break;
00835 
00836     case FT_TUPLE:
00837     case IEF_TUPLE_1:
00838     case IEF_TUPLE_2:
00839     case IEF_TUPLE_4:
00840         {
00841             size += sizeof( binptr_4 );
00842             for (Iterator<BinRep> iter = to_tuple(); iter.valid(); ++iter) 
00843                 size += iter.current()._setl_length();
00844         }
00845         break;
00846         
00847     case FT_SET:
00848     case IEF_SET_1:
00849     case IEF_SET_2:
00850     case IEF_SET_4:
00851         {
00852             size += sizeof( binptr_4 );
00853             for (Iterator<BinRep> iter = to_set(); iter.valid(); ++iter) 
00854                 size += iter.current()._setl_length();
00855         }
00856         break;
00857 
00858     case IEF_MAP_1:
00859     case IEF_MAP_2:
00860     case IEF_MAP_4:
00861         {
00862             p_abort( "not suppoted" );
00863 
00864             size += sizeof( binptr_4 );
00865             for (KeyIterator<String,BinRep> iter = to_map(); 
00866                                             iter.valid(); ++iter) {
00867                 size += iter.current_data()._setl_length();
00868             }
00869         }
00870         break;
00871 
00872     default:
00873         p_abort( "unknown form code" );
00874         break;
00875     }
00876 
00877     return size;
00878 }
00879 
00880 int
00881 BinRep::_ief_length( Database<String,IntElem> *map ) const
00882 {
00883     int     size = sizeof( binptr_1 );
00884 
00885     switch( _fc ) {
00886     case FT_OMEGA:
00887     case IEF_OMEGA:
00888     case FT_ATOM:
00889     case IEF_TRUE:
00890     case IEF_FALSE:
00891         break;
00892 
00893     case FT_DOUBLE:
00894     case IEF_REAL:
00895         size += sizeof( binptr_8 );
00896         break;
00897 
00898     case FT_LONGINT:
00899     case FT_SHORT:
00900     case IEF_INTEGER_1:
00901     case IEF_INTEGER_2:
00902     case IEF_INTEGER_4:
00903         size += bytes_per_value( to_integer() );
00904         break;
00905 
00906     case FT_STRING:
00907     case IEF_STRING_1:
00908     case IEF_STRING_2:
00909     case IEF_STRING_4:
00910         if (map == 0) 
00911             size += bytes_per_value( _len ) + _len;
00912         else {
00913             String  str;
00914 
00915             to_string( str );
00916 
00917             IntElem *e;
00918 
00919             if ((e = map->find_ref(str)) == 0) {
00920                 e = new IntElem( map->entries() + 1 );
00921                 map->ins( str, e );
00922             }
00923 
00924             size += bytes_per_value( e->value() );
00925         }
00926         break;
00927 
00928     case FT_TUPLE:
00929     case IEF_TUPLE_1:
00930     case IEF_TUPLE_2:
00931     case IEF_TUPLE_4:
00932         {
00933             size += bytes_per_value( to_tuple().entries() );
00934             for (Iterator<BinRep> iter = to_tuple(); iter.valid(); ++iter) 
00935                 size += iter.current()._ief_length( map );
00936         }
00937         break;
00938         
00939     case FT_SET:
00940     case IEF_SET_1:
00941     case IEF_SET_2:
00942     case IEF_SET_4:
00943         {
00944             size += bytes_per_value( to_set().entries() );
00945             for (Iterator<BinRep> iter = to_set(); iter.valid(); ++iter) 
00946                 size += iter.current()._ief_length( map );
00947         }
00948         break;
00949 
00950     case IEF_MAP_1:
00951     case IEF_MAP_2:
00952     case IEF_MAP_4:
00953         {
00954             p_abort( "not suppoted" );
00955 
00956             size += bytes_per_value( to_map().entries() );
00957             for (KeyIterator<String,BinRep> iter = to_map(); 
00958                                             iter.valid(); ++iter) {
00959                 size += iter.current_data()._ief_length( map );
00960             }
00961         }
00962         break;
00963 
00964     default:
00965         p_abort( "unknown form code" );
00966         break;
00967     }
00968 
00969     return size;
00970 }
00971 
00972 void 
00973 BinRep::_ief_format( BinPtr &p, Database<String,IntElem> *map ) const
00974 {
00975     switch( _fc ) {
00976     case FT_OMEGA:
00977     case IEF_OMEGA:
00978         p.store( IEF_OMEGA, 1 );
00979         break;
00980 
00981     case FT_ATOM:
00982     case IEF_TRUE:
00983     case IEF_FALSE:
00984         p.store( ( to_boolean() ? IEF_TRUE : IEF_FALSE ), 1 );
00985         break;
00986 
00987     case FT_DOUBLE:
00988     case IEF_REAL:
00989         {
00990             double  x = to_double();
00991 
00992             p.store( IEF_REAL, 1 );
00993             p.store( x );
00994         }
00995         break;
00996 
00997     case FT_LONGINT:
00998     case FT_SHORT:
00999     case IEF_INTEGER_1:
01000     case IEF_INTEGER_2:
01001     case IEF_INTEGER_4:
01002         {
01003             int value = to_integer();
01004             int size = bytes_per_value( value );
01005 
01006             p.store( select_type(size, 
01007                         IEF_INTEGER_1, IEF_INTEGER_2, IEF_INTEGER_4 ), 1 );
01008             p.store( value, size );
01009         }
01010         break;
01011 
01012     case FT_STRING:
01013     case IEF_STRING_1:
01014     case IEF_STRING_2:
01015     case IEF_STRING_4:
01016         if (map == 0) {
01017             int size = bytes_per_value( _len );
01018 
01019             p.store( select_type(size, 
01020                         IEF_STRING_1, IEF_STRING_2, IEF_STRING_4 ), 1 );
01021             p.store( _len, size );
01022             p.store( _u.C, _len );
01023         }
01024         else {
01025             String  str;
01026             to_string( str );
01027 
01028             IntElem *e = map->find_ref(str);
01029             p_assert( e, "must call _ief_length() first" );
01030 
01031             int size = bytes_per_value( e->value() );
01032 
01033             p.store( select_type(size, 
01034                         IEF_DICT_1, IEF_DICT_2, IEF_DICT_4 ), 1 );
01035             p.store( e->value(), size );
01036         }
01037         break;
01038 
01039     case FT_TUPLE:
01040     case IEF_TUPLE_1:
01041     case IEF_TUPLE_2:
01042     case IEF_TUPLE_4:
01043         {
01044             List<BinRep> &L = to_tuple();
01045 
01046             int size = bytes_per_value( L.entries() );
01047 
01048             p.store( select_type(size, 
01049                         IEF_TUPLE_1, IEF_TUPLE_2, IEF_TUPLE_4 ), 1 );
01050             p.store( L.entries(), size ); 
01051 
01052             for (Iterator<BinRep> iter = L; iter.valid(); ++iter) 
01053                 iter.current()._ief_format( p, map );
01054         }
01055         break;
01056         
01057     case FT_SET:
01058     case IEF_SET_1:
01059     case IEF_SET_2:
01060     case IEF_SET_4:
01061         {
01062             Set<BinRep> &S = to_set();
01063 
01064             int size = bytes_per_value( S.entries() );
01065 
01066             p.store( select_type(size, 
01067                         IEF_SET_1, IEF_SET_2, IEF_SET_4 ), 1 );
01068             p.store( S.entries(), size ); 
01069 
01070             for (Iterator<BinRep> iter = S; iter.valid(); ++iter) 
01071                 iter.current()._ief_format( p, map );
01072         }
01073         break;
01074 
01075     case IEF_MAP_1:
01076     case IEF_MAP_2:
01077     case IEF_MAP_4:
01078         {
01079             p_abort( "not supported" );
01080 
01081             Database<String, BinRep> &D = to_map();
01082 
01083             int size = bytes_per_value( D.entries() );
01084 
01085             p.store( select_type(size, 
01086                         IEF_MAP_1, IEF_MAP_2, IEF_MAP_4 ), 1 );
01087             p.store( D.entries(), size ); 
01088 
01089             for (KeyIterator<String,BinRep> iter = to_map(); 
01090                                             iter.valid(); ++iter) {
01091             
01092                 iter.current_data()._ief_format( p, map );
01093             }
01094         }
01095         break;
01096 
01097     default:
01098         p_abort( "unknown form code" );
01099         break;
01100     }
01101 }
01102 
01103 void
01104 BinRep::ief_format(MemBuf &buf) const
01105 {
01106     Database<String,IntElem> map;
01107 
01108     int body_version = 1;
01109     int body_length  = _ief_length( &map );
01110 
01111     List<BinRep> *dict = new List<BinRep>;
01112 
01113     dict->make_static_list( map.entries() );
01114 
01115     for (KeyIterator<String,IntElem> iter = map; iter.valid(); ++iter) {
01116         BinRep  *b = new BinRep;
01117         b->put_string( iter.current_key() );
01118         dict->modify( iter.current_data().value() - 1, b );
01119     }
01120 
01121     dict->unfix_size();
01122 
01123     BinRep  head;
01124 
01125     head.put_tuple( dict );
01126 
01127     int header_version = 1;
01128     int header_length  = head._ief_length( 0 );
01129 
01130     buf.reset();
01131     buf.append_empty( 2*sizeof(binptr_1) + 4*sizeof(binptr_4) 
01132                                          + header_length 
01133                                          + body_length );
01134     BinPtr  p( buf.data_ref() );
01135 
01136     p.store( IEF_HEADER, 1 );
01137     p.store( header_version );
01138     p.store( header_length );
01139     head._ief_format( p, 0 );
01140 
01141     p.store( IEF_BODY, 1 );
01142     p.store( body_version );
01143     p.store( body_length );
01144     _ief_format( p, &map );
01145 }
01146 
01147 void
01148 BinRep::_setl_format( BinPtr &p ) const
01149 {
01150     switch( _fc ) {
01151     case FT_OMEGA:
01152     case IEF_OMEGA:
01153         p.store( (long) FT_OMEGA, 4 );
01154         break;
01155 
01156     case FT_ATOM:
01157     case IEF_TRUE:
01158     case IEF_FALSE:
01159         {
01160             binptr_4    atom_value=  (int) to_boolean();
01161             binptr_4    pointer = 0x01234567;
01162 
01163             p.store( FT_ATOM, 4 );
01164             p.store( atom_value );
01165             p.store( pointer );
01166         }
01167         break;
01168 
01169     case FT_DOUBLE:
01170     case IEF_REAL:
01171         {
01172             double  x = to_double();
01173 
01174             p.store( FT_DOUBLE, 4 );
01175             p.store( x );
01176         }
01177         break;
01178 
01179     case FT_LONGINT:
01180     case FT_SHORT:
01181     case IEF_INTEGER_1:
01182     case IEF_INTEGER_2:
01183     case IEF_INTEGER_4:
01184         {
01185             int value = to_integer();
01186             int size = bytes_per_value( value );
01187 
01188             if (size <= 2) {
01189                 p.store( FT_SHORT, 4 );
01190                 p.store( value, 4 );
01191             }
01192             else {
01193                 const int   max_packets = 3;
01194                 binptr_4 buffer[ max_packets ];
01195 
01196                 int      sign = 1, len = 0;
01197 
01198                 if (value < 0) {
01199                     sign  = -1;
01200                     value = -value;
01201                 }
01202 
01203                 do {
01204                     const int mask = (1 << 15) - 1;     /// ...  mask out 1st 15 bits
01205                     buffer[ len++ ] = (mask & value);
01206                     value >>= 15;
01207                 } while (value != 0);
01208 
01209                 p_assert( len > 0 && len <= max_packets, "too many packets" );
01210 
01211                 sign = sign * len;
01212 
01213                 p.store( FT_LONGINT, 4 );
01214                 p.store( sign );
01215 
01216                 for (int i = 0; i < len; ++i)
01217                     p.store( buffer[i] );
01218             }
01219         }
01220         break;
01221 
01222     case FT_STRING:
01223     case IEF_STRING_1:
01224     case IEF_STRING_2:
01225     case IEF_STRING_4:
01226         p.store( FT_STRING, 4 );
01227         p.store( _len, 4 );
01228         p.store( _u.C, _len );
01229         break;
01230 
01231     case FT_TUPLE:
01232     case IEF_TUPLE_1:
01233     case IEF_TUPLE_2:
01234     case IEF_TUPLE_4:
01235         {
01236             List<BinRep> &L = to_tuple();
01237 
01238             p.store( FT_TUPLE, 4 );
01239             p.store( L.entries(), 4 ); 
01240 
01241             for (Iterator<BinRep> iter = L; iter.valid(); ++iter) 
01242                 iter.current()._setl_format( p );
01243         }
01244         break;
01245         
01246     case FT_SET:
01247     case IEF_SET_1:
01248     case IEF_SET_2:
01249     case IEF_SET_4:
01250         {
01251             Set<BinRep> &S = to_set();
01252 
01253             p.store( FT_SET, 4 );
01254             p.store( S.entries(), 4 ); 
01255 
01256             for (Iterator<BinRep> iter = S; iter.valid(); ++iter) 
01257                 iter.current()._setl_format( p );
01258         }
01259         break;
01260 
01261     case IEF_MAP_1:
01262     case IEF_MAP_2:
01263     case IEF_MAP_4:
01264         p_abort( "not supported" );
01265         break;
01266 
01267     default:
01268         p_abort( "unknown form code" );
01269         break;
01270     }
01271 }
01272 
01273 void
01274 BinRep::setl_format(MemBuf &buf) const
01275 {
01276     int length = _setl_length();
01277 
01278     buf.reset();
01279     buf.append_empty( sizeof(binptr_4) + length );
01280 
01281     BinPtr  p( buf.data_ref() );
01282 
01283     p.store( length );
01284     _setl_format( p );
01285 }
01286 
01287 void
01288 BinRep::read( istream &ifs )
01289 {
01290     char    ch;
01291 
01292     /// ...  If anything exists in this BinRep, remove it.
01293     _destroy();
01294 
01295     ifs.get( ch );
01296 
01297     if (ifs.eof())
01298         return;
01299 
01300     ifs.putback( ch );
01301 
01302     if (ch != IEF_HEADER) {
01303         int     length = -1;
01304 
01305         ifs.read( (char *) &length, sizeof(length) );
01306 
01307         if (length > 0) {
01308             p_assert( length < 9999999, "SETL binstr too long" );
01309 
01310             _setl_parse( ifs );
01311 
01312             ifs.get( ch );
01313 
01314             if (! ifs.eof())
01315                 ifs.putback( ch );
01316         }
01317     }
01318     else {
01319         p_assert( ch == IEF_HEADER, "not IEF_HEADER code" );
01320 
01321         _ief_parse( ifs );
01322 
01323         ifs.get( ch );
01324         if (! ifs.eof())
01325             ifs.putback( ch );
01326     }
01327 }
01328 
01329 int
01330 BinRep::structures_OK() const
01331 {
01332     /// ...  Check the structure of the data for errors or inconsistency
01333     /// ...  Return 0 and print error message if problems found, otherwise
01334     /// ...  return 1 without message.
01335 
01336     return 1;
01337 }
01338 
01339 Boolean
01340 BinRep::is_omega() const
01341 {
01342     return ( 
01343 #if 0
01344         type() == FT_ALT_OMEGA || type() == FT_OMEGA || 
01345 #endif
01346         type() == IEF_OMEGA );
01347 }
01348 
01349 Boolean
01350 BinRep::is_boolean() const
01351 {
01352     return ( 
01353 #if 0
01354         type() == FT_ATOM || 
01355 #endif
01356         type() == IEF_TRUE || type() == IEF_FALSE );
01357 }
01358 
01359 Boolean
01360 BinRep::is_double() const
01361 {
01362     return ( 
01363 #if 0
01364         type() == FT_DOUBLE || 
01365 #endif
01366         type() == IEF_REAL );
01367 }
01368 
01369 Boolean
01370 BinRep::is_integer() const
01371 {
01372     return ( 
01373 #if 0
01374         type() == FT_LONGINT || type() == FT_SHORT ||
01375 #endif
01376          type() == IEF_INTEGER_1 || type() == IEF_INTEGER_2 ||
01377          type() == IEF_INTEGER_4 );
01378 }
01379 
01380 Boolean
01381 BinRep::is_string() const
01382 {
01383     return ( 
01384 #if 0
01385         type() == FT_STRING  || 
01386 #endif
01387         type() == IEF_STRING_1 || 
01388         type() == IEF_STRING_2 || type() == IEF_STRING_4 );
01389 }
01390 
01391 Boolean
01392 BinRep::is_tuple() const
01393 {
01394     return ( 
01395 #if 0
01396         type() == FT_TUPLE  || 
01397 #endif
01398         type() == IEF_TUPLE_1 || 
01399         type() == IEF_TUPLE_2 || type() == IEF_TUPLE_4 );
01400 }
01401 
01402 Boolean
01403 BinRep::is_set() const
01404 {
01405     return ( 
01406 #if 0
01407         type() == FT_SET || 
01408 #endif
01409 #if 0
01410         type() == IEF_MAP_1 || 
01411         type() == IEF_MAP_2 || type() == IEF_MAP_4 ||
01412 #endif
01413         type() == IEF_SET_1 || 
01414         type() == IEF_SET_2 || type() == IEF_SET_4 );
01415 }
01416 
01417 Boolean
01418 BinRep::to_boolean() const
01419 {
01420     p_assert( is_boolean(), "not a boolean" );
01421 
01422     switch ( _fc ) {
01423     case IEF_TRUE:
01424         return True;
01425 
01426     case IEF_FALSE:
01427         return False;
01428     default: 
01429       return False;
01430     }
01431 
01432     return False;
01433 }
01434 
01435 
01436 double
01437 BinRep::to_double() const
01438 {
01439     p_assert( is_double(), "not a double" );
01440 
01441     BinPtr  p( _u.C );
01442 
01443     double value;
01444 
01445     p.fetch( value );
01446 
01447     return value;
01448 }
01449 
01450 int
01451 BinRep::to_integer() const
01452 {
01453     p_assert( is_integer(), "not an integer" );
01454 
01455     BinPtr  p( _u.C );
01456 
01457     switch ( _fc ) {
01458     case IEF_INTEGER_1:
01459         {
01460             binptr_1    value;
01461             p.fetch( value );
01462 
01463             return value;
01464         }
01465 
01466     case IEF_INTEGER_2:
01467         {
01468             binptr_2   value;
01469             p.fetch( value );
01470 
01471             return value;
01472         }
01473 
01474     case IEF_INTEGER_4:
01475         {
01476             binptr_4     value;
01477             p.fetch( value );
01478 
01479             return value;
01480         }
01481     default: return 0;
01482     }
01483 
01484     return 0;
01485 }
01486 
01487 
01488 void
01489 BinRep::to_string(String & str) const
01490 {
01491     p_assert( is_string(), "not a string" );
01492 
01493     String s( (char *) _u.C, _len );
01494 
01495     str = s;
01496 }
01497 
01498 
01499 List<BinRep> &
01500 BinRep::to_tuple() const
01501 {
01502     p_assert( is_tuple(), "not a tuple" );
01503 
01504     return *_u.L;
01505 }
01506 
01507 Set<BinRep> &
01508 BinRep::to_set() const
01509 {
01510     p_assert( is_set(), "not a set" );
01511     return *_u.S;
01512 }
01513 
01514 
01515 Database<String, BinRep> &
01516 BinRep::to_map() const
01517 {
01518     p_assert( is_map(), "not a map" );
01519 
01520     return *_u.D;
01521 }
01522 
01523 
01524 void
01525 BinRep::put_omega()
01526 {
01527     _destroy();
01528 
01529     _fc  = IEF_OMEGA;
01530     _len = 0;
01531     _u.C = 0;
01532 }
01533 
01534 void
01535 BinRep::put_tuple(List<BinRep> *L)
01536 {
01537     _destroy();
01538 
01539     _fc  = IEF_TUPLE_4;
01540     _len = 0;
01541     _u.L = L;
01542 }
01543 
01544 void
01545 BinRep::put_set(Set<BinRep> *S)
01546 {
01547     _destroy();
01548 
01549     _fc  = IEF_SET_4;
01550     _len = 0;
01551     _u.S = S;
01552 }
01553 
01554 void
01555 BinRep::put_map(Database<String,BinRep> *D)
01556 {
01557     p_abort( "not supported" );
01558 
01559     _destroy();
01560 
01561     _fc  = IEF_MAP_4;
01562     _len = 0;
01563     _u.D = D;
01564 }
01565 
01566 void
01567 BinRep::put_integer(const int x)
01568 {
01569     _destroy();
01570 
01571     switch (bytes_per_value(x)) {
01572     case 1:
01573         {
01574             binptr_1 *value = (binptr_1 *)malloc(sizeof(binptr_1));
01575 
01576             _fc  = IEF_INTEGER_1;
01577             _len = sizeof( *value );
01578 
01579             *value = (char) x;
01580             _u.C = (void *) value;
01581             break;
01582         }
01583 
01584     case 2:
01585         {
01586             binptr_2 *value = (binptr_2 *)malloc(sizeof(binptr_2));
01587 
01588             _fc  = IEF_INTEGER_2;
01589             _len = sizeof( *value );
01590 
01591             *value = (binptr_2) x;
01592             _u.C = (void *) value;
01593             break;
01594         }
01595 
01596     case 4:
01597         {
01598             binptr_4  *value = (binptr_4 *)malloc(sizeof(binptr_4));
01599 
01600             _fc  = IEF_INTEGER_4;
01601             _len = sizeof( *value );
01602 
01603             *value = (int) x;
01604             _u.C = (void *) value;
01605             break;
01606         }
01607     }
01608 }
01609 
01610 void
01611 BinRep::put_boolean(const Boolean b)
01612 {
01613     _destroy();
01614 
01615     _fc  = (b ? IEF_TRUE : IEF_FALSE);
01616     _len = 0;
01617     _u.C = 0;
01618 }
01619 
01620 void
01621 BinRep::put_string(const char *s, int length)
01622 {
01623     _destroy();
01624 
01625     char   *buffer = (char *)malloc((length + 1) * sizeof(char));
01626     BinPtr  p( buffer );
01627 
01628     p.store( s, length );
01629 
01630     _fc  = IEF_STRING_4;
01631     _len = length;
01632     _u.C = (void *) buffer;
01633 }
01634 
01635 void
01636 BinRep::put_string(const String & s)
01637 {
01638     const char *p = (const char *) s;
01639     put_string( p, s.len() );
01640 }
01641 
01642 void
01643 BinRep::put_string(const char *s)
01644 {
01645     put_string( s, strlen(s) );
01646 }
01647 
01648 void
01649 BinRep::put_double(const double d)
01650 {
01651     _destroy();
01652 
01653     double *value = (double *)malloc(sizeof(double));
01654 
01655     *value = d;
01656 
01657     _fc  = IEF_REAL;
01658     _len = sizeof( *value );
01659 
01660     _u.C = (void *) value;
01661 }
01662 
01663 
01664 Listable *
01665 BinRep::listable_clone() const
01666 {
01667     return new BinRep( *this );
01668 }
01669 
01670 void 
01671 BinRep::print(ostream & o) const
01672 {
01673     String  str;
01674 
01675     ascii_format( str );
01676     o << str;
01677 }
01678 
01679 BinRep &
01680 BinRep::operator[] (int i) const
01681 {
01682     p_assert( is_tuple(), "not a tuple" );
01683 
01684     List<BinRep> &L = to_tuple();
01685 
01686     if (i >= 0 && L.entries() > i)
01687         return L[i];
01688 
01689     return _omega();
01690 }
01691 
01692 BinRep &
01693 BinRep::operator[] (const char *field) const
01694 {
01695     BinRep    *b = find_ref( field );
01696 
01697     return ( (b != 0) ? *b : _omega() );
01698 }
01699 
01700 void
01701 BinRep::del(int i) 
01702 {
01703     p_assert( is_tuple(), "not a tuple" );
01704 
01705     List<BinRep> &L = to_tuple();
01706 
01707     if (i >= 0 && L.entries() > i)
01708         L.del(i);
01709 }
01710 
01711 void
01712 BinRep::del(const char *field) 
01713 {
01714     p_assert( is_set() == True || is_map() == True, "not a set or map" );
01715 
01716     if (is_set()) {
01717         for (Mutator<BinRep> iter = to_set(); iter.valid(); ++iter) {
01718             p_assert( iter.current().is_tuple(), "not a tuple" );
01719 
01720             List<BinRep> &L = iter.current().to_tuple();
01721 
01722             if (L.entries() == 2) {
01723                 BinRep &key = L[0];
01724 
01725                 if (key.is_string()) {
01726                     String    key_string;
01727 
01728                     key.to_string( key_string );
01729                     if (key_string == field) {
01730                         iter.del();
01731                         return;
01732                     }
01733                 }
01734             }
01735         }
01736     }
01737     else if (is_map()) {
01738         Database<String,BinRep> &D = to_map();
01739 
01740         String    s = field;
01741         BinRep *b = D.find_ref( s );
01742 
01743         if (b != 0)
01744             D.del( s );
01745     }
01746 }
01747 
01748 void
01749 BinRep::ins( BinRep *b )
01750 {
01751     if (is_tuple())
01752         to_tuple().ins_last( b );
01753     else if (is_set())
01754         to_set().ins( b );
01755     else {
01756         p_abort( "not a set or tuple" );
01757     }
01758 }
01759 
01760 void
01761 BinRep::ins( const BinRep &b )
01762 {
01763     if (is_tuple())
01764         to_tuple().ins_last( new BinRep(b) );
01765     else if (is_set())
01766         to_set().ins( new BinRep(b) );
01767     else {
01768         p_abort( "not a set or tuple" );
01769     }
01770 }
01771  
01772 
01773 BinRep *
01774 BinRep::clone() const
01775 {
01776     return new BinRep( *this );
01777 }
01778 
01779 BinRep *
01780 BinRep::find_ref(const char *field) const
01781 {
01782     p_assert( is_set() == True || is_map() == True, "not a set or map" );
01783 
01784     if (is_set()) {
01785         for (Iterator<BinRep> iter = to_set(); iter.valid(); ++iter) {
01786             p_assert( iter.current().is_tuple(), "not a tuple" );
01787 
01788             List<BinRep> &L = iter.current().to_tuple();
01789 
01790             if (L.entries() == 2) {
01791                 BinRep &key = L[0];
01792 
01793                 if (key.is_string()) {
01794                     String    key_string;
01795 
01796                     key.to_string( key_string );
01797                     if (key_string == field) 
01798                         return &L[1];
01799                 }
01800             }
01801         }
01802     }
01803     else if (is_map()) {
01804         Database<String,BinRep> &D = to_map();
01805 
01806         String    s = field;
01807         BinRep *b = D.find_ref( s );
01808 
01809         if (b != 0)
01810             return b;
01811     }
01812 
01813     return 0;
01814 }
01815 
01816 
01817 
01818 static char    *type_name[] = {
01819      "FT_OMEGA",        /// ...  FT_OMEGA (0)
01820      "FT_ATOM",         /// ...  FT_ATOM  (1)
01821      "FT_SHORT",        /// ...  FT_SHORT (2)
01822      "(Undefined)",     /// ...  (3)
01823      "(Undefined)",     /// ...  (4)
01824      "(Undefined)",     /// ...  (5)
01825      "(Undefined)",     /// ...  (6)
01826      "(Undefined)",     /// ...  (7)
01827      "(Undefined)",     /// ...  (8)
01828      "(Undefined)",     /// ...  (9)
01829      "FT_DOUBLE",       /// ...  FT_DOUBLE (10)
01830      "FT_LONGINT",      /// ...  FT_LONGINT (11)
01831      "FT_STRING",       /// ...  FT_STRING (12)
01832      "FT_TUPLE",        /// ...  FT_TUPLE (13)
01833      "(Undefined)",     /// ...  (14)
01834      "FT_SET"           /// ...  FT_SET (15)
01835 };
01836 
01837 static char    *ief_type_name[] = {
01838   "IEF_OMEGA",     // = 'A',   /// ...  Omega
01839   "IEF_TRUE",      // = 'B',   /// ...  True
01840   "IEF_FALSE",     // = 'C',   /// ...  False
01841   "IEF_REAL",      // = 'D',   /// ...  8 byte IEEE double  
01842   "IEF_INTEGER_1", // = 'E',   /// ...  1 byte signed integer    
01843   "IEF_INTEGER_2", // = 'F',   /// ...  2 byte signed integer    
01844   "IEF_INTEGER_4", // = 'G',   /// ...  4 byte signed integer
01845   "IEF_STRING_1",  // = 'H',   /// ...  1 byte unsigned length, up to $2^{8}-1$ 
01846   "IEF_STRING_2",  // = 'I',   /// ...  2 byte unsigned length, up to $2^{16}-1$
01847   "IEF_STRING_4",  // = 'J',   /// ...  4 byte unsigned length, up to $2^{32}-1$ 
01848   "IEF_TUPLE_1",   // = 'K',   /// ...  1 byte unsigned length, up to $2^{8}-1$ 
01849   "IEF_TUPLE_2",   // = 'L',   /// ...  2 byte unsigned length, up to $2^{16}-1$
01850   "IEF_TUPLE_4",   // = 'M',   /// ...  4 byte unsigned length, up to $2^{32}-1$
01851   "IEF_SET_1",     // = 'N',   /// ...  1 byte unsigned length, up to $2^{8}-1$ 
01852   "IEF_SET_2",     // = 'O',   /// ...  2 byte unsigned length, up to $2^{16}-1$
01853   "IEF_SET_4",     // = 'P',   /// ...  4 byte unsigned length, up to $2^{32}-1$
01854   "IEF_MAP_1",     // = 'Q',   /// ...  1 byte unsigned length, up to $2^{8}-1$ 
01855   "IEF_MAP_2",     // = 'R',   /// ...  2 byte unsigned length, up to $2^{16}-1$
01856   "IEF_MAP_4",     // = 'S',   /// ...  4 byte unsigned length, up to $2^{32}-1$
01857   "IEF_DICT_1",    // = 'T',   /// ...  1 byte unsigned dictionary index
01858   "IEF_DICT_2",    // = 'U',   /// ...  2 byte unsigned dictionary index 
01859   "IEF_DICT_4",    // = 'V',   /// ...  4 byte unsigned dictionary index 
01860 };
01861 
01862 char *
01863 binstr_type_name( BINSTR_TYPE expected_type )
01864 {
01865     int    index = (int) expected_type;
01866 
01867     if (index >= 0 && index <= 15)
01868         return type_name[index];
01869     else if (index >= 'A' && index <= 'Z')
01870         return ief_type_name[index - 'A'];
01871     else if (index == '$')
01872         return "IEF_HEADER";
01873     else if (index == '#')
01874         return "IEF_BODY";
01875 
01876     return "(undefined error)";
01877 }
01878 
 © 1995-2005 University of Illinois, Urbana-Champaign. All rights reserved.  Fri Mar 25 23:05:41 2005