📄 wy__hstr.cpp
字号:
/* Copyright is licensed by GNU LGPL. by I.J.Wang 2004*/#define WYLIB_SOURCE#include "wy__hstr.h"#include <cstdlib>#include <cstring>#include <limits>// [Syn] Copy element pointed by src_ptr to position pointed by des_ptr// and increase src_ptr/des_ptr to the next position. This procedure// iterates n_size times.//// Note: Macro is intended for small-size string copy (or move)// For string copy operation make sure "des_ptr <= src_ptr" //// [Ret] src_ptr+=n_size// des_ptr+=n_size//#define WY__FCOPY(des_ptr,src_ptr,n_size) \ for(int i=n_size; i>0; --i) { *((des_ptr)++)=*((src_ptr)++); }// [Syn] Copy element pointed by src_ptr to position pointed by des_ptr// and decrease src_ptr/des_ptr to the previous position. This procedure// iterates n_size times.//// Note: Macro is intended for small-size string copy (or move)// For string copy operation make sure "src_ptr <= des_ptr" and// src/des point to the last element of the string//// [Ret] src_ptr-=n_size// des_ptr-=n_size//#define WY__BCOPY(des_ptr,src_ptr,n_size) \ for(int i=n_size; i>0; --i) { *((des_ptr)--)=*((src_ptr)--); }#ifndef __USE_GNUstatic void* memrchr(const void *s, int c, size_t n){ const char Tch( static_cast<char>(c) ); // not really sure for(const char*p(static_cast<const char*>(s)+n-1); n>0; --p,--n) { if(*p==Tch) { return(const_cast<char*>(p)); } } return(NULL);};#endifconst char Wy__HStr::class_name[]="Wy__HStr";//#define WY__DUMPMSG#ifdef WY__DUMPMSG#include <iostream>#endifclass Wy__HStr::Wy__Assert_Check { public: Wy__Assert_Check() { if(max_capacity()>static_cast<Wy__HStr::size_type>( std::numeric_limits<ssize_t>::max()/2-1)) { WY_TERMINATE(""); }; if(((int)DefaultObjSize-(int)sizeof(value_type)-(int)sizeof(Wy__HStr)) !=min_capacity()) { WY_TERMINATE(""); // DefaultObjSize too small } if(_memsize(0)!=DefaultObjSize) { WY_TERMINATE(""); } if(_memsize(min_capacity())!=DefaultObjSize) { WY_TERMINATE(""); } if(_capmem(DefaultObjSize)!=min_capacity()) { WY_TERMINATE(""); } if(_capmem( _memsize(min_capacity()) )!=min_capacity()) { WY_TERMINATE(""); } for(size_type i=0; i<9*BufGranBitsMask; i+=BufGranBitsMask) { if(_memsize(i)<i+sizeof(Wy__HStr)+sizeof(value_type)) {#ifdef WY__DUMPMSG std::cout << i << std::endl;#endif WY_TERMINATE(""); } if(_memsize(i)<DefaultObjSize) {#ifdef WY__DUMPMSG std::cout << i << std::endl;#endif WY_TERMINATE(""); } } for(size_type i=DefaultObjSize; i<9*BufGranBitsMask; i+=BufGranBitsMask) { if(_capmem(i)+sizeof(Wy__HStr)+sizeof(value_type)<i) {#ifdef WY__DUMPMSG std::cout << i << std::endl;#endif WY_TERMINATE(""); } } // Note: min_capacity has to be enough for 1. "UTC" 2. arithmetic // type representation to prevent Wym_EFBIG report // if(min_capacity()<64+1) { // long long in radix 2 WY_TERMINATE(""); } if(max_capacity()<WY_WHAT_IS_MAX_SIZE) { WY_TERMINATE(""); // should be enough for wrd(..) } };} static const wy__do_not_use_me__;Wy__HStr* Wy__HStr::alloc(void) WY__TSPC(Reply){ const size_type tsize=_memsize(min_capacity()); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=0; _data_buf(hptr)[0]=EOS;#ifdef WY_DEBUG _data_buf(hptr)[hptr->_m_dcap]=-5; // last char of _data_buf if(((char*)hptr)[tsize-1]!=-5) { // last char of object WY_TERMINATE(""); } _data_buf(hptr)[hptr->_m_dcap]=0x5a; // last char of _data_buf if(((char*)hptr)[tsize-1]!=0x5a) { // last char of object WY_TERMINATE(""); }#endif return(hptr);};Wy__HStr* Wy__HStr::alloc(const Wy__HStr& str) WY__TSPC(Reply){ const size_type str_size(str.size()); const size_type tsize=_memsize(str_size); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=str_size; std::memcpy(_data_buf(hptr),_data_buf(&str),str_size); _data_buf(hptr)[str_size]=EOS; return(hptr);};Wy__HStr* Wy__HStr::alloc(size_type cap) WY__TSPC(Reply){ if(cap>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(cap); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=0; _data_buf(hptr)[0]=EOS; return(hptr);};Wy__HStr* Wy__HStr::alloc(size_type cnum, value_type ch) WY__TSPC(Reply){ if(cnum>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(cnum); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=cnum; std::memset(_data_buf(hptr),ch,cnum); _data_buf(hptr)[cnum]=EOS; return(hptr);};Wy__HStr* Wy__HStr::alloc(const WyCSeg& cs) WY__TSPC(Reply){ const size_type csize(cs.size()); if(csize>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(csize); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=csize; std::memcpy(_data_buf(hptr),cs.begin(),csize); _data_buf(hptr)[csize]=EOS; return(hptr);};// note: buffer capacity is larger than enough by 1/4//Wy__HStr* Wy__HStr::alloc(const WyCSeg& cs1, const WyCSeg& cs2) WY__TSPC(Reply){ const size_type csize1(cs1.size()); const size_type csize2(cs2.size()); if((csize1>Wy__HStr::max_capacity())||(csize2>Wy__HStr::max_capacity())) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type rs(csize1+csize2); if(rs>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(rs+(rs>>2)); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=rs; std::memcpy(_data_buf(hptr) ,cs1.begin(),csize1); std::memcpy(_data_buf(hptr)+csize1,cs2.begin(),csize2); _data_buf(hptr)[rs]=EOS; return(hptr);};// note: buffer capacity is larger than enough by 1/4//Wy__HStr* Wy__HStr::alloc(const WyCSeg& cs1, const WyCSeg& cs2, const WyCSeg& cs3) WY__TSPC(Reply){ const size_type csize1(cs1.size()); const size_type csize2(cs2.size()); const size_type csize3(cs3.size()); if((csize1>Wy__HStr::max_capacity())||(csize2>Wy__HStr::max_capacity()) ||(csize3>Wy__HStr::max_capacity())) { WY_THROW( Reply(Wym_EFBIG) ); } size_type rs(csize1+csize2); if(rs>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } rs+=csize3; if(rs>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(rs+(rs>>2)); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=rs; std::memcpy(_data_buf(hptr) ,cs1.begin(),csize1); std::memcpy(_data_buf(hptr)+csize1 ,cs2.begin(),csize2); std::memcpy(_data_buf(hptr)+csize1+csize2,cs3.begin(),csize3); _data_buf(hptr)[rs]=EOS; return(hptr);};// note: buffer capacity is larger than enough by 1/4//Wy__HStr* Wy__HStr::alloc(const WyCSeg& cs, value_type ch) WY__TSPC(Reply){ const size_type csize( cs.size() ); if(csize>=max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(csize+sizeof(ch)+(csize>>2)); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=csize+1; Wy::_strcpy(_data_buf(hptr),cs); _data_buf(hptr)[csize]=ch; _data_buf(hptr)[hptr->_m_dlen]=EOS; return(hptr);};// note: buffer capacity is larger than enough by 1/4//Wy__HStr* Wy__HStr::alloc(value_type ch,const WyCSeg& cs) WY__TSPC(Reply){ const size_type csize( cs.size() ); if(csize>=max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(csize+sizeof(ch)+(csize>>2)); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=csize+1; _data_buf(hptr)[0]=ch; Wy::_strcpy(_data_buf(hptr)+1,cs); _data_buf(hptr)[hptr->_m_dlen]=EOS; return(hptr);};// note: buffer capacity is larger than enough by 1/4//Wy__HStr* Wy__HStr::alloc(const WyCSeg& cs, size_type cnum, value_type ch) WY__TSPC(Reply){ const size_type csize(cs.size()); if((csize>max_capacity())||(cnum>max_capacity())) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type rs=csize+cnum; if(rs>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(rs+(rs>>2)); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=rs; std::memcpy(_data_buf(hptr),cs.begin(),csize); std::memset(_data_buf(hptr)+csize,ch,cnum); _data_buf(hptr)[rs]=EOS; return(hptr);};// note: buffer capacity is larger than enough by 1/4//Wy__HStr* Wy__HStr::alloc(const WyCSeg& cs1, size_type cnum, value_type ch,const WyCSeg& cs2) WY__TSPC(Reply){ const size_type csize1(cs1.size()); const size_type csize2(cs2.size()); if((csize1>max_capacity())||(cnum>max_capacity())||(csize2>max_capacity())) { WY_THROW( Reply(Wym_EFBIG) ); } size_type rs=csize1+cnum; if(rs>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } rs+=csize2; if(rs>max_capacity()) { WY_THROW( Reply(Wym_EFBIG) ); } const size_type tsize=_memsize(rs+(rs>>2)); Wy__HStr* hptr=reinterpret_cast<Wy__HStr*>( _i_alloc(tsize) ); if(hptr==NULL) { WY_THROW( Reply(Wym_ENOMEM) ); } hptr->_m_dcap=_capmem(tsize); hptr->_m_dlen=rs; std::memcpy(_data_buf(hptr),cs1.begin(),csize1); std::memset(_data_buf(hptr)+csize1,ch,cnum); std::memcpy(_data_buf(hptr)+csize1+cnum,cs2.begin(),csize2); _data_buf(hptr)[rs]=EOS; return(hptr);};WyRet Wy__HStr::set_string(const Wy__HStr& hstr) WY__TSPC(){ const size_type hsize(hstr._m_dlen); value_type* des_ptr(_data_buf(this)); if(hstr.cseg().is_overlap( WyCSeg(des_ptr,hsize+sizeof(value_type)) )) { // note: overlap is reported after EFBIG WY_RETURN(Wym_ELOOP); } if(hsize<8) { const WyCSeg::value_type* src_ptr(_data_buf(&hstr)); WY__FCOPY(des_ptr,src_ptr,hsize); _m_dlen=hsize; *des_ptr=EOS; } else { std::memcpy(des_ptr,_data_buf(&hstr),hsize); _m_dlen=hsize; des_ptr[_m_dlen]=EOS; } return(Ok);};WyRet Wy__HStr::set_string(const WyCSeg& cs) WY__TSPC(){ const size_type csize(cs.size()); if(csize<6) { value_type* des_ptr(_data_buf(this)); if(cs.is_overlap( WyCSeg(des_ptr,csize+sizeof(value_type)) )) { // note: overlap is reported after EFBIG WY_RETURN(Wym_ELOOP); } const WyCSeg::value_type* src_ptr(cs.begin()); WY__FCOPY(des_ptr,src_ptr,csize); _m_dlen=csize; *des_ptr=EOS; } else { if(csize>_capacity()) { WY_RETURN( Wym_EFBIG ); } value_type* des_ptr(_data_buf(this)); if(cs.is_overlap( WyCSeg(des_ptr,csize+sizeof(value_type)) )) { // note: overlap is reported after EFBIG WY_RETURN(Wym_ELOOP); } std::memcpy(des_ptr,cs.begin(),csize); _m_dlen=csize; des_ptr[_m_dlen]=EOS; } return(Ok);};WyRet Wy__HStr::set_string(size_type cnum,value_type ch) WY__TSPC(){ if(cnum>_capacity()) { WY_RETURN( Wym_EFBIG ); } value_type* des_ptr(_data_buf(this)); std::memset(des_ptr,ch,cnum); _m_dlen=cnum; des_ptr[cnum]=EOS; return(Ok);};WyRet Wy__HStr::append(const Wy__HStr& hstr) WY__TSPC(){ const size_type hsize(hstr._m_dlen); if(hsize<8) { const size_type rs(_m_dlen+hsize); if(rs>_capacity()) { WY_RETURN(Wym_EFBIG); // overflow or size too long } value_type* des_ptr(_data_buf(this)+_m_dlen); if(hstr.cseg().is_overlap( WyCSeg(des_ptr,_m_dcap-_m_dlen+sizeof(value_type))) ) { // note: overlap is reported after EFBIG WY_RETURN(Wym_ELOOP); } const WyCSeg::value_type* src_ptr(_data_buf(&hstr)); WY__FCOPY(des_ptr,src_ptr,hsize); *des_ptr=EOS; _m_dlen=rs; } else { if(hsize>_capacity()) { WY_RETURN(Wym_EFBIG); } const size_type rs(_m_dlen+hsize); if(rs>_capacity()) { WY_RETURN(Wym_EFBIG); } value_type* des_ptr(_data_buf(this)+_m_dlen); if(hstr.cseg().is_overlap( WyCSeg(des_ptr,_m_dcap-_m_dlen+sizeof(value_type))) ) { // note: overlap is reported after EFBIG WY_RETURN(Wym_ELOOP); } std::memcpy(des_ptr,_data_buf(&hstr),hsize); //_data_buf(this)[rs]=EOS; des_ptr[hsize]=EOS; _m_dlen=rs; } return(Ok);};WyRet Wy__HStr::append(const WyCSeg& cs) WY__TSPC(){ const size_type csize(cs.size()); if(csize<8) { const size_type rs(_m_dlen+csize); if(rs>_capacity()) { WY_RETURN(Wym_EFBIG); // overflow or size too long } value_type* des_ptr(_data_buf(this)+_m_dlen); if(cs.is_overlap( WyCSeg(des_ptr,_m_dcap-_m_dlen+sizeof(value_type)))) { // note: overlap is reported after EFBIG WY_RETURN(Wym_ELOOP); } const WyCSeg::value_type* src_ptr(cs.begin()); WY__FCOPY(des_ptr,src_ptr,csize); *des_ptr=EOS; _m_dlen=rs; } else { if(csize>_capacity()) { WY_RETURN(Wym_EFBIG); } const size_type rs(_m_dlen+csize); if(rs>_capacity()) { WY_RETURN(Wym_EFBIG); } value_type* des_ptr(_data_buf(this)+_m_dlen); if(cs.is_overlap( WyCSeg(des_ptr,_m_dcap-_m_dlen+sizeof(value_type)))) { // note: overlap is reported after EFBIG WY_RETURN(Wym_ELOOP); } std::memcpy(des_ptr,cs.begin(),csize); _m_dlen=rs; //_data_buf(this)[rs]=EOS; des_ptr[csize]=EOS; } return(Ok);};WyRet Wy__HStr::append(size_type cnum,value_type ch) WY__TSPC(){ if(cnum>_capacity()) { WY_RETURN(Wym_EFBIG); } const size_type rs=_m_dlen+cnum; if(rs>_capacity()) { WY_RETURN(Wym_EFBIG); // overflow or size too long } value_type* des_ptr(_data_buf(this)+_m_dlen); std::memset(des_ptr,ch,cnum); _m_dlen=rs; des_ptr[cnum]=EOS; return(Ok);};WyRet Wy__HStr::append(value_type ch) WY__TSPC(){ if(_m_dlen>=_capacity()) { WY_RETURN( Wym_EFBIG ); } value_type* const cp(_data_buf(this)+(_m_dlen++)); cp[0]=ch; cp[1]=EOS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -