Pol  Revision:cb584c9
symcont.cpp
Go to the documentation of this file.
1 
8 #include "symcont.h"
9 
10 #include <cstdio>
11 #include <cstdlib>
12 #include <cstring>
13 #include <string>
14 
15 #include "../clib/logfacility.h"
16 #include "../clib/strutil.h"
17 
18 namespace Pol
19 {
20 namespace Bscript
21 {
23 {
24  s = NULL;
25  usedLen = allocLen = 0u;
26  growBy = PgrowBy;
27 }
29 {
30  if ( s )
31  free( s );
32  s = NULL;
33 }
34 
36 {
37  if ( s )
38  free( s );
39  s = NULL;
40  usedLen = allocLen = 0;
41 }
42 
43 void SymbolContainer::resize( unsigned lengthToAdd )
44 {
45  while ( usedLen + lengthToAdd > allocLen )
46  {
47  allocLen += growBy;
48  if ( s == NULL )
49  {
50  s = (char*)calloc( 1, (unsigned)allocLen );
51  usedLen = 0;
52  }
53  else
54  {
55  char* t = (char*)realloc( s, allocLen );
56  if ( t )
57  s = t;
58  else
59  throw std::runtime_error( "allocation failure in SymbolContainer::resize(" +
60  Clib::decint( allocLen ) + ")" );
61  }
62  }
63 }
64 
65 bool SymbolContainer::findexisting( const void* data, int datalen, unsigned& position )
66 {
67  int nstarting = usedLen - datalen + 1;
68  // don't use the first byte, because that's the "fake null"
69  for ( int i = 1; i < nstarting; i++ )
70  {
71  if ( memcmp( s + i, data, datalen ) == 0 )
72  {
73  position = i;
74  return true;
75  }
76  }
77  return false;
78 }
79 
80 void SymbolContainer::append( const char* string, unsigned& position )
81 {
82  int nChars = static_cast<unsigned int>( strlen( string ) + 1 );
83  if ( findexisting( string, nChars, position ) )
84  return;
85  resize( nChars );
86  strcpy( s + usedLen, string );
87  position = usedLen;
88  usedLen += nChars;
89 }
90 
91 void SymbolContainer::append( int lvalue, unsigned& position )
92 {
93  resize( sizeof lvalue );
94  std::memcpy( s + usedLen, &lvalue, sizeof( int ) );
95  position = usedLen;
96  usedLen += sizeof lvalue;
97 }
98 
99 void SymbolContainer::append( double dvalue, unsigned& position )
100 {
101  resize( sizeof dvalue );
102  std::memcpy( s + usedLen, &dvalue, sizeof( double ) );
103  position = usedLen;
104  usedLen += sizeof dvalue;
105 }
106 
107 void SymbolContainer::append( void* data, unsigned datalen, unsigned& position )
108 {
109  resize( datalen );
110  if ( findexisting( data, datalen, position ) )
111  return;
112  memcpy( s + usedLen, data, datalen );
113  position = usedLen;
114  usedLen += datalen;
115 }
116 
117 void SymbolContainer::write( FILE* fp )
118 {
119  if ( fwrite( &usedLen, sizeof usedLen, 1, fp ) != 1 )
120  throw std::runtime_error( "SymbolContainer::write failed" );
121  if ( fwrite( s, usedLen, 1, fp ) != 1 )
122  throw std::runtime_error( "SymbolContainer::write failed" );
123 }
124 
126 {
127  // we write the length, followed by the actual data.
128  return sizeof usedLen + usedLen;
129 }
130 
131 void SymbolContainer::write( char* fname )
132 {
133  FILE* fp = fopen( fname, "wb" );
134  if ( !fp )
135  throw std::runtime_error( std::string( "Unable to open " ) + fname + " for writing." );
136  write( fp );
137  fclose( fp );
138 }
139 
140 void SymbolContainer::read( FILE* fp )
141 {
142  size_t fread_res = fread( &usedLen, sizeof usedLen, 1, fp );
143  if ( fread_res != 1 )
144  throw std::runtime_error( "failed to read in SymbolContainer::read()." );
145  char* new_s = (char*)realloc( s, usedLen );
146  if ( !new_s )
147  throw std::runtime_error( "allocation failure in SymbolContainer::read()." );
148  s = new_s;
149  fread_res = fread( s, usedLen, 1, fp );
150  if ( fread_res != 1 )
151  throw std::runtime_error( "failed to read in SymbolContainer::read()." );
152  allocLen = usedLen;
153 }
154 
156 {
157  SymbolContainer::read( fp );
158  ST = (StoredToken*)s;
159 }
160 
161 void SymbolContainer::read( char* fname )
162 {
163  FILE* fp = fopen( fname, "rb" );
164  if ( !fp )
165  throw std::runtime_error( std::string( "Unable to open " ) + fname + " for reading." );
166  read( fp );
167  fclose( fp );
168 }
169 
170 void StoredTokenContainer::append_tok( const StoredToken& sToken, unsigned* pposition )
171 {
172  resize( sizeof sToken );
173  unsigned position = usedLen / sizeof( StoredToken );
174  usedLen += sizeof sToken;
175  atPut1( sToken, position );
176  if ( pposition )
177  *pposition = position;
178 }
179 
180 void StoredTokenContainer::atPut1( const StoredToken& sToken, unsigned position )
181 {
182  if ( position >= count() )
183  throw std::runtime_error( "Assigning token at invalid position " + Clib::decint( position ) +
184  ", range is 0.." + Clib::decint( count() - 1 ) );
185 
186  char* dst = s + position * sizeof( StoredToken );
187  StoredToken* st = (StoredToken*)dst;
188  *st = sToken;
189 }
190 
191 void StoredTokenContainer::atGet1( unsigned position, StoredToken& sToken ) const
192 {
193  if ( position >= count() )
194  throw std::runtime_error( "Retrieving token at invalid position " + Clib::decint( position ) +
195  ", range is 0.." + Clib::decint( count() - 1 ) );
196 
197  char* src = s + position * sizeof( StoredToken );
198  StoredToken* st = (StoredToken*)src;
199 
200  sToken = *st;
201 }
202 
204 {
206  ST = (StoredToken*)s;
207 }
208 
210 {
211  void* d = SymbolContainer::detach();
212  ST = NULL;
213  return d;
214 }
215 
216 void StoredTokenContainer::resize( unsigned lengthToAdd )
217 {
218  SymbolContainer::resize( lengthToAdd );
219  ST = (StoredToken*)s;
220 }
221 
222 StoredToken::StoredToken( unsigned char aModule, int aID, BTokenType aType, unsigned aOffset )
223  : type( static_cast<unsigned char>( aType ) ),
224  id( static_cast<unsigned char>( aID ) ),
225  offset( static_cast<unsigned short>( aOffset ) ),
226  module( aModule )
227 {
228  if ( offset != aOffset )
229  {
230  ERROR_PRINT << "Data segment overflowed.\n"
231  << "Flog the programmer for using 2-byte offsets in datafiles.\n";
232  throw std::runtime_error( "Data segment overflowed" );
233  }
234 }
235 }
236 }
void append_tok(const StoredToken &token, unsigned *position=NULL)
Definition: symcont.cpp:170
bool findexisting(const void *data, int datalen, unsigned &position)
Definition: symcont.cpp:65
void atGet1(unsigned position, StoredToken &token) const
Definition: symcont.cpp:191
std::string decint(unsigned short v)
Definition: strutil.cpp:64
virtual void pack(void) POL_OVERRIDE
Definition: symcont.cpp:203
virtual void read(FILE *fp) POL_OVERRIDE
Definition: symcont.cpp:155
virtual void write(FILE *fp)
Definition: symcont.cpp:117
unsigned short offset
Definition: symcont.h:33
virtual void pack(void)
Definition: symcont.h:57
unsigned int get_write_length() const
Definition: symcont.cpp:125
virtual void * detach(void)
Definition: symcont.h:70
void append(const char *string, unsigned &position)
Definition: symcont.cpp:80
virtual void resize(unsigned lengthToAdd) POL_OVERRIDE
Definition: symcont.cpp:216
std::unordered_map< u64, ScriptDiffData > data
Definition: osmod.cpp:966
SymbolContainer(int growBy=512)
Definition: symcont.cpp:22
void atPut1(const StoredToken &token, unsigned position)
Definition: symcont.cpp:180
virtual void read(FILE *fp)
Definition: symcont.cpp:140
#define ERROR_PRINT
Definition: logfacility.h:230
virtual void resize(unsigned lengthToAdd)
Definition: symcont.cpp:43
virtual void * detach(void) POL_OVERRIDE
Definition: symcont.cpp:209
Definition: berror.cpp:12
StoredToken(unsigned char aModule=0, int aID=CTRL_STATEMENTBEGIN, BTokenType aType=TYP_CONTROL, unsigned aOffset=0 )
Definition: symcont.cpp:222