#ifndef __higinet_zistream_h__ #define __higinet_zistream_h__ #include #include #include #include #include struct stream_exception: public std::logic_error { explicit stream_exception(const char*e) :std::logic_error(e) { } explicit stream_exception(const std::string&e) :std::logic_error(e) { } }; namespace endian { struct flag { #ifndef LITTLE_ENDIAN static const bool little=true; #else static const bool little=false; #endif }; inline void cp_uint8_r(void*d,const void*s,size_t c) { uint8_t*di=(uint8_t*)d; const uint8_t*si=(const uint8_t*)s; while(c-->0) *di++=*--si; } inline void cp_uint8(void*d,const void*s,size_t c) { memcpy(d,s,c); } template struct copy_impl { void operator()(void*d,const void*s,size_t)const { } }; template<> struct copy_impl { void operator()(void*d,const void*s,size_t count)const { cp_uint8 ((uint8_t*)d,(const uint8_t*)s,count); } }; template<> struct copy_impl { void operator()(void*d,const void*s,size_t count)const { cp_uint8_r (d, (const uint8_t*)s+count, count); } }; inline void copy(void*d,const void*s,size_t count) { copy_impl()(d,s,count); } } struct skip { int m_count; skip(int count):m_count(count){} }; template struct as { T t; F&f; as(F&f_):f(f_){} }; struct npc { int m_count; npc(int c=-1):m_count(c) {} void reset(int count=-1){m_count=count;} operator int()const {return m_count;} }; struct zistream { private: const uint8_t* m_buff; size_t m_pos,m_size; bool m_owner_buff; npc m_np; void assert_buff_size(size_t len) { if(len > m_size) { char buf[256]; sprintf(buf, "无更多的数据:%s(size=%d,pos=%d,fetch=%d).", __FUNCTION__,(int)m_size,(int)m_pos,(int)len); throw stream_exception(buf); } } public: const uint8_t*buff()const{return m_buff;} const uint8_t*cur_data()const{return m_buff+m_pos;} size_t pos()const{return m_pos;} void load(void*d,size_t len,size_t pos) { assert_buff_size(pos+len); endian::copy(d,m_buff+pos,len); } void load(void*d,size_t len) { load(d,len,m_pos); m_pos+=len; } int32_t load_int8 (size_t pos){int8_t rc;load(&rc,sizeof(rc),pos);return rc;} int32_t load_int16(size_t pos){int16_t rc;load(&rc,sizeof(rc),pos);return rc;} int32_t load_int32(size_t pos){int32_t rc;load(&rc,sizeof(rc),pos);return rc;} int64_t load_int64(size_t pos){int64_t rc;load(&rc,sizeof(rc),pos);return rc;} int32_t load_int8 (){int8_t rc; load(&rc,sizeof(rc)); return rc;} int32_t load_int16(){int16_t rc; load(&rc,sizeof(rc)); return rc;} int32_t load_int32(){int32_t rc; load(&rc,sizeof(rc)); return rc;} int64_t load_int64(){int64_t rc; load(&rc,sizeof(rc)); return rc;} uint32_t load_uint8 (size_t pos){uint8_t rc;load(&rc,sizeof(rc),pos);return rc;} uint32_t load_uint16(size_t pos){uint16_t rc;load(&rc,sizeof(rc),pos);return rc;} uint32_t load_uint32(size_t pos){uint32_t rc;load(&rc,sizeof(rc),pos);return rc;} uint64_t load_uint64(size_t pos){uint64_t rc;load(&rc,sizeof(rc),pos);return rc;} uint32_t load_uint8 (){uint8_t rc; load(&rc,sizeof(rc)); return rc;} uint32_t load_uint16(){uint16_t rc; load(&rc,sizeof(rc)); return rc;} uint32_t load_uint32(){uint32_t rc; load(&rc,sizeof(rc)); return rc;} uint64_t load_uint64(){uint64_t rc; load(&rc,sizeof(rc)); return rc;} std::vector load_bytes(size_t count) { std::vector rc(count,0); load(&*rc.begin(), count); return std::move(rc); } std::string load_string(size_t count) { std::string rc(count,' '); load(&*rc.begin(), count); return std::move(rc); } bool eof() const {return m_pos >= m_size; } size_t size()const {return m_size;} void set_size(uint32_t size){m_size=size;} public: zistream(const void*pbuf,size_t buf_size,bool owner_buff=false) :m_buff((const uint8_t*)pbuf) ,m_pos(0) ,m_size(buf_size) ,m_owner_buff(owner_buff) { } ~zistream() { if(m_owner_buff && m_buff) { ::free((void*)m_buff); } } friend zistream& operator>>(zistream&is, uint8_t &i) { i=is.load_uint8 ();return is; } friend zistream& operator>>(zistream&is, uint16_t&i) { i=is.load_uint16();return is; } friend zistream& operator>>(zistream&is, uint32_t&i) { i=is.load_uint32();return is; } friend zistream& operator>>(zistream&is, uint64_t&i) { i=is.load_uint64();return is; } friend zistream& operator>>(zistream&is, int8_t &i) { i=is.load_int8 ();return is; } friend zistream& operator>>(zistream&is, int16_t&i) { i=is.load_int16();return is; } friend zistream& operator>>(zistream&is, int32_t&i) { i=is.load_int32();return is; } friend zistream& operator>>(zistream&is, int64_t&i) { i=is.load_int64();return is; } friend zistream& operator>>(zistream&is, const npc&i) { is.m_np.reset(i);return is;} friend zistream& operator>>(zistream&is, void*x) { if(is.m_np <= 0) return is; is.load(x,is.m_np); is.m_np.reset(); return is; } friend zistream& operator>>(zistream&is, const skip&s) { is.assert_buff_size(s.m_count); is.m_pos+=s.m_count; return is; } }; class zostream { private: uint8_t* m_buff; size_t m_pos,m_size; int m_owner_buff; void grow(size_t nsize) { if(m_buff!=nullptr && nsizem_pos) m_pos=len+pos; return *this; } zostream& save(const void*pbuf,int len) { grow(len+m_pos); endian::copy(m_buff+m_pos,pbuf,len); m_pos+=len; return *this; } zostream& save(int8_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(int16_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(int32_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(int64_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(int8_t i) {return save(&i,sizeof(i));} zostream& save(int16_t i) {return save(&i,sizeof(i));} zostream& save(int32_t i) {return save(&i,sizeof(i));} zostream& save(int64_t i) {return save(&i,sizeof(i));} zostream& save(uint8_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(uint16_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(uint32_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(uint64_t i,size_t pos){return save(&i,sizeof(i),pos);} zostream& save(uint8_t i) {return save(&i,sizeof(i));} zostream& save(uint16_t i) {return save(&i,sizeof(i));} zostream& save(uint32_t i) {return save(&i,sizeof(i));} zostream& save(uint64_t i) {return save(&i,sizeof(i));} zostream& save(const std::string&s) { return save(s.c_str(), s.size()); } zostream& save(const char*s) { return save(s, strlen(s)); } friend zostream& operator<<(zostream&os, uint8_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, uint16_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, uint32_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, uint64_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, int8_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, int16_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, int32_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, int64_t i) { return os.save(i);} friend zostream& operator<<(zostream&os, const std::string &i) { return os.save(i);} friend zostream& operator<<(zostream&os, const char*i) { return os.save(i);} public: zostream(size_t buf_size,void*buf=nullptr) :m_buff((uint8_t*)buf) ,m_pos(0) ,m_size(buf_size) { if(m_buff) { m_owner_buff=0; } } ~zostream() { if(m_owner_buff && m_buff) free(m_buff); } const uint8_t*data()const{return m_buff;}const uint8_t *data(){return m_buff;} size_t size()const {return m_pos;} }; #endif