The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Revision:
0:97a4f8cc534c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sqstdlib/sqstdblobimpl.h	Tue Dec 16 10:20:34 2014 +0000
@@ -0,0 +1,108 @@
+/*	see copyright notice in squirrel.h */
+#ifndef _SQSTD_BLOBIMPL_H_
+#define _SQSTD_BLOBIMPL_H_
+
+struct SQBlob : public SQStream
+{
+	SQBlob(SQInteger size) {
+		_size = size;
+		_allocated = size;
+		_buf = (unsigned char *)sq_malloc(size);
+		memset(_buf, 0, _size);
+		_ptr = 0;
+		_owns = true;
+	}
+	virtual ~SQBlob() {
+		sq_free(_buf, _allocated);
+	}
+	SQInteger Write(void *buffer, SQInteger size) {
+		if(!CanAdvance(size)) {
+			GrowBufOf(_ptr + size - _size);
+		}
+		memcpy(&_buf[_ptr], buffer, size);
+		_ptr += size;
+		return size;
+	}
+	SQInteger Read(void *buffer,SQInteger size) {
+		SQInteger n = size;
+		if(!CanAdvance(size)) {
+			if((_size - _ptr) > 0)
+				n = _size - _ptr;
+			else return 0;
+		}
+		memcpy(buffer, &_buf[_ptr], n);
+		_ptr += n;
+		return n;
+	}
+	bool Resize(SQInteger n) {
+		if(!_owns) return false;
+		if(n != _allocated) {
+			unsigned char *newbuf = (unsigned char *)sq_malloc(n);
+			memset(newbuf,0,n);
+			if(_size > n)
+				memcpy(newbuf,_buf,n);
+			else
+				memcpy(newbuf,_buf,_size);
+			sq_free(_buf,_allocated);
+			_buf=newbuf;
+			_allocated = n;
+			if(_size > _allocated)
+				_size = _allocated;
+			if(_ptr > _allocated)
+				_ptr = _allocated;
+		}
+		return true;
+	}
+	bool GrowBufOf(SQInteger n)
+	{
+		bool ret = true;
+		if(_size + n > _allocated) {
+			if(_size + n > _size * 2)
+				ret = Resize(_size + n);
+			else
+				ret = Resize(_size * 2);
+		}
+		_size = _size + n;
+		return ret;
+	}
+	bool CanAdvance(SQInteger n) {
+		if(_ptr+n>_size)return false;
+		return true;
+	}
+	SQInteger Seek(SQInteger offset, SQInteger origin) {
+		switch(origin) {
+			case SQ_SEEK_SET:
+				if(offset > _size || offset < 0) return -1;
+				_ptr = offset;
+				break;
+			case SQ_SEEK_CUR:
+				if(_ptr + offset > _size || _ptr + offset < 0) return -1;
+				_ptr += offset;
+				break;
+			case SQ_SEEK_END:
+				if(_size + offset > _size || _size + offset < 0) return -1;
+				_ptr = _size + offset;
+				break;
+			default: return -1;
+		}
+		return 0;
+	}
+	bool IsValid() {
+		return _buf?true:false;
+	}
+	bool EOS() {
+		return _ptr == _size;
+	}
+	SQInteger Flush() { return 0; }
+	SQInteger Tell() { return _ptr; }
+	SQInteger Len() { return _size; }
+	SQUserPointer GetBuf(){ return _buf; }
+private:
+	SQInteger _size;
+	SQInteger _allocated;
+	SQInteger _ptr;
+	unsigned char *_buf;
+	bool _owns;
+};
+
+#endif //_SQSTD_BLOBIMPL_H_