Back to home page

Enduro/X

 
 

    


0001 /*  see copyright notice in pscript.h */
0002 #ifndef _PSSTD_BLOBIMPL_H_
0003 #define _PSSTD_BLOBIMPL_H_
0004 
0005 struct PSBlob : public PSStream
0006 {
0007     PSBlob(PSInteger size) {
0008         _size = size;
0009         _allocated = size;
0010         _buf = (unsigned char *)ps_malloc(size);
0011         memset(_buf, 0, _size);
0012         _ptr = 0;
0013         _owns = true;
0014     }
0015     virtual ~PSBlob() {
0016         ps_free(_buf, _allocated);
0017     }
0018     PSInteger Write(void *buffer, PSInteger size) {
0019         if(!CanAdvance(size)) {
0020             GrowBufOf(_ptr + size - _size);
0021         }
0022         memcpy(&_buf[_ptr], buffer, size);
0023         _ptr += size;
0024         return size;
0025     }
0026     PSInteger Read(void *buffer,PSInteger size) {
0027         PSInteger n = size;
0028         if(!CanAdvance(size)) {
0029             if((_size - _ptr) > 0)
0030                 n = _size - _ptr;
0031             else return 0;
0032         }
0033         memcpy(buffer, &_buf[_ptr], n);
0034         _ptr += n;
0035         return n;
0036     }
0037     /* Not implemented */
0038     PSUserPointer ReadLine(void *buffer,PSInteger size) {
0039         return NULL;
0040     }
0041     bool Resize(PSInteger n) {
0042         if(!_owns) return false;
0043         if(n != _allocated) {
0044             unsigned char *newbuf = (unsigned char *)ps_malloc(n);
0045             memset(newbuf,0,n);
0046             if(_size > n)
0047                 memcpy(newbuf,_buf,n);
0048             else
0049                 memcpy(newbuf,_buf,_size);
0050             ps_free(_buf,_allocated);
0051             _buf=newbuf;
0052             _allocated = n;
0053             if(_size > _allocated)
0054                 _size = _allocated;
0055             if(_ptr > _allocated)
0056                 _ptr = _allocated;
0057         }
0058         return true;
0059     }
0060     bool GrowBufOf(PSInteger n)
0061     {
0062         bool ret = true;
0063         if(_size + n > _allocated) {
0064             if(_size + n > _size * 2)
0065                 ret = Resize(_size + n);
0066             else
0067                 ret = Resize(_size * 2);
0068         }
0069         _size = _size + n;
0070         return ret;
0071     }
0072     bool CanAdvance(PSInteger n) {
0073         if(_ptr+n>_size)return false;
0074         return true;
0075     }
0076     PSInteger Seek(PSInteger offset, PSInteger origin) {
0077         switch(origin) {
0078             case PS_SEEK_SET:
0079                 if(offset > _size || offset < 0) return -1;
0080                 _ptr = offset;
0081                 break;
0082             case PS_SEEK_CUR:
0083                 if(_ptr + offset > _size || _ptr + offset < 0) return -1;
0084                 _ptr += offset;
0085                 break;
0086             case PS_SEEK_END:
0087                 if(_size + offset > _size || _size + offset < 0) return -1;
0088                 _ptr = _size + offset;
0089                 break;
0090             default: return -1;
0091         }
0092         return 0;
0093     }
0094     bool IsValid() {
0095         return _buf?true:false;
0096     }
0097     bool EOS() {
0098         return _ptr == _size;
0099     }
0100     PSInteger Flush() { return 0; }
0101     PSInteger Tell() { return _ptr; }
0102     PSInteger Len() { return _size; }
0103     PSUserPointer GetBuf(){ return _buf; }
0104 private:
0105     PSInteger _size;
0106     PSInteger _allocated;
0107     PSInteger _ptr;
0108     unsigned char *_buf;
0109     bool _owns;
0110 };
0111 
0112 #endif //_PSSTD_BLOBIMPL_H_