Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

FrontierFile.cpp

Go to the documentation of this file.
00001 
00002 /*
00003     TSGL - Teddy Space Game Library
00004     Copyright (C) 2002 Timo Suoranta
00005     tksuoran@cc.helsinki.fi
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Lesser General Public
00009     License as published by the Free Software Foundation; either
00010     version 2.1 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Lesser General Public License for more details.
00016 
00017     You should have received a copy of the GNU Lesser General Public
00018     License along with this library; if not, write to the Free Software
00019     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021     $Id: FrontierFile.cpp,v 1.1 2002/01/08 20:47:05 tksuoran Exp $
00022 */
00023 
00024 
00025 #include "Teddy/SpaceGame/FrontierFile.h"
00026 #include "Teddy/SysSupport/EndianIn.h"
00027 #include "Teddy/SysSupport/Messages.h"
00028 #include <cstdlib>
00029 #include <cstring>
00030 #include <cctype>
00031 #include <cstdio>
00032 using namespace Teddy::SysSupport;
00033 
00034 
00035 namespace Teddy     {
00036 namespace SpaceGame {
00037 
00038 
00040 FrontierFile::FrontierFile( const char *fname, Uint32 options ){
00041     EndianIn *is;             
00042 
00043     is = new EndianIn( fname );
00044     is->set_bigendian();
00045 
00046     int len = is->len();
00047     buf = new char[ len ];
00048     is->read_all( buf );
00049     buf[len] = 0; 
00050     is->close(), is = NULL;
00051     pos = buf;
00052 
00053 }
00054 
00055 
00057 void FrontierFile::seek( const char *label ){
00058     pos = strstr( (char*)(pos), label );
00059     if( pos == 0 ){
00060         ffe_debug_msg( "Not found" );
00061     }
00062 }
00063 
00064 
00066 void FrontierFile::seek( const Sint32 bytes ){
00067     pos += bytes;
00068 }
00069 
00070 
00072 void FrontierFile::reset(){
00073     pos = buf;
00074 }
00075 
00076 
00078 void FrontierFile::skip_white(){
00079     while( isspace(*pos) ){
00080         pos++;
00081     }
00082 }
00083 
00084 
00086 int FrontierFile::get_type(){
00087     char *mark_beg;
00088     char  a;
00089     char  b;
00090 
00091     skip_white();
00092     mark_beg = pos;
00093 
00094 //  cout << "? ";
00095 //  cout.flush();
00096 
00097     while( true ){
00098         a = *pos;
00099 //      cout << a;
00100 //      cout.flush();
00101 
00102         if( pos != mark_beg ){
00103             //  End of label reference;
00104             //
00105             //  Unrecogniced strings from end of white spaces
00106             //  up to end of line or comma are intepreted as
00107             //  label references as label references
00108             if( a==13 || a==10 || a==13 || a==',' ){
00109 //              cout << " !lr "; cout.flush();
00110                 pos = mark_beg;
00111                 return FF_LABEL_REF;
00112             }
00113 
00114             //  Check if we hit unrecogniced element
00115             //  not terminated by newline or comma;
00116             //  simply skip those (db, dd, resb etc.)
00117             if( isspace(a) ){
00118                 skip_white();
00119                 mark_beg = pos;
00120                 continue;
00121             }
00122         }
00123 
00124         //  Byte
00125         if( a=='0' ){
00126             pos++;
00127             b = *pos;
00128             if( b=='x' ){
00129                 pos++;
00130 //              cout << " !b "; cout.flush();
00131                 return FF_BYTE;
00132             }else{
00133                 continue;
00134             }
00135         }
00136 
00137         //  Start of string
00138         if( a=='\'' ){
00139 //          cout << " !s "; cout.flush();
00140             return FF_STRING;
00141         }
00142 
00143         //  End of label definition
00144         if( a==':' ){
00145 //          cout << " !ld "; cout.flush();
00146             pos = mark_beg;
00147             return FF_LABEL_DEF;
00148         }
00149         pos++;
00150     }
00151 }
00152 
00153 
00155 Uint8 FrontierFile::get_byte(){
00156     static char         *s;
00157     static int           string_size = 0;
00158     static int           string_pos  = 0;
00159     static bool          use_string  = false;
00160     static const char   *str;
00161 
00162     if( use_string ){
00163         string_pos++;
00164 //      cout <<  "string_pos = "  << (int)(string_pos);
00165 //      cout << " string_size = " << (int)(string_size) << endl;
00166         if( string_pos==string_size ){
00167             string_size = 0;
00168             string_pos  = 0;
00169             use_string  = false;
00170             pos++;
00171         }
00172     }
00173 
00174     if( use_string==false ){
00175         switch( get_type() ){
00176 
00177         case FF_BYTE:
00178             return get_byte_low( false );
00179             break;
00180 
00181         case FF_STRING:
00182             s           = get_string();
00183             string_size = strlen(s);
00184             string_pos  = 0;
00185             use_string  = true;
00186             str         = s;
00187 //          cout << "String '" << s << "'" << endl;
00188             break;
00189 
00190         default:
00191             ffe_debug_msg( "unexpected data in file" );
00192             return 0;
00193             break;
00194         }
00195     }
00196 
00197     if( use_string ){
00198 //      cout << "get byte '" << (char)(str[string_pos]) << "'" << endl;
00199         return (Uint8)(str[string_pos]);
00200     }else{
00201         ffe_debug_msg( "Hmm?" );
00202         return 0;
00203     }
00204 }
00205 
00206 
00208 Uint8 FrontierFile::get_byte_low( bool gt ){
00209     char  a;
00210     char  b;
00211     char *hex_digits = "0123456789abcdef";
00212     int   a_val = 0;
00213     int   b_val = 0;
00214     int   val   = 0;
00215     int   len   = 0;
00216     int   i;
00217     int   typ;
00218 
00219     if( gt ){
00220         typ = get_type();
00221     }else{
00222         typ = FF_BYTE;
00223     }
00224     switch( typ ){
00225     case FF_BYTE:
00226         //  Get value of first digit
00227         a = *pos++;
00228 //      cout << "First digit is '" << a << endl; cout.flush();
00229         for( i=0; i<16; i++ ){
00230             if( hex_digits[i] == a ){
00231                 a_val = i;
00232                 len = 1;
00233                 break;
00234             }
00235         }
00236 
00237         //  Not even first hex digit found? (Should not happen in valid files)
00238         if( len!=1 ){
00239             break;
00240         }
00241 
00242         //  Look for second digit, get value
00243         b = *pos++;
00244 //      cout << "Second digit is '" << b << endl; cout.flush();
00245         for( i=0; i<16; i++ ){
00246             if( hex_digits[i] == b ){
00247                 b_val = i;
00248                 len = 2;
00249                 break;
00250             }
00251         }
00252 
00253         //  Determine return value as either single or double char hex number
00254         if( len==2 ){
00255             val = (a_val<<4) + b_val;
00256         }else{
00257             pos--;  //  Back one char; it wasn't a hex digit
00258             if( len==1 ){
00259                 val = a_val;
00260             }
00261         }
00262         break;
00263 
00264     case FF_STRING:
00265         printf( "ERROR Found String, was looking for Byte\n" );
00266         break;
00267 
00268     case FF_LABEL_DEF:
00269         printf( "ERROR Found Label Definition, was looking for Byte\n" );
00270         break;
00271 
00272     case FF_LABEL_REF:
00273         printf( "ERROR Found Label Reference, was looking for Byte\n" );
00274         break;
00275 
00276     case FF_UNKNOWN:
00277     default:
00278         printf( "ERROR Unknown, was looking for Byte\n" );
00279         break;
00280     }
00281 
00282     return val;
00283 
00284 }
00285 
00286 
00288 Sint8 FrontierFile::read_Sint8(){
00289     Sint8 i = get_byte();
00290     return i;
00291 }
00292 
00293 
00295 Sint16 FrontierFile::read_Sint16(){
00296     Sint32 b1 = get_byte();
00297     Sint32 b2 = get_byte();
00298     Sint32 i = b1 + (b2<<8);
00299     return i;
00300 }
00301 
00302 
00304 Sint32 FrontierFile::read_Sint32(){
00305     Sint32 b1 = get_byte();
00306     Sint32 b2 = get_byte();
00307     Sint32 b3 = get_byte();
00308     Sint32 b4 = get_byte();
00309     Sint32 i = b1 + (b2<<8) + (b3<<16) + (b4<<24);
00310     return i;
00311 }
00312 
00313 
00315 Uint8 FrontierFile::read_Uint8 (){
00316     Uint8 i = get_byte();
00317     return i;
00318 }
00319 
00320 
00322 Uint16 FrontierFile::read_Uint16(){
00323     Uint32 b1 = get_byte();
00324     Uint32 b2 = get_byte();
00325     Uint16 i = b1 + (b2<<8);
00326     return i;
00327 }
00328 
00329 
00331 Uint32 FrontierFile::read_Uint32(){
00332     Uint32 b1 = get_byte();
00333     Uint32 b2 = get_byte();
00334     Uint32 b3 = get_byte();
00335     Uint32 b4 = get_byte();
00336     Uint32 i = b1 + (b2<<8) + (b3<<16) + (b4<<24);
00337     return i;
00338 }
00339 
00340 
00342 float FrontierFile::read_float(){
00343     Uint32 i = get_byte() + (get_byte()<<8) + (get_byte()<<16) + (get_byte()<<24);
00344     float f = *(float*)(&i);
00345     return f;
00346 }
00347 
00348 
00350 char *FrontierFile::get_string(){
00351     char  *s   = new char[256];
00352     char  *beg = pos;
00353     int    len = 0;
00354 
00355 //  cout << "S: ";
00356     switch( get_type() ){
00357     case FF_LABEL_DEF:
00358         printf( "ERROR Found Label Definition, was looking for String\n" );
00359         break;
00360 
00361     case FF_LABEL_REF:
00362         printf( "ERROR Found Label Reference, was looking for String\n" );
00363         break;
00364 
00365     case FF_STRING:
00366         pos++;
00367         beg = pos;
00368         while( (*pos!='\'') && (*pos!=':') && (*pos!=10) && (*pos!=13) && (*pos!=',') ){
00369             s[len] = *pos;
00370             pos++;
00371             if( len<255 ){
00372                 len++;
00373             }
00374         }
00375         s[len] = 0;
00376         break;
00377 
00378     case FF_BYTE:
00379         printf( "ERROR Found Byte, was looking for String\n" );
00380         break;
00381 
00382     case FF_UNKNOWN:
00383     default:
00384         printf( "ERROR Unknown, was looking for String" );
00385         break;
00386     }
00387     return s;
00388 }
00389 
00390 
00392 char *FrontierFile::get_label_def(){
00393     char *s   = new char[256];
00394     char *beg = pos;
00395     int   len = 0;
00396 
00397 //  cout << "LD: ";
00398     switch( get_type() ){
00399     case FF_LABEL_DEF:
00400         while( (*pos!=':') && (*pos!=10) && (*pos!=13) ){
00401             s[len] = *pos;
00402             pos++;
00403             if( len<255 ){
00404                 len++;
00405             }
00406         }
00407         s[len] = 0;
00408         pos++;
00409         break;
00410 
00411     case FF_LABEL_REF:
00412         printf( "ERROR Found Label Reference, was looking for Label Definition\n" );
00413         break;
00414 
00415     case FF_STRING:
00416         printf( "ERROR Found String, was looking for Label Definition\n" );
00417         break;
00418 
00419     case FF_BYTE:
00420         printf( "ERROR Found Byte, was looking for Label Definition\n" );
00421         break;
00422 
00423     case FF_UNKNOWN:
00424     default:
00425         printf( "ERROR Unknown, was looking for Label Definition\n" );
00426         break;
00427     }
00428 //  cout << " D: '" << s << "' "<< endl;
00429     return s;
00430 }
00431 
00432 
00434 char *FrontierFile::get_label_ref(){
00435     char *s   = new char[ 80 ];
00436     int   len = 0;
00437     char *beg;
00438 
00439     switch( get_type() ){
00440     case FF_LABEL_DEF:
00441     case FF_LABEL_REF:
00442     case FF_STRING:
00443         beg = pos;
00444         while( (isspace(*pos)==0) && (*pos!=',') && (*pos!=10) && (*pos!=13) ){
00445             s[len] = *pos;
00446             pos++;
00447             if( len<72 ){
00448                 len++;
00449             }
00450         }
00451         s[len] = 0;
00452         break;
00453 
00454     case FF_BYTE:
00455         get_byte_low( false );
00456         get_byte();
00457         get_byte();
00458         get_byte();
00459         strcpy( s, "NULL" );
00460         break;
00461 
00462     case FF_UNKNOWN:
00463     default:
00464         break;
00465     }
00466     return s;
00467 }
00468 
00469 
00470 };  //  namespace SpaceGame
00471 };  //  namespace Teddy
00472 
00473