Pol  Revision:cb584c9
binaryfilescrobj.cpp
Go to the documentation of this file.
1 
8 #include "binaryfilescrobj.h"
9 
10 #include <fstream>
11 #include <stddef.h>
12 
13 #include "../bscript/berror.h"
14 #include "../bscript/bobject.h"
15 #include "../bscript/executor.h"
16 #include "../bscript/impstr.h"
17 #include "../bscript/objmembers.h"
18 #include "../bscript/objmethods.h"
19 #include "../clib/clib_endian.h"
20 #include "../clib/rawtypes.h"
21 
22 namespace Pol
23 {
24 namespace Core
25 {
27  : Bscript::BObjectImp( OTBinaryFile ),
28  _filename( "" ),
29  openmode( std::ios::in ),
30  bigendian( true )
31 {
32 }
33 
34 BBinaryfile::BBinaryfile( std::string filename, unsigned short mode, bool _bigendian )
35  : Bscript::BObjectImp( OTBinaryFile ), _filename( std::move(filename) ), bigendian( _bigendian )
36 {
37  using std::ios;
38 
39  // FIXME: ms::stl has different flag values then stlport :(
40  openmode = static_cast<ios::openmode>( 0x0 );
41  if ( mode & 0x01 )
42  openmode |= ios::in;
43  if ( mode & 0x02 )
44  openmode |= ios::out;
45  if ( mode & 0x04 )
46  openmode |= ios::ate;
47  if ( mode & 0x08 )
48  openmode |= ios::app;
49  if ( mode & 0x10 )
50  openmode |= ios::trunc;
51 
52  if ( !file.Open( filename, openmode ) )
53  return;
54 }
55 
57 {
58  file.Close();
59 }
60 
62 {
63  return sizeof( *this ) + _filename.capacity();
64 }
65 
66 Bscript::BObjectRef BBinaryfile::get_member_id( const int /*id*/ ) // id test
67 {
68  return Bscript::BObjectRef( new Bscript::BLong( 0 ) );
69 }
71 {
72  Bscript::ObjMember* objmember = Bscript::getKnownObjMember( membername );
73  if ( objmember != nullptr )
74  return this->get_member_id( objmember->id );
75  else
77 }
78 
80 {
81  Bscript::ObjMethod* objmethod = Bscript::getKnownObjMethod( methodname );
82  if ( objmethod != nullptr )
83  return this->call_method_id( objmethod->id, ex );
84  else
85  return nullptr;
86 }
87 
89  bool /*forcebuiltin*/ )
90 {
91  using namespace Bscript;
92  switch ( id )
93  {
94  case MTH_CLOSE:
95  file.Close();
96  return new BLong( 1 );
97  case MTH_SIZE:
98  return new BLong( static_cast<int>( file.FileSize( ex ) ) );
99  case MTH_SEEK:
100  {
101  using std::ios;
102 
103  if ( ex.numParams() != 2 )
104  return new BError( "Seek requires 2 parameter." );
105  int value, type;
106  if ( ( !ex.getParam( 0, value ) ) || ( !ex.getParam( 1, type ) ) )
107  return new BError( "Invalid parameter" );
108  // FIXME: ms::stl has different flag values then stlport :(
109  ios::seekdir seekdir;
110  if ( type & 0x01 )
111  seekdir = ios::cur;
112  else if ( type & 0x02 )
113  seekdir = ios::end;
114  else
115  seekdir = ios::beg;
116  if ( !file.Seek( value, seekdir ) )
117  return new BLong( 0 );
118  return new BLong( 1 );
119  }
120  case MTH_TELL:
121  return new BLong( static_cast<int>( file.Tell() ) );
122  case MTH_PEEK:
123  return new BLong( file.Peek() );
124  case MTH_FLUSH:
125  file.Flush();
126  return new BLong( 1 );
127 
128  case MTH_GETINT32:
129  {
130  u32 _u32;
131  if ( !file.Read( _u32 ) )
132  return new BError( "Failed to read" );
133  if ( bigendian )
134  _u32 = cfBEu32( _u32 );
135  return new BLong( _u32 );
136  }
137  case MTH_GETSINT32:
138  {
139  s32 _s32;
140  if ( !file.Read( _s32 ) )
141  return new BError( "Failed to read" );
142  if ( bigendian )
143  _s32 = cfBEu32( _s32 );
144  return new BLong( _s32 );
145  }
146  case MTH_GETINT16:
147  {
148  u16 _u16;
149  if ( !file.Read( _u16 ) )
150  return new BError( "Failed to read" );
151  if ( bigendian )
152  _u16 = cfBEu16( _u16 );
153  return new BLong( _u16 );
154  }
155  case MTH_GETSINT16:
156  {
157  s16 _s16;
158  if ( !file.Read( _s16 ) )
159  return new BError( "Failed to read" );
160  if ( bigendian )
161  _s16 = cfBEu16( _s16 );
162  return new BLong( _s16 );
163  }
164  case MTH_GETINT8:
165  {
166  u8 _u8;
167  if ( !file.Read( _u8 ) )
168  return new BError( "Failed to read" );
169  return new BLong( _u8 );
170  }
171  case MTH_GETSINT8:
172  {
173  s8 _s8;
174  if ( !file.Read( _s8 ) )
175  return new BError( "Failed to read" );
176  return new BLong( _s8 );
177  }
178  case MTH_GETSTRING:
179  {
180  if ( ex.numParams() != 1 )
181  return new BError( "GetString requires 1 parameter." );
182  int value;
183  if ( !ex.getParam( 0, value ) )
184  return new BError( "Invalid parameter" );
185  if ( value < 1 )
186  return new BError( "Len is negative or 0." );
187  std::vector<unsigned char> _char;
188  _char.resize( value );
189  if ( !file.Read( &_char[0], value ) )
190  return new BError( "Failed to read" );
191  int len = 0;
192  const char* _str = reinterpret_cast<const char*>( &_char[0] );
193  // Returns maximum of len characters or up to the first null-byte
194  while ( len < value && *( _str + len ) )
195  len++;
196  return new String( _str, len );
197  }
198 
199  case MTH_SETINT32:
200  {
201  if ( ex.numParams() != 1 )
202  return new BError( "SetInt32 requires 1 parameter." );
203  int value;
204  if ( !ex.getParam( 0, value ) )
205  return new BError( "Invalid parameter" );
206  u32 _u32 = static_cast<u32>( value );
207  if ( bigendian )
208  _u32 = cfBEu32( _u32 );
209  if ( !file.Write( _u32 ) )
210  return new BError( "Failed to write" );
211  return new BLong( 1 );
212  }
213  case MTH_SETSINT32:
214  {
215  if ( ex.numParams() != 1 )
216  return new BError( "SetSInt32 requires 1 parameter." );
217  int value;
218  if ( !ex.getParam( 0, value ) )
219  return new BError( "Invalid parameter" );
220  s32 _s32 = static_cast<s32>( value );
221  if ( bigendian )
222  _s32 = cfBEu32( _s32 );
223  if ( !file.Write( _s32 ) )
224  return new BError( "Failed to write" );
225  return new BLong( 1 );
226  }
227  case MTH_SETINT16:
228  {
229  if ( ex.numParams() != 1 )
230  return new BError( "SetInt16 requires 1 parameter." );
231  int value;
232  if ( !ex.getParam( 0, value ) )
233  return new BError( "Invalid parameter" );
234  u16 _u16 = static_cast<u16>( value );
235  if ( bigendian )
236  _u16 = cfBEu16( _u16 );
237  if ( !file.Write( _u16 ) )
238  return new BError( "Failed to write" );
239  return new BLong( 1 );
240  }
241  case MTH_SETSINT16:
242  {
243  if ( ex.numParams() != 1 )
244  return new BError( "SetSInt16 requires 1 parameter." );
245  int value;
246  if ( !ex.getParam( 0, value ) )
247  return new BError( "Invalid parameter" );
248  s16 _s16 = static_cast<s16>( value );
249  if ( bigendian )
250  _s16 = cfBEu16( _s16 );
251  if ( !file.Write( _s16 ) )
252  return new BError( "Failed to write" );
253  return new BLong( 1 );
254  }
255  case MTH_SETINT8:
256  {
257  if ( ex.numParams() != 1 )
258  return new BError( "SetInt8 requires 1 parameter." );
259  int value;
260  if ( !ex.getParam( 0, value ) )
261  return new BError( "Invalid parameter" );
262  u8 _u8 = static_cast<u8>( value );
263  if ( !file.Write( _u8 ) )
264  return new BError( "Failed to write" );
265  return new BLong( 1 );
266  }
267  case MTH_SETSINT8:
268  {
269  if ( ex.numParams() != 1 )
270  return new BError( "SetSInt8 requires 1 parameter." );
271  int value;
272  if ( !ex.getParam( 0, value ) )
273  return new BError( "Invalid parameter" );
274  s8 _s8 = static_cast<s8>( value );
275  if ( !file.Write( _s8 ) )
276  return new BError( "Failed to write" );
277  return new BLong( 1 );
278  }
279  case MTH_SETSTRING:
280  {
281  if ( ex.numParams() != 2 )
282  return new BError( "SetString requires 2 parameters." );
283  int value;
284  const String* text;
285  if ( ( !ex.getStringParam( 0, text ) ) || ( !ex.getParam( 1, value ) ) )
286  return new BError( "Invalid parameter" );
287  u32 len = static_cast<u32>( text->value().length() );
288  if ( value == 1 )
289  len++;
290  if ( !file.WriteString( text->value().c_str(), len ) )
291  return new BError( "Failed to write" );
292  return new BLong( 1 );
293  }
294 
295  default:
296  return nullptr;
297  }
298 }
299 
301 {
302  return new BBinaryfile( _filename, static_cast<unsigned short>( openmode ), bigendian );
303 }
304 
305 std::string BBinaryfile::getStringRep() const
306 {
307  return "BinaryFile";
308 }
309 
311 {
312  if ( _filename == "" )
313  return false;
314  return file.IsOpen();
315 }
316 
317 bool BBinaryfile::operator==( const Bscript::BObjectImp& objimp ) const
318 {
319  if ( objimp.isa( Bscript::BObjectImp::OTBinaryFile ) )
320  {
321  if ( ( (BBinaryfile&)objimp )._filename == _filename )
322  return true;
323  }
324  else if ( objimp.isa( Bscript::BObjectImp::OTBoolean ) )
325  return isTrue() == static_cast<const Bscript::BBoolean&>( objimp ).isTrue();
326  return false;
327 }
328 
329 BinFile::BinFile( const std::string& filename, std::ios::openmode mode )
330 {
331  Open( filename, mode );
332 }
333 
335 {
336  Close();
337 }
338 
339 bool BinFile::Open( const std::string& filename, std::ios::openmode mode )
340 {
341  if ( _file.is_open() )
342  return true;
343 
344  _file.open( filename.c_str(), mode | std::ios::binary );
345  if ( !_file.is_open() )
346  return false;
347  return true;
348 }
349 
351 {
352  return _file.is_open();
353 }
354 
356 {
357  if ( !_file.is_open() )
358  return;
359 
360  _file.close();
361 }
362 
363 bool BinFile::Seek( std::fstream::pos_type abs_offset, std::ios::seekdir origin )
364 {
365  if ( !_file.is_open() )
366  return false;
367 
368  if ( !_file.seekg( abs_offset, origin ) )
369  return false;
370  return true;
371 }
372 
373 bool BinFile::ReadBuffer( void* buffer, std::streamsize length )
374 {
375  if ( !_file.read( reinterpret_cast<char*>( buffer ), length ) )
376  return false;
377  return true;
378 }
379 
380 bool BinFile::WriteBuffer( void* buffer, std::streamsize length )
381 {
382  if ( !_file.write( reinterpret_cast<char*>( buffer ), length ) )
383  return false;
384  return true;
385 }
386 
387 bool BinFile::WriteString( const char* chr, unsigned len )
388 {
389  if ( !_file.write( chr, len ) )
390  return false;
391  return true;
392 }
393 
394 std::fstream::pos_type BinFile::FileSize( Bscript::Executor& exec )
395 {
396  if ( !_file.is_open() )
397  return std::fstream::pos_type( 0 );
398 
399  std::fstream::pos_type save_pos = _file.tellg();
400  if ( save_pos == std::fstream::pos_type( -1 ) )
401  {
402  exec.setFunctionResult(
403  new Bscript::BError( "FileSize failed to determine current position." ) );
404  return std::fstream::pos_type( 0 );
405  }
406  if ( !_file.seekg( 0, std::ios::end ) )
407  {
408  exec.setFunctionResult( new Bscript::BError( "FileSize failed to seek to end of file." ) );
409  return std::fstream::pos_type( 0 );
410  }
411  std::fstream::pos_type size = _file.tellg();
412  if ( size == std::fstream::pos_type( -1 ) )
413  {
414  exec.setFunctionResult( new Bscript::BError( "FileSize could not determine file size." ) );
415  return std::fstream::pos_type( 0 );
416  }
417  if ( !_file.seekg( save_pos ) )
418  {
419  exec.setFunctionResult(
420  new Bscript::BError( "FileSize failed to seek to original position." ) );
421  return std::fstream::pos_type( 0 );
422  }
423  return size;
424 }
425 
426 std::fstream::pos_type BinFile::Tell()
427 {
428  if ( !_file.is_open() )
429  return -1;
430  return _file.tellg();
431 }
432 
434 {
435  if ( !_file.is_open() )
436  return -1;
437  return _file.peek();
438 }
439 
441 {
442  if ( _file.is_open() )
443  _file.flush();
444 }
445 }
446 }
void setFunctionResult(BObjectImp *imp)
Definition: executor.cpp:374
unsigned char u8
Definition: rawtypes.h:25
bool WriteBuffer(void *buffer, std::streamsize length)
const std::string & value() const
Definition: impstr.h:67
bool WriteString(const char *chr, unsigned len)
virtual bool operator==(const Bscript::BObjectImp &objimp) const POL_OVERRIDE
BObjectType type() const
Definition: bobject.h:358
bool isa(BObjectType type) const
Definition: bobject.h:353
bool ReadBuffer(void *buffer, std::streamsize length)
char * binary(unsigned int val, int nbits)
#define cfBEu32(x)
Definition: clib_endian.h:43
ObjMember * getKnownObjMember(const char *token)
Definition: parser.cpp:483
STL namespace.
ObjMethod * getKnownObjMethod(const char *token)
Definition: parser.cpp:666
virtual Bscript::BObjectRef get_member(const char *membername) POL_OVERRIDE
virtual Bscript::BObjectImp * copy() const POL_OVERRIDE
bool Seek(std::fstream::pos_type abs_offset, std::ios::seekdir origin)
std::fstream::pos_type Tell()
unsigned short u16
Definition: rawtypes.h:26
unsigned char buffer[10000]
Definition: UoToolMain.cpp:109
unsigned int u32
Definition: rawtypes.h:27
signed short s16
Definition: rawtypes.h:30
std::ios::openmode openmode
virtual std::string getStringRep() const POL_OVERRIDE
static UninitObject * create()
Definition: bobject.h:482
signed int s32
Definition: rawtypes.h:31
virtual Bscript::BObjectRef get_member_id(const int id) POL_OVERRIDE
size_t numParams() const
Definition: executor.h:145
std::fstream::pos_type FileSize(Bscript::Executor &exec)
#define cfBEu16(x)
Definition: clib_endian.h:44
signed char s8
Definition: rawtypes.h:29
bool Open(const std::string &filename, std::ios::openmode mode)
virtual Bscript::BObjectImp * call_method_id(const int id, Bscript::Executor &ex, bool forcebuiltin=false) POL_OVERRIDE
const String * getStringParam(unsigned param)
Definition: executor.cpp:347
virtual size_t sizeEstimate() const POL_OVERRIDE
virtual bool isTrue() const POL_OVERRIDE
Definition: berror.cpp:12
virtual Bscript::BObjectImp * call_method(const char *methodname, Bscript::Executor &ex) POL_OVERRIDE
bool getParam(unsigned param, int &value)
Definition: executor.cpp:363