#ifndef _in_buff_hpp_ #define _in_buff_hpp_ #include #include #include #include "clock.h" struct buff_t { private: char*ptr_; int len_; int owner_; public: buff_t(const buff_t&); buff_t() :ptr_(0) ,len_(0) ,owner_(0) { } buff_t(char*ptr,int len,bool owner=false) :ptr_(ptr) ,len_(len) ,owner_(owner?1:0) { } char*ptr()const { return ptr_; } bool empty()const { return len_==0; } int size()const { return len_; } int len()const { return len_; } void set(int len) { len_=len; } void reset(void*ptr,int len,bool owner) { if(owner_) ::free(ptr_); ptr_=(char*)ptr; len_=len; owner_=owner?1:0; } void clear() { reset(0,0,0); } ~buff_t() { if(owner_) { ::free(ptr_); } } }; struct buf_base { private: buf_base(const buf_base&); protected: char*m_base; int m_mask,m_size; int64_t m_ppos,m_gpos; public: buf_base(int size) { m_size=256; while(m_sizelen_data()) return -1; return (int)(uint8_t)m_base[pos(i+m_gpos)]; } uint8_t& operator[](int i) { return *(uint8_t*)&m_base[pos(i+m_gpos)]; } }; struct in_buff:buf_base { in_buff(int size) :buf_base(size) { } ~in_buff() { } buff_t alloc() { const int ppos=pos(m_ppos); const int gpos=pos(m_gpos); int len=gpos<=ppos ?size()-ppos :gpos-ppos; return len==0?buff_t(0,0):buff_t(m_base+ppos,len); } void commit(int len) { m_ppos+=len; } void free(int len) { m_gpos+=len; } buff_t peek() { const int ppos=pos(m_ppos); const int gpos=pos(m_gpos); return buff_t(m_base+gpos,gpos<=ppos?ppos-gpos:size()-gpos); } /* char*peek(char*buf,int len) { if(len>len_data()) return 0; buff_t b=peek(); if(b.len()>=len) return b.ptr(); memcpy(buf,b.ptr(),b.len()); memcpy(buf+b.len(),m_base,len-b.len()); return buf; } */ buff_t get(int len) { if(len>len_data()) return buff_t(0,0); buff_t b=peek(); if(b.len()>=len) { free(len); return b; } else { buff_t r ((char*)malloc(len),len,1); memcpy(r.ptr(),b.ptr(),b.len()); memcpy(r.ptr()+b.len(),m_base,len-b.len()); free(len); return r; } } buff_t get(const char*chim) { int len=find(chim); if(len==0) return buff_t(); return get(len); } char*get(char *buf,int len) { if(len>len_data()) return 0; buff_t b=peek(); if(b.len()>=len) { memcpy(buf,b.ptr(),len); } else { memcpy(buf,b.ptr(),b.len()); memcpy(buf+b.len(),m_base,len-b.len()); } free(len); return buf; } void skip(int len) { free(len); } int find(const char*chim)const { int slen=strlen(chim); for(int64_t p=m_gpos;ppos(p++)]!=chim[0]) continue; int j=1; for(;jsize()|| !ztomic::cas(&m_ppos,&ppos,ppos+len)) { if(c.count_ms()>=time_out_ms) return false; counter=yield(counter); continue; } int p=pos(ppos); int c=p+len-size(); if(c<=0) { memcpy(m_base+p,d,len); } else { memcpy(m_base+p,d,len-c); memcpy(m_base,d+len-c,c); } break; } return true; } void free(int len) { ztomic::fetch_add(&m_gpos,len); } char*peek(int*len) { const int p=pos(m_ppos); const int g=pos(m_gpos); *len=g<=p?p-g:size()-g; return m_base+g; } }; */ #endif