This is a quick code snippet that should help many of youall out with this. Basically it's just a class wrapping the std::vector class with char or unsigned char passed as the template paramater. This should also give you an idea of how to expose many of the types found under the std namespace. I personally am using this class for a sockets extension I wrote (yes I will release it when I am done testing). Use this as you wish:
EDIT1: Added another class, ubytebuffer. Also made the classes suck less by not inheriting from the std::vector, option to hold one internally. Also overloaded the constructor to take a string for when the need arises.
// bytebuffer.h#include <vector>#include <iostream>#define CHECK if(r<0){std::cout<<"Error in angelscript exposure. Line:"<<__LINE__<<"\nFile: "<<std::string(__FILE__)<<"\n";}typedef uint8 unsigned char;class bytebuffer {public: bytebuffer(){ref_count = 1;}; bytebuffer(const std::string& in); bytebuffer(const bytebuffer& b){}; ~bytebuffer(){} uint8 front(); uint8 back(); uint8 operator[](int pos); int size(); void get_str(std::string& in); void flush(); void AddRef(){ref_count++;}; void Release(){if(--ref_count==0){delete this;}}; std::vector<char> invec; int ref_count;};class ubytebuffer {public: ubytebuffer(){ref_count = 1;}; ubytebuffer(const std::string& in); ubytebuffer(const ubytebuffer& b){}; ~ubytebuffer(){} uint8 front(); uint8 back(); uint8 operator[](int pos); int size(); void get_str(std::string& in); void flush(); void AddRef(){ref_count++;}; void Release(){if(--ref_count==0){delete this;}}; std::vector<uint8> invec; int ref_count;};// bytebuffer.cppbytebuffer::bytebuffer(const std::string& in) : invec(in.c_str(),in.c_str()+in.size()){}uint8 bytebuffer::front(){ return invec.front();}uint8 bytebuffer::back(){ return invec.back();}uint8 bytebuffer::operator[](int pos){ return invec[pos];}int bytebuffer::size(){ return invec.size();}void bytebuffer::get_str(std::string& in){ for(int i=0;i<invec.size();i++) in.push_back((char)invec);}void bytebuffer::flush(){ invec.clear();}ubytebuffer::ubytebuffer(const std::string& in) : invec(in.c_str(),in.c_str()+in.size()){}uint8 ubytebuffer::front(){ return invec.front();}uint8 ubytebuffer::back(){ return invec.back();}uint8 ubytebuffer::operator[](int pos){ return invec[pos];}int ubytebuffer::size(){ return invec.size();}extern "C" ubytebuffer::get_str(std::string& in){ for(int i=0;i<invec.size();i++) in.push_back((char)invec);}extern "C" ubytebuffer::flush(){ invec.clear();}extern "C" bytebuffer* ByteBufferFactory(){ return new bytebuffer;}extern "C" bytebuffer* ByteBufferFactory__(const std::string& in){ return new bytebuffer(in);}ARAD_C ubytebuffer* uByteBufferFactory(){ return new ubytebuffer;}ARAD_C ubytebuffer* uByteBufferFactory__(const std::string& in){ return new ubytebuffer(in);}ARAD_C void RegisterByteBuffer(asIScriptEngine* e){ int r; r=e->RegisterObjectType("bytebuffer",sizeof(bytebuffer), asOBJ_REF);CHECK; r=e->RegisterObjectBehaviour("bytebuffer",asBEHAVE_FACTORY,"bytebuffer@ f()",asFUNCTION(ByteBufferFactory),asCALL_CDECL);CHECK; r=e->RegisterObjectBehaviour("bytebuffer",asBEHAVE_FACTORY,"bytebuffer@ f(const string ∈)",asFUNCTION(ByteBufferFactory__),asCALL_CDECL);CHECK; r=e->RegisterObjectBehaviour("bytebuffer",asBEHAVE_ADDREF,"void f()",asMETHOD(bytebuffer,AddRef),asCALL_THISCALL);CHECK; r=e->RegisterObjectBehaviour("bytebuffer",asBEHAVE_RELEASE,"void f()",asMETHOD(bytebuffer,Release),asCALL_THISCALL);CHECK; r=e->RegisterObjectBehaviour("bytebuffer",asBEHAVE_INDEX,"int8 f(int)",asMETHOD(bytebuffer,operator[]),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("bytebuffer","int size()",asMETHOD(bytebuffer,size),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("bytebuffer","int8 back()",asMETHOD(bytebuffer,back),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("bytebuffer","int8 front()",asMETHOD(bytebuffer,front),asCALL_THISCALL);CHECK; r=e->RegisterObjectType("ubytebuffer",sizeof(ubytebuffer), asOBJ_REF);CHECK; r=e->RegisterObjectBehaviour("ubytebuffer",asBEHAVE_FACTORY,"ubytebuffer@ f()",asFUNCTION(uByteBufferFactory),asCALL_CDECL);CHECK; r=e->RegisterObjectBehaviour("ubytebuffer",asBEHAVE_FACTORY,"ubytebuffer@ f(const string ∈)",asFUNCTION(uByteBufferFactory__),asCALL_CDECL);CHECK; r=e->RegisterObjectBehaviour("ubytebuffer",asBEHAVE_ADDREF,"void f()",asMETHOD(ubytebuffer,AddRef),asCALL_THISCALL);CHECK; r=e->RegisterObjectBehaviour("ubytebuffer",asBEHAVE_RELEASE,"void f()",asMETHOD(ubytebuffer,Release),asCALL_THISCALL);CHECK; r=e->RegisterObjectBehaviour("ubytebuffer",asBEHAVE_INDEX,"uint8 f(int)",asMETHOD(ubytebuffer,operator[]),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("ubytebuffer","int size()",asMETHOD(ubytebuffer,size),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("ubytebuffer","uint8 back()",asMETHOD(ubytebuffer,back),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("ubytebuffer","uint8 front()",asMETHOD(ubytebuffer,front),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("ubytebuffer","void get_string(string@)",asMETHOD(ubytebuffer,get_str),asCALL_THISCALL);CHECK; r=e->RegisterObjectMethod("ubytebuffer","void flush(string@)",asMETHOD(ubytebuffer,flush),asCALL_THISCALL);CHECK;}
Then here is a script you can use to test it. Just replace println with whatever function you use to output stuff. println is basically std::cout<<whatever<<"\n":
// ByteBuffer test for AngelRAD... oh crap wasn't supposed to let that one slip =p// Author: ormvoid run(){ println("bytebuffer test"); println("testing string input.\n"); ubytebuffer@ second=ubytebuffer(string("GOBBLE!!!")); for(int j=0;j!=second.size();j++) { string t(); t+=second[j]; println(t); } string@ s = string(); second.get_string(s); println(s);}
[Edited by - _orm_ on June 26, 2010 1:48:11 PM]