Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10761 was 9324, checked in by ponder, 18 years ago

Added byte_order.h to
Added binary_file.h binary_file.cc
Changed the bsp code to work on big endian machines.

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