00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00020 #ifndef flc_membuf_H
00021 #define flc_membuf_H
00022
00023 #include <falcon/setup.h>
00024 #include <falcon/types.h>
00025 #include <falcon/garbageable.h>
00026 #include <falcon/deepitem.h>
00027 #include <falcon/error.h>
00028
00029 namespace Falcon {
00030
00031 class VMachine;
00032 class Stream;
00033 class CoreObject;
00034
00035 class FALCON_DYN_CLASS MemBuf: public DeepItem, public Garbageable
00036 {
00037 public:
00038 typedef void (*tf_deletor)( void* memory );
00039 enum {
00040 INVALID_MARK = 0xFFFFFFFF,
00041 MAX_LEN = 0xFFFFFFFF
00042 } t_enum_mark;
00043
00044 protected:
00045 byte *m_memory;
00046
00047 uint32 m_length;
00048 uint32 m_mark;
00049 uint32 m_limit;
00050 uint32 m_position;
00051
00052 uint16 m_wordSize;
00053 uint16 m_byteOrder;
00054
00055 CoreObject *m_dependant;
00056 tf_deletor m_deletor;
00057
00058 public:
00059
00065 MemBuf( uint32 ws, uint32 length );
00066
00078 MemBuf( uint32 ws, byte *data, uint32 length );
00079
00094 MemBuf( uint32 ws, byte *data, uint32 length, tf_deletor deletor );
00095
00102 virtual ~MemBuf();
00103
00104 uint16 wordSize() const { return m_wordSize; }
00105 uint32 length() const { return m_length; }
00106
00107 virtual uint32 get( uint32 pos ) const = 0;
00108 virtual void set( uint32 pos, uint32 value ) = 0;
00109
00110 uint32 position() const { return m_position; }
00111 uint32 getMark() const { return m_mark; }
00112 uint32 limit() const { return m_limit; }
00113
00119 void put( uint32 data )
00120 {
00121 if ( m_position >= length() )
00122 throw new AccessError( ErrorParam( e_arracc, __LINE__ ).module( __FILE__ ).symbol( "put" ).extra( "MemBuf" ) );
00123
00124 set( m_position++, data );
00125 }
00126
00132 uint32 get()
00133 {
00134 if ( m_position >= m_limit )
00135 throw new AccessError( ErrorParam( e_arracc, __LINE__ ).module( __FILE__ ).symbol( "get" ).extra( "MemBuf" ) );
00136
00137 return get( m_position++ );
00138 }
00139
00143 uint32 size() const { return m_length * m_wordSize; }
00144
00154 void resize( uint32 newSize );
00155
00157 byte *data() const { return m_memory; }
00158
00160 void limit( uint32 l )
00161 {
00162 if ( l > length() )
00163 throw new AccessError( ErrorParam( e_arracc, __LINE__ ).module( __FILE__ ).symbol( "limit" ).extra( "MemBuf" ) );
00164
00165 m_limit = l;
00166 if ( l < m_position )
00167 m_position = l;
00168 }
00169
00173 void position( uint32 p )
00174 {
00175 if ( p > m_limit )
00176 throw new AccessError( ErrorParam( e_arracc, __LINE__ ).module( __FILE__ ).symbol( "position" ).extra( "MemBuf" ) );
00177
00178 m_position = p;
00179 if ( m_mark < m_position )
00180 m_mark = INVALID_MARK;
00181 }
00182
00186 void placeMark( uint32 m )
00187 {
00188 if ( m > m_position )
00189 throw new AccessError( ErrorParam( e_arracc, __LINE__ ).module( __FILE__ ).symbol( "mark" ).extra( "MemBuf" ) );
00190
00191 m_mark = m;
00192 }
00193
00197 void placeMark()
00198 {
00199 m_mark = m_position;
00200 }
00201
00205 void reset()
00206 {
00207 if ( m_mark == INVALID_MARK )
00208 throw new AccessError( ErrorParam( e_arracc, __LINE__ ).module( __FILE__ ).symbol( "reset" ).extra( "MemBuf" ) );
00209
00210 m_position = m_mark;
00211 }
00212
00216 void rewind()
00217 {
00218 m_position = 0;
00219 m_mark = INVALID_MARK;
00220 }
00221
00222
00226 void clear()
00227 {
00228 m_position = 0;
00229 m_limit = m_length;
00230 m_mark = INVALID_MARK;
00231 }
00232
00236 void flip()
00237 {
00238 m_limit = m_position;
00239 m_position = 0;
00240 m_mark = INVALID_MARK;
00241 }
00242
00248 void compact();
00249
00251 uint32 remaining() const {
00252 return m_limit - m_position;
00253 }
00254
00258 void length( uint32 s ) { m_length = s; }
00259 void setData( byte *data, uint32 length, tf_deletor deletor = 0 );
00260
00264 CoreObject *dependant() const { return m_dependant; }
00265
00275 void dependant( CoreObject *g ) { m_dependant = g; }
00276
00277 virtual bool serialize( Stream *stream, bool bLive = false ) const;
00278
00279 static MemBuf *deserialize( VMachine *vm, Stream *stream );
00280
00285 static MemBuf *create( int nWordSize, uint32 length );
00286
00287 virtual MemBuf* clone() const;
00288 virtual void gcMark( uint32 gen );
00289
00290 virtual void readProperty( const String &, Item &item );
00291 virtual void writeProperty( const String &, const Item &item );
00292 virtual void readIndex( const Item &pos, Item &target );
00293 virtual void writeIndex( const Item &pos, const Item &target );
00294 };
00295
00296 class FALCON_DYN_CLASS MemBuf_1: public virtual MemBuf
00297 {
00298 public:
00299 MemBuf_1( uint32 length ):
00300 MemBuf( 1, length )
00301 {}
00302
00303 MemBuf_1( byte *data, uint32 length, tf_deletor deletor = 0 ):
00304 MemBuf( 1, data, length, deletor )
00305 {}
00306
00307 virtual uint32 get( uint32 pos ) const;
00308 virtual void set( uint32 pos, uint32 value );
00309 };
00310
00311 class FALCON_DYN_CLASS MemBuf_2: public virtual MemBuf
00312 {
00313 public:
00314 MemBuf_2( uint32 length ):
00315 MemBuf( 2, length )
00316 {}
00317
00318 MemBuf_2( byte *data, uint32 length, tf_deletor deletor = 0 ):
00319 MemBuf( 2, data, length, deletor )
00320 {}
00321
00322 virtual uint32 get( uint32 pos ) const;
00323 virtual void set( uint32 pos, uint32 value );
00324 };
00325
00326 class FALCON_DYN_CLASS MemBuf_3: public virtual MemBuf
00327 {
00328 public:
00329 MemBuf_3( uint32 length ):
00330 MemBuf( 3, length )
00331 {}
00332
00333 MemBuf_3( byte *data, uint32 length, tf_deletor deletor = 0 ):
00334 MemBuf( 3, data, length, deletor )
00335 {}
00336
00337 virtual uint32 get( uint32 pos ) const;
00338 virtual void set( uint32 pos, uint32 deletor );
00339 };
00340
00341 class FALCON_DYN_CLASS MemBuf_4: public virtual MemBuf
00342 {
00343 public:
00344 MemBuf_4( uint32 length ):
00345 MemBuf( 4, length )
00346 {}
00347
00348 MemBuf_4( byte *data, uint32 length, tf_deletor deletor = 0 ):
00349 MemBuf( 4, data, length, deletor )
00350 {}
00351
00352 virtual uint32 get( uint32 pos ) const;
00353 virtual void set( uint32 pos, uint32 value );
00354 };
00355
00356
00357 }
00358
00359 #endif
00360
00361