SourceForge.jp

dkutilBuffer.h

説明を見る。
00001 
00007 #ifndef _dKingyoUtilClass_global_h_
00008 #define _dKingyoUtilClass_global_h_
00009 
00010 
00011 #include "dkutilDefined.h"
00012 #include "dkutilAllocatePolicy.h"
00013 
00014 
00015 namespace dkutil{
00016 
00017 
00018 
00020 typedef boost::scoped_array<char> temporary_buffer;
00021 
00022 
00025 /*
00026 class scoped_buffer : protected boost::noncopyable{
00027     typedef size_t size_type ;
00028     char *mptr;
00029     size_type  msize;
00030     void Allocate(char *buf,size_type size){
00031         if(size==0){
00032             mptr= NULL;
00033             msize = 0;
00034             return;
00035         }
00036         char *tmp=(char*)DKUTIL_SAFE_REALLOC(buf,size);
00037         if(!tmp){
00038             DK_TRUE_ASSERT_OR_THROW(!tmp,std::logic_error("メモリが足らん!"));
00039         }
00040         //0初期化
00041         memset(tmp,0,size);
00042         mptr = tmp;
00043         msize = size;
00044     }
00045 public:
00046     scoped_buffer(size_type size=0){
00047         Allocate(NULL,size);
00048     }
00049     ~scoped_buffer(){
00050         clear();
00051     }
00053     char *get()const{return mptr;}
00055     char *data()const{return get();}
00056     size_type capacity()const{return msize;}
00057     void clear(){DKUTIL_SAFE_FREE(mptr);msize=0;}
00059     bool isValid()const{return mptr != NULL;}
00061     void reset(size_type size)
00062   {
00063         DK_TRUE_ASSERT_OR_THROW(size==0,std::invalid_argument("scoped_buffer reset"));
00064         clear();
00065         Allocate(NULL,size);
00066   }
00067     size_type size()const{return msize;}
00069     void resize(size_type size){
00070         Allocate(mptr,size);
00071     }
00072     inline char operator [](size_type s){
00073         {//配列は0から始まる
00074             DK_TRUE_ASSERT_OR_THROW(s >= msize,std::overflow_error("scoped_buffer overflowなり"));
00075         }
00076         return get()[s];
00077     }
00078 
00079 };
00080 */
00081 
00082 
00083 template<class IMPL>
00084 class scoped_buffer_base: protected boost::noncopyable{
00085     typedef size_t size_type ;
00086     char *mptr;
00087     size_type  msize;
00088     IMPL ma;
00089     void Allocate(char *buf,size_type size){
00090         if(size==0){
00091             mptr= NULL;
00092             msize = 0;
00093             return;
00094         }
00095         char *tmp=(char*)DKUTIL_SAFE_REALLOC(buf,size);
00096         if(!tmp){
00097             DK_TRUE_ASSERT_OR_THROW(!tmp,std::logic_error("メモリが足らん!"));
00098         }
00099         //0初期化
00100         memset(tmp,0,size);
00101         mptr = tmp;
00102         msize = size;
00103     }
00104 public:
00105     scoped_buffer_base(size_type size=0){
00106         //try{
00107             Allocate(NULL,size);
00108         //catch(...){
00109         //  clear();
00110         //  throw;
00111         //}
00112     }
00113     virtual ~scoped_buffer_base(){
00114         clear();
00115     }
00117     char *get()const{return mptr;}
00119     char *data()const{return get();}
00120     size_type capacity()const{return msize;}
00121     void clear(){DKUTIL_SAFE_FREE(mptr);msize=0;}
00123     bool isValid()const{return mptr != NULL;}
00125     void reset(size_type size)
00126   {
00127         DK_TRUE_ASSERT_OR_THROW(size==0,std::invalid_argument("scoped_buffer reset"));
00128         clear();
00129         Allocate(NULL,size);
00130   }
00131     size_type size()const{return msize;}
00133     void resize(size_type size){
00134         Allocate(mptr,size);
00135     }
00136     inline char & operator [](size_type s){
00137         {//配列は0から始まる
00138             DK_TRUE_ASSERT_OR_THROW(s >= msize,std::overflow_error("scoped_buffer overflowなり"));
00139         }
00140         return (get())[s];
00141     }
00142     inline const char & operator [](size_type s)const{
00143         {//配列は0から始まる
00144             DK_TRUE_ASSERT_OR_THROW(s >= msize,std::overflow_error("scoped_buffer overflowなり"));
00145         }
00146         return (get())[s];
00147     }
00148 
00149 };
00151 typedef scoped_buffer_base<policy::allocate_policy_malloc> scoped_buffer;
00153 typedef scoped_buffer_base<policy::allocate_policy_globalalloc> scoped_globalalloc_buffer;
00154 
00159 template<class T>
00160 class offset_pusher : protected boost::noncopyable{
00161 public:
00162     typedef std::size_t size_type;
00163 private:
00164     T *mbuf;
00165     size_type moffset;
00166     size_type msize;
00167 protected:
00168     void SetOffset(size_type o){    moffset = o;}
00169     size_type GetOffset(){return moffset;}
00170     void OffsetPlus(size_type plus){ moffset += plus;}
00171     
00172 public:
00173 
00174     offset_pusher(const T *buff,size_type size) : mbuf(const_cast<T *>(buff)){
00175         moffset=0;
00176         msize = size;
00177     }
00178     T *now()const{return &mbuf[moffset];}
00179     T *get()const{
00180         return mbuf;
00181     }
00183     size_type size()const{return moffset;}
00185     size_type capacity()const{return msize;}
00192 
00193     int  push_back(const T *item,size_type num){
00194         int result=edk_SUCCEEDED;
00195         if(msize == moffset && //オフセットとbufferが同じ
00196             msize != 0)//buffer が0でない
00197         {
00198             throw std::out_of_range("すでにバッファは使いきっちまったっつーの!!");
00199         }
00200         if(msize - moffset < num){
00201             result = edk_Not_Satisfactory;
00202             num = msize - moffset;
00203         }
00204         {
00205             size_type i=0;
00206             for(;i<num;i++){
00207                 mbuf[moffset + i] = item[i];
00208             }
00209             moffset += i;
00210         }
00211         return result;
00212     }
00213     void reset(const T *buff,size_type size){
00214         mbuf = const_cast<T *>(buff);
00215         moffset=0;
00216         msize = size;
00217     }
00218 };
00219 
00220 
00232 template<typename T,typename A=std::allocator<T> >
00233 class buffer_base{
00234 public:
00235     typedef char value_type;
00236   typedef size_t size_type;
00237   typedef ptrdiff_t difference_type;
00238     typedef size_t size_type;
00239     typedef T * pointer;
00240     typedef T& reference;
00241     typedef const T &const_reference;
00242     typedef const T *const_pointer;
00243 private:
00244     T *buff;//バッファ
00245     size_type mcapacity;//許容容量(数。byte単位ではない)
00246     size_type msize;//使用済みサイズ(数。byte単位ではない)
00247     bool mEmpty;//エンプティか?
00248     void _construct(){
00249         mEmpty=true;buff=NULL;mcapacity=0;msize=0;
00250     }
00251     A mAlloc;
00253     void init_buf(void *buf,size_type num){
00254         ::memset(buf,0,sizeof(T) * num);
00255     }
00256 protected:
00257     void SetEmpty(bool e){  mEmpty = e;}
00258     void SetSize(size_type s){ msize = s;}
00259     void SetCapacity(size_type c){mcapacity = c;}
00260     /*
00261     struct buffer_SerializeStruct{
00262         size_type Capacity;
00263         size_type Size;
00264         bool Empty;
00265         buffer_SerializeStruct(
00266             size_type gCapacity,size_type gSize,bool gEmpty) : 
00267         Capacity(gCapacity) , Size(gSize) , Empty(gEmpty){
00268         }   
00269     };
00270     std::size_t GetSerializeSize()const{
00271         size_type lsize = sizeof(buffer_SerializeStruct); 
00272         lsize += mcapacity + private_::serialize_offset_pusher::get_top_size();
00273         return lsize;
00274     }
00275     bool GetSerializeData(char *buf,std::size_t bufsize)const{
00276         size_type lsize = GetSerializeSize();
00277         if(bufsize < lsize){
00278             return false;
00279         }
00280         
00281         
00282         buffer_SerializeStruct dat(mcapacity,msize,mEmpty);
00283         private_::serialize_offset_pusher pusher(buf,bufsize);
00284         pusher.push_back((const char *)&dat,sizeof(dat));
00285         
00286         if(DKUTIL_FAILED(pusher.push_back((const char *)data(),capacity())))
00287         {
00288              DEBUGASSERT(!"んなはずあるか!");
00289         }
00290         
00291         return true;
00292     }
00293 
00294     bool SetSerialize(char *buf,std::size_t size){
00295         clear();
00296         _construct();
00297     
00298         DK_TRUE_ASSERT_OR_THROW(
00299             (char)isLittleEndian() != buf[0],
00300             std::logic_error("Endianが違うからシリアライズできないなり(え、エンディアンの違いを意識しない機構を用意しろだって!?")
00301         );
00302         //ずらす・・・
00303         buf += private_::serialize_offset_pusher::get_top_size();
00304         
00305         //datにアっタッチする
00306         buffer_SerializeStruct *dat;
00307         dat = (buffer_SerializeStruct *)&buf[0];
00308 
00309         SetEmpty(dat->Empty);
00310         SetCapacity(dat->Capacity);
00311         SetSize(dat->Size);
00312         if(false==SetBuff(&buf[sizeof(buffer_SerializeStruct)],dat->Capacity)){
00313             DEBUGASSERT(!"そんなぁ!");
00314         }
00315         return true;
00316     }
00317     */
00318 public:
00319 
00320 
00321     buffer_base(){_construct();}
00322     buffer_base(size_type size){
00323         _construct();
00324         resize(size);
00325     }
00327     buffer_base(const buffer_base &data){
00328         _construct();
00329         if(data.isValid()){
00330             reserve(data.mcapacity);
00331             if(!data.empty()){
00332                 SetBuff(data.buff,data.mcapacity);
00333             }
00334         }
00335     }
00336 
00337     virtual ~buffer_base(){
00338         clear();
00339     }
00341     void clear(){
00342         if(isValid()){
00343             mAlloc.deallocate(buff);
00344             buff=NULL;
00345         }
00346         mEmpty=true;
00347         mcapacity=0;
00348         msize=0;
00349     }
00351     int reserve(size_type num){
00352         if(num==0) return edk_FAILED;
00353         clear();
00354         buff = mAlloc.allocate(num);
00355         if(!buff) return edk_FAILED;
00356         init_buf(buff,num);
00357         mcapacity = num;
00358         return edk_SUCCEEDED;
00359     }
00361     int resize(size_type size){
00362         return reserve(size);
00363     }
00369 
00370     bool SetBuff(const T *data,size_type num){
00371         if(! isValid())
00372         {//バッファ確保していなかったら確保
00373             reserve(num);
00374         }else{//既にバッファ確保済みならバッファを初期化
00375             init_buf(buff,num);
00376         }
00377         bool b=DKUTIL_SUCCEEDED(dkmemcpy(buff,mcapacity * sizeof(T),data,sizeof(T) * num));
00378         if(!b){return false;}
00379         mEmpty=false;
00380         msize = num;//コピー済みサイズ保存
00381 
00382         return true;
00383     }
00390 
00391     bool SetString(size_type buffsize,const char *str,...){
00392         if(sizeof(T) != sizeof(char)) throw std::logic_error("buffer_base/ sizeof(T) != sizeof(char)");
00393         
00394         temporary_buffer b(new char[buffsize]);
00395         SET_VA_LIST(b.get(),buffsize,str);
00396         size_type len = strlen(b.get());
00397         if( (int)(capacity() - len) <= 0)
00398         {//lenがcapacity()を超えていたら・・・
00399             b.get()[capacity() - 1] = NULL;
00400             len = capacity();
00401         }
00402         else
00403         {//超えていないのなら           
00404             
00405         }
00406         return SetBuff(b.get(),len);
00407     }
00408     bool SetString(const char *str,...){
00409         if(sizeof(T) != sizeof(char))
00410         {
00411             //sizeof(bool)==sizeof(char)だけど、
00412             //ん〜。typeidは嫌だし〜〜。SetStringだけのためにねぇ〜。
00413             throw std::logic_error("buffer_base/ sizeof(T) != sizeof(char)");
00414         }
00415         size_type buffsize = strlen(str);
00416         buffsize += 256;
00417         temporary_buffer b(new char[buffsize]);
00418         /*va_list VaList;
00419         va_start( VaList , str ) ;
00420         _vsnprintf( b.get() ,buffsize, str , VaList ) ;
00421         va_end( VaList ) ;*/
00422         SET_VA_LIST(b.get(),buffsize,str);
00423         size_type len = strlen(b.get());
00424         if( (int)(capacity() - len) <= 0)
00425         {//lenがcapacity()を超えていたら・・・
00426             b.get()[capacity() - 1] = NULL;
00427             len = capacity();
00428         }
00429         else
00430         {//超えていないのなら           
00431             
00432         }
00433         return SetBuff(b.get(),strlen(b.get()));
00434         /*buffer_base b;
00435         b.reserve(buffsize + 1);
00436         SET_VA_LIST(b.data(),b.capacity(),str);
00437         return SetBuff(b.data(),strlen(b.data()));*/
00438     }
00439     bool isValid()const{
00440         if(!buff){return false;}
00441         return true;
00442     }
00443     bool empty()const{
00444         return mEmpty;
00445     }
00447     size_type size()const{return msize;}
00449     size_type capacity()const{return mcapacity;}
00451     size_type byte_size()const{return size() * sizeof(T);}
00453     size_type byte_capacity()const{return capacity() * sizeof(T);}
00454     
00456     pointer data(){return buff;}
00457     const_pointer data()const {return buff;}
00459     reference at(size_type s){
00460         if(!isValid()) throw std::logic_error("buffer_base/ not initialized");
00461         if(size() < s) throw std::out_of_range("buffer_base::at / out of range");
00462         return buff[s];
00463     }
00464     const_reference at(size_type s)const{
00465         if(!isValid()) throw std::logic_error("buffer_base/ not initialized");
00466         if(size() < s) throw std::out_of_range("buffer_base::at / out of range");
00467         return buff[s];
00468     }
00470     reference operator[](size_type s){  return at(s);}
00471     const_reference operator[](size_type s)const{   return at(s);}
00472     
00473     friend bool operator==(buffer_base<T,A> t1,buffer_base<T,A> t2){
00474         return DKUTIL_SUCCEEDED(dkmemcmp(t1.data(),t1.size(),t2.data(),t2.size()));
00475     }
00476 
00477 };
00478 
00479 
00481 typedef buffer_base<BYTE> byte_buffer;
00482 typedef buffer_base<char> char_buffer;
00483 //typedef buffer_base<char> byte_buffer;
00484 
00485 
00487 /*
00488 template<BYTE_BUFFER_POLICY=byte_buffer>
00489 class buffer_operator{
00490     byte_buffer mBuff;
00491 public:
00492 
00493     buffer_operator(){}
00494     virtual ~buffer_operator(){}
00495     virtual ~file_operator(){close();}
00496     bool reset(const char *filename,const char *mode,const char *type){
00497         close();
00498         DK_TRUE_ASSERT_OR_THROW((filename==NULL || mode==NULL || type==NULL),
00499             std::invalid_argument("file_operator::resetinvalid argument"));
00500 
00501         mfilename=filename;
00502         mmode = mode;
00503         mmode += type;
00504         return true;
00505     }
00506     const char *filename()const{return mfilename.c_str();}
00507     const char *mode()const{return mmode.c_str();}
00508     bool open(){
00509         close();
00510         mfp=::fopen(mfilename.c_str(),mmode.c_str());
00511         if(mfp==NULL) return false;
00512         return true;
00513     }
00514     const FILE *handle()const{return mfp;}
00515 
00516     size_t read(void *buf,size_t size){
00517         check_fp();
00518         return fread((buf),1,size,mfp);
00519     }
00520     size_t write(void *buf,size_t size){
00521         check_fp();
00522         return fwrite((buf),1,size,mfp);
00523     }
00524     bool eof()const{
00525         check_fp();
00526         return ( 0 != feof(mfp) );
00527     }
00528     bool error()const{
00529         check_fp();
00530         return ( 0 != ferror(mfp) );
00531     }
00532     bool seek(long offset, int origin ){
00533         check_fp();
00534         return (0 == fseek(mfp,offset,origin) );
00535     }
00536     
00537     void close(){
00538         if(mfp){::fclose(mfp);mfp=NULL;}
00539     }
00540 
00541 
00542 };
00543 */
00544 
00556 template<std::size_t WORKSPACE_SIZE = 64,class BUFFER_T=byte_buffer>
00557 class WorkSpaceBase{
00558 public:
00559     typedef BUFFER_T BUFFER_TYPE;
00560     enum{
00561         enuWorkSize = WORKSPACE_SIZE,
00562     };
00563 #   ifdef _MSC_VER
00564     typedef BUFFER_T::size_type size_type;
00565     typedef BUFFER_T::pointer pointer;
00566     typedef BUFFER_T::const_pointer const_pointer;
00567 #else
00568     typedef size_t size_type;
00569     typedef char *pointer;
00570     typedef const pointer const_pointer;
00571 #endif
00572 
00573 private://めんどくさいし〜。
00574     char WorkData[enuWorkSize];
00575 
00576     BUFFER_T mDWorkSpace;
00577     void _construct(){
00578 
00579         NULL_CHAR_ARRAY(WorkData);
00580         mDWorkSpace.clear();
00581     }
00582 public:
00583 
00584 
00586     WorkSpaceBase(){
00587         _construct();
00588     }
00590     WorkSpaceBase(const WorkSpaceBase<WORKSPACE_SIZE,BUFFER_T> &data){
00591         _construct();
00592         if(data.mDWorkSpace.empty()){
00593             SetBuff(data.WorkData,enuWorkSize);
00594         }else{
00595             mDWorkSpace = data.mDWorkSpace;
00596         }
00597     }
00598     //destructor
00599     virtual ~WorkSpaceBase(){
00600         clear();
00601     }
00603     void clear(){
00604         mDWorkSpace.clear();
00605         NULL_CHAR_ARRAY(WorkData);
00606     }
00611     bool reserve(size_type size){
00612         if(size <= enuWorkSize || (!mDWorkSpace.empty())){
00613             return false;
00614         }
00615         mDWorkSpace.resize(size);
00616         return true;
00617     }
00619     bool resize(size_type size){
00620         return reserve(size);
00621     }
00623     pointer data(){
00624         if(mDWorkSpace.empty()){
00625             return WorkData;
00626         }else{
00627             return mDWorkSpace.data();
00628         }
00629     }
00630     const_pointer data()const{
00631         if(mDWorkSpace.empty()){
00632             return WorkData;
00633         }else{
00634             return mDWorkSpace.data();
00635         }
00636     }
00638     size_type capacity()const{
00639         if(mDWorkSpace.empty()){
00640             return enuWorkSize;
00641         }else{
00642             return mDWorkSpace.size();
00643         }
00644     }
00645 
00651 
00652     bool SetBuff(const char *src,size_type size){
00653         int r;
00654         if(!mDWorkSpace.isValid()){
00655             NULL_CHAR_ARRAY(WorkData);
00656             r = dkmemcpy(WorkData,capacity(),src,size);
00657             return DKUTIL_SUCCEEDED(r);
00658         }else{
00659             return  mDWorkSpace.SetBuff(src,size);
00660         }
00661         //return false;
00662     }
00663 
00664     bool SetString(size_type buffsize,const char *str,...){
00665         
00666         temporary_buffer b(new char[buffsize]);
00667         SET_VA_LIST(b.get(),buffsize,str);
00668         return SetBuff(b.get(),strlen(b.get()));
00669     }
00670     bool SetString(const char *str,...){
00671         
00672         size_type buffsize = strlen(str);
00673         buffsize += 256;
00674         temporary_buffer b(new char[buffsize]);
00675         SET_VA_LIST(b.get(),buffsize,str);
00676         return SetBuff(b.get(),strlen(b.get()));
00677     }
00678     
00679     
00680 };
00681 
00683 typedef WorkSpaceBase<> WorkSpace;
00684 
00685 
00686 }//end of dkutil namespace
00687 #endif//end of include once

dkutil 1.02リリース前 d金魚専用マニュアルバージョンに対してSun Dec 28 21:23:07 2003に生成されました。 doxygen 1.3.5