module firebird_databasebuffer; private import ibase; private import firebirdCommon; private import std.string; private import std.c.string; private import std.c.stdlib; final class DBPARAMBLOCK { private char []DbParamBlockVector; // Dynamically allocated DATABASEPARAMETERBLOCK structure private int DbParamBlockmSize=0, DbParamBlockmAlloc=0; // Its used size in bytes public: void DPBGrow(int needed) { // Allocate or grow the DbParamBlockVector, so that 'needed' bytes can be written (at least) if(this.DbParamBlockVector.length == 0) ++needed; // Initial alloc will require one more byte if((DbParamBlockmSize + needed) > DbParamBlockmAlloc) { // We need to grow the buffer. We use increments of BUFFERINCR bytes. needed = (needed / BUFFERINCR + 1) * BUFFERINCR; char[] newbuffer; newbuffer.length = DbParamBlockmAlloc + needed; if(this.DbParamBlockVector.length == 0) { // Initial allocation, initialize the version tag newbuffer[0] = isc_dpb_version1; DbParamBlockmSize = 1; } else { // Move the old buffer content to the new one this.DbParamBlockVector = newbuffer[0..DbParamBlockmSize]; this.DbParamBlockVector.length = 0; } this.DbParamBlockVector = newbuffer; DbParamBlockmAlloc += needed; } } void DPBInsert(char type, char *data) { // Insert a new char* 'cluster' int len = strlen(data); DPBGrow(len + 2); this.DbParamBlockVector[DbParamBlockmSize++] = type; this.DbParamBlockVector[DbParamBlockmSize++] = cast(char)(len); memcpy(&DbParamBlockVector[DbParamBlockmSize], cast(char*) data, len); DbParamBlockmSize += len; } void DPBInsert(char type, short data) { // Insert a new int16 'cluster' DPBGrow(2 + 2); this.DbParamBlockVector[DbParamBlockmSize++] = type; this.DbParamBlockVector[DbParamBlockmSize++] = cast(char)(2); short vax = cast(short) isc_vax_integer(cast(char*)&data, 2); *cast(short*)&DbParamBlockVector[DbParamBlockmSize] = vax; DbParamBlockmSize += 2; } void DPBInsert(char type, bool data) { // Insert a new bool 'cluster' DPBGrow(2 + 1); this.DbParamBlockVector[DbParamBlockmSize++] = type; this.DbParamBlockVector[DbParamBlockmSize++] = cast(char)(1); this.DbParamBlockVector[DbParamBlockmSize++] = cast(char)(data ? 1 : 0); } void DPBInsert(char type, char data) { // Insert a new byte 'cluster' DPBGrow(2 + 1); this.DbParamBlockVector[DbParamBlockmSize++] = type; this.DbParamBlockVector[DbParamBlockmSize++] = cast(char)(1); this.DbParamBlockVector[DbParamBlockmSize++] = data; } void DPBReset() { // Clears the DATABASEPARAMETERBLOCK if(DbParamBlockmAlloc != 0) { DbParamBlockVector.length = 0; DbParamBlockmSize = 0; DbParamBlockmAlloc = 0; } } char *DPBHandle(){ return this.DbParamBlockVector.ptr; } short DPBSize(){ return cast(short) DbParamBlockmSize; } } final class DPB { private: char []mBuffer; // Dynamically allocated DATABASEPARAMETERBLOCK structure int mSize, mAlloc; // Its used size in bytes - Its allocated size in bytes public: void DPBGrow(int needed) { // Allocate or grow the mBuffer, so that 'needed' bytes can be written (at least) if(this.mBuffer.length == 0) ++needed; // Initial alloc will require one more byte if((mSize + needed) > mAlloc) { // We need to grow the buffer. We use increments of BUFFERINCR bytes. needed = (needed / BUFFERINCR + 1) * BUFFERINCR; char[] newbuffer; newbuffer.length = mAlloc + needed; if(this.mBuffer.length == 0) { // Initial allocation, initialize the version tag newbuffer[0] = isc_dpb_version1; mSize = 1; } else { // Move the old buffer content to the new one this.mBuffer = newbuffer[0..mSize]; this.mBuffer.length = 0; } this.mBuffer = newbuffer; mAlloc += needed; } } void DPBInsert(char type, char *data) { // Insert a new char* 'cluster' int len = strlen(data); DPBGrow(len + 2); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(len); memcpy(&mBuffer[mSize], cast(char*) data, len); mSize += len; } void DPBInsert(char type, short data) { // Insert a new int16 'cluster' DPBGrow(2 + 2); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(2); short vax = cast(short) isc_vax_integer(cast(char*)&data, 2); //mBuffer ~= cast(short)isc_vax_integer(cast(char*)&data, 2); *cast(short*)&mBuffer[mSize] = vax; //this.mBuffer ~= vax & 255; //this.mBuffer ~= (vax >> 8) & 255; mSize += 2; } void DPBInsert(char type, bool data) { // Insert a new bool 'cluster' DPBGrow(2 + 1); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(1); this.mBuffer[mSize++] = cast(char)(data ? 1 : 0); } void DPBInsert(char type, char data) { // Insert a new byte 'cluster' DPBGrow(2 + 1); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(1); this.mBuffer[mSize++] = data; } void DPBReset() { // Clears the DATABASEPARAMETERBLOCK if(mAlloc != 0) { //free(mBuffer); mBuffer.length = 0; mSize = 0; mAlloc = 0; } } char *DPBHandle(){ return this.mBuffer.ptr; } short DPBSize(){ return cast(short) mSize; } this() { mSize = 0; mAlloc = 0; } ~this() { if(mAlloc != 0) mBuffer.length = 0; } } /+ class DPB { private: char *mBuffer; // Dynamically allocated DATABASEPARAMETERBLOCK structure int mSize, mAlloc; // Its used size in bytes - Its allocated size in bytes public: void DPBGrow(int needed) { if(mBuffer == null) ++needed; // Initial alloc will require one more byte if((mSize + needed) > mAlloc) { // We need to grow the buffer. We use increments of BUFFERINCR bytes. needed = (needed / BUFFERINCR + 1) * BUFFERINCR; char* newbuffer = cast(char *) malloc(mAlloc + needed); if(mBuffer == null) { // Initial allocation, initialize the version tag newbuffer[0] = isc_dpb_version1; mSize = 1; } else { // Move the old buffer content to the new one memcpy(newbuffer, mBuffer, mSize); free(mBuffer); } mBuffer = newbuffer; mAlloc += needed; } } void DPBInsert(char type, char *data) { // Insert a new char* 'cluster' int len = strlen(data); DPBGrow(len + 2); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(len); memcpy(&mBuffer[mSize], cast(char*) data, len); mSize += len; } void DPBInsert(char type, short data) { // Insert a new int16 'cluster' DPBGrow(2 + 2); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(2); short vax = cast(short) isc_vax_integer(cast(char*)&data, 2); //mBuffer ~= cast(short)isc_vax_integer(cast(char*)&data, 2); *cast(short*)&mBuffer[mSize] = vax; //this.mBuffer ~= vax & 255; //this.mBuffer ~= (vax >> 8) & 255; mSize += 2; } void DPBInsert(char type, bool data) { // Insert a new bool 'cluster' DPBGrow(2 + 1); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(1); this.mBuffer[mSize++] = cast(char)(data ? 1 : 0); } void DPBInsert(char type, char data) { // Insert a new byte 'cluster' DPBGrow(2 + 1); this.mBuffer[mSize++] = type; this.mBuffer[mSize++] = cast(char)(1); this.mBuffer[mSize++] = data; } void DPBReset() { // Clears the DATABASEPARAMETERBLOCK if(mAlloc != 0) { free(mBuffer); mSize = 0; mAlloc = 0; } } char *DPBHandle(){ return cast(char*) mBuffer; } short DPBSize() { return cast(short) mSize; } this() { mSize = 0; mAlloc = 0; } ~this() { if(mAlloc != 0) free(mBuffer); } } +/