Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/terrain/src/lib/util/filesys/binary_file.cc @ 9753

Last change on this file since 9753 was 9417, checked in by bensch, 18 years ago

Cleanup after merge

File size: 5.2 KB
Line 
1#include "binary_file.h"
2#include <ctype.h>
3#include <stdlib.h>
4
5int bytesize( const char _c )
6{
7  switch( _c)
8  {
9    case 'f':
10    case 'i':
11      return 4;
12    case 'b':
13      return 1;
14    case 's':
15      return 2;
16    default:
17      return 0;
18  }
19}
20
21pDataSemantics BinaryFile::compileSemantics( const char *_semantics )
22{
23  const char *curr = _semantics;
24  char *tmp = new char[strlen(_semantics)];
25  //Find out how many subchunks exist.
26  pDataSemantics chunk = new DataSemantics();
27  bool terminated = false;
28  int open = 0;
29  while ( *curr )
30  {
31    switch( *curr )
32    {
33      case 'i':
34      case 'f':
35      case 'b':
36      case 's':
37        chunk->numChunkNodes++;
38        break;
39      case '(':
40        terminated = false;
41        chunk->numChunkNodes++;
42        while ( *curr && terminated == false )
43        {
44          if ( *curr == ')' )
45            terminated = true;
46          curr++;
47        }
48        if ( !terminated )
49        {
50          printf( "Syntax error: ')' is missing" );
51          delete chunk;
52          return NULL;
53        }
54        break;
55      default:
56        break;
57    }
58    curr++;
59  }
60  //Compile the chunks...
61  chunk->chunks = new pDataSemantics[chunk->numChunkNodes];
62  int currChunk = 0;
63  curr = _semantics;
64  while ( *curr )
65  {
66    switch( *curr )
67    {
68      case 'i':
69      case 'f':
70      case 'b':
71      case 's':
72        chunk->chunks[currChunk] = new DataSemantics();
73        chunk->chunks[currChunk]->isTerminal = true;
74        chunk->chunks[currChunk]->type = bytesize( *curr );
75        chunk->chunks[currChunk]->totalSize = bytesize( *curr );
76        currChunk++;
77        break;
78        case '(': {
79        curr++;
80        open = 0;
81        memset( tmp, 0, strlen( _semantics ) );
82        char * cp = tmp;
83        while ( *curr )
84        {
85          if ( *curr == '(' )
86            open++;
87          if ( *curr == ')' )
88          {
89            if ( open )
90              open--;
91            else
92              break;
93          }
94          *cp = *curr;
95          cp++;
96          curr++;
97        }
98        *cp = '\0';
99        chunk->chunks[currChunk] = compileSemantics( tmp );
100        currChunk++;
101        }
102        break;
103      case ')':
104        printf( "Syntax error: ')' shouldn't appear here\n" );
105        delete[] tmp; delete chunk;
106        return NULL;
107        break;
108      default:
109        int multiplier = 1, quantifier = 0;
110        const char *start = curr;
111        const char *end = curr;
112        while ( isdigit( *end ) )
113        {
114          end++;
115        }
116        for ( const char *d = end-1; d >=start; --d )
117        {
118          quantifier+=multiplier*(*d-'0');
119          multiplier*=10;
120        }
121        if ( start == end )
122        {
123          printf( "Syntax error: '%c' is not known.\n", *curr );
124          delete[] tmp; delete chunk;
125          return NULL;
126        }
127        if ( currChunk )
128        {
129          chunk->chunks[currChunk-1]->quantifier = quantifier;
130          chunk->chunks[currChunk-1]->totalSize*= quantifier;
131        }
132        else
133        {
134          printf( "Syntax error: Quantifier without a preceding type\n" );
135          delete[] tmp; delete chunk;
136          return NULL;
137        }
138        curr = end-1;
139        break;
140    }
141    curr++;
142  }
143  for ( int i = 0; i < chunk->numChunkNodes; ++i )
144  {
145    chunk->totalSize+= chunk->chunks[i]->totalSize;
146  }
147  delete[] tmp;
148  return chunk;
149}
150
151void convert_data( pDataSemantics _comp, void *_data )
152{
153  char *ptr = (char*)_data;
154  short *sptr;
155  int *iptr;
156  if ( _comp->isTerminal )
157  {
158    switch( _comp->type )
159    {
160      case TT_INT:
161        iptr = (int*)ptr;
162        for ( int i = 0; i < _comp->quantifier; ++i )
163        {
164          swap32( iptr );
165          iptr++;
166        }
167        break;
168      case TT_SHORT:
169        sptr = (short*)ptr;
170        for ( int i = 0; i < _comp->quantifier; ++i )
171        {
172          swap16( sptr );
173          sptr++;
174        }
175        break;
176      case TT_BYTE:
177        break;
178    }
179  }
180  else
181  {
182    for ( int j = 0; j < _comp->quantifier; ++j )
183    {
184      for ( int i = 0; i < _comp->numChunkNodes; ++i )
185      {
186        convert_data( _comp->chunks[i], ptr );
187        ptr+= _comp->chunks[i]->totalSize;
188      }
189    }
190
191  }
192}
193void BinaryFile::read( const char *_semantics, int _chunks,
194                       void* _buf, size_t& _bytesRead )
195{
196  pDataSemantics comp = compileSemantics( _semantics );
197  fread( _buf, comp->totalSize, _chunks, this->handle() );
198  if ( byteorder != NATIVE_BYTEORDER )
199  {
200    for ( int i = 0; i < _chunks; ++i )
201    {
202      convert_data( comp, (char*)_buf+i*comp->totalSize );
203    }
204  }
205  _bytesRead = comp->totalSize*_chunks;
206  delete comp;
207}
208void BinaryFile::read( const char *_semantics,
209                       void* _buf, size_t& _bytesRead )
210{
211  pDataSemantics comp = compileSemantics( _semantics );
212  fread( _buf, comp->totalSize, 1, this->handle() );
213
214  if ( byteorder != NATIVE_BYTEORDER )
215  {
216    convert_data( comp, _buf );
217  }
218  delete comp;
219}
220
221void BinaryFile::write( const char *_semantics,
222                        void* _buf, size_t& _bytesWritten )
223{
224  pDataSemantics comp = compileSemantics( _semantics );
225  if ( byteorder != NATIVE_BYTEORDER )
226  {
227    convert_data( comp, _buf );
228  }
229  _bytesWritten = comp->totalSize;
230  fwrite( _buf, comp->totalSize, 1, this->handle() );
231  delete comp;
232}
Note: See TracBrowser for help on using the repository browser.