sqstdblobimpl.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /* see copyright notice in squirrel.h */
  2. #ifndef _SQSTD_BLOBIMPL_H_
  3. #define _SQSTD_BLOBIMPL_H_
  4. struct SQBlob : public SQStream
  5. {
  6. SQBlob(SQInteger size) {
  7. _size = size;
  8. _allocated = size;
  9. _buf = (unsigned char *)sq_malloc(size);
  10. memset(_buf, 0, _size);
  11. _ptr = 0;
  12. _owns = true;
  13. }
  14. virtual ~SQBlob() {
  15. sq_free(_buf, _allocated);
  16. }
  17. SQInteger Write(void *buffer, SQInteger size) {
  18. if(!CanAdvance(size)) {
  19. GrowBufOf(_ptr + size - _size);
  20. }
  21. memcpy(&_buf[_ptr], buffer, size);
  22. _ptr += size;
  23. return size;
  24. }
  25. SQInteger Read(void *buffer,SQInteger size) {
  26. SQInteger n = size;
  27. if(!CanAdvance(size)) {
  28. if((_size - _ptr) > 0)
  29. n = _size - _ptr;
  30. else return 0;
  31. }
  32. memcpy(buffer, &_buf[_ptr], n);
  33. _ptr += n;
  34. return n;
  35. }
  36. bool Resize(SQInteger n) {
  37. if(!_owns) return false;
  38. if(n != _allocated) {
  39. unsigned char *newbuf = (unsigned char *)sq_malloc(n);
  40. memset(newbuf,0,n);
  41. if(_size > n)
  42. memcpy(newbuf,_buf,n);
  43. else
  44. memcpy(newbuf,_buf,_size);
  45. sq_free(_buf,_allocated);
  46. _buf=newbuf;
  47. _allocated = n;
  48. if(_size > _allocated)
  49. _size = _allocated;
  50. if(_ptr > _allocated)
  51. _ptr = _allocated;
  52. }
  53. return true;
  54. }
  55. bool GrowBufOf(SQInteger n)
  56. {
  57. bool ret = true;
  58. if(_size + n > _allocated) {
  59. if(_size + n > _size * 2)
  60. ret = Resize(_size + n);
  61. else
  62. ret = Resize(_size * 2);
  63. }
  64. _size = _size + n;
  65. return ret;
  66. }
  67. bool CanAdvance(SQInteger n) {
  68. if(_ptr+n>_size)return false;
  69. return true;
  70. }
  71. SQInteger Seek(SQInteger offset, SQInteger origin) {
  72. switch(origin) {
  73. case SQ_SEEK_SET:
  74. if(offset > _size || offset < 0) return -1;
  75. _ptr = offset;
  76. break;
  77. case SQ_SEEK_CUR:
  78. if(_ptr + offset > _size || _ptr + offset < 0) return -1;
  79. _ptr += offset;
  80. break;
  81. case SQ_SEEK_END:
  82. if(_size + offset > _size || _size + offset < 0) return -1;
  83. _ptr = _size + offset;
  84. break;
  85. default: return -1;
  86. }
  87. return 0;
  88. }
  89. bool IsValid() {
  90. return _size == 0 || _buf?true:false;
  91. }
  92. bool EOS() {
  93. return _ptr == _size;
  94. }
  95. SQInteger Flush() { return 0; }
  96. SQInteger Tell() { return _ptr; }
  97. SQInteger Len() { return _size; }
  98. SQUserPointer GetBuf(){ return _buf; }
  99. private:
  100. SQInteger _size;
  101. SQInteger _allocated;
  102. SQInteger _ptr;
  103. unsigned char *_buf;
  104. bool _owns;
  105. };
  106. #endif //_SQSTD_BLOBIMPL_H_