Marine Library  1.0
C++ library for Linux Networking Development
char_buffer.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Zhao DAI <daidodo@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or any
7  * later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see accompanying file LICENSE.txt
16  * or <http://www.gnu.org/licenses/>.
17  */
18 
25 #ifndef DOZERG_CHAR_BUFFER_H_20121218
26 #define DOZERG_CHAR_BUFFER_H_20121218
27 
28 #include <cassert>
29 #include <algorithm>
30 #include <stdexcept>
31 #include <cstddef>
32 #include <iterator>
33 #include <memory>
34 #include <cstring>
35 #include "impl/environment.hh"
36 
37 NS_SERVER_BEGIN
38 
48 template<typename CharT>
50 {
51  typedef CCharBuffer<CharT> __Myt;
52  typedef CharT __Char;
53 public:
54  typedef std::char_traits<__Char> traits_type;
55  typedef typename traits_type::char_type value_type;
56  typedef value_type & reference;
57  typedef const value_type & const_reference;
58  typedef value_type * pointer;
59  typedef const value_type * const_pointer;
60  typedef __gnu_cxx::__normal_iterator<
61  pointer, CCharBuffer> iterator;
62  typedef __gnu_cxx::__normal_iterator<
63  const_pointer, CCharBuffer> const_iterator;
64  typedef size_t size_type;
65  typedef ptrdiff_t difference_type;
66  typedef std::reverse_iterator<iterator> reverse_iterator;
67  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
68  static const size_type npos = static_cast<size_type>(-1);
69  //functions
74  : buf_(NULL)
75  , capa_(0)
76  , sz_(0)
77  {}
83  CCharBuffer(pointer buf)
84  : buf_(buf)
85  , capa_(traits_type::length(buf))
86  , sz_(capa_)
87  {}
96  CCharBuffer(pointer buf, size_type capacity, size_type size = 0)
97  : buf_(buf)
98  , capa_(capacity)
99  , sz_(std::min(size, capacity))
100  {}
110  __Myt & assign(pointer buf, size_type capacity, size_type size = 0){
111  buf_ = buf;
112  capa_ = capacity;
113  sz_ = std::min(size, capacity);
114  return *this;
115  }
124  __Myt & assign(const __Myt & other){
125  if(this != &other)
126  assign(other.buf_, other.capa_, other.sz_);
127  return *this;
128  }
133  void swap(__Myt & other) throw() {
134  if(this != &other){
135  std::swap(buf_, other.buf_);
136  std::swap(capa_, other.capa_);
137  std::swap(sz_, other.sz_);
138  }
139  }
147  iterator begin(){return iterator(&buf_[0]);}
153  iterator end(){return iterator(&buf_[sz_]);}
158  const_iterator begin() const{return const_iterator(&buf_[0]);}
164  const_iterator end() const{return const_iterator(&buf_[sz_]);}
169  reverse_iterator rbegin(){return reverse_iterator(end());}
174  reverse_iterator rend(){return reverse_iterator(begin());}
179  const_reverse_iterator rbegin() const{return const_reverse_iterator(end());}
184  const_reverse_iterator rend() const{return const_reverse_iterator(begin());}
193  bool empty() const{return !sz_;}
199  size_type length() const{return size();}
205  size_type size() const{return sz_;}
210  size_type capacity() const{return capa_;}
215  size_type max_size() const{return size_type(-1);}
225  reference operator [](size_type i){return buf_[i];}
231  const_reference operator [](size_type i) const{return buf_[i];}
236  reference front(){return operator [](0);}
241  const_reference front() const{return operator [](0);}
246  reference back(){return operator [](sz_ - 1);}
251  const_reference back() const{return operator [](sz_ - 1);}
258  reference at(size_type i){
259  assert(buf_);
260  check_offset_throw(i);
261  return buf_[i];
262  }
269  const_reference at(size_type i) const{
270  assert(buf_);
271  check_offset_throw(i);
272  return buf_[i];
273  }
279  const_pointer c_str() const{return buf_;}
285  const_pointer data() const{return buf_;}
297  void clear(){sz_ = 0;}
305  void resize(size_type count, value_type val = 0){
306  check_capa_throw(count);
307  if(count > sz_){
308  assert(buf_);
309  assign_aux(buf_ + sz_, count - sz_, val);
310  }
311  sz_ = count;
312  }
325  size_type copy(pointer buf, size_type count, size_type offset = 0) const{
326  check_size_throw(offset);
327  if(offset + count > sz_)
328  count = sz_ - offset;
329  if(count){
330  assert(buf_ && buf);
331  copy_aux(buf, buf_ + offset, count);
332  }
333  return count;
334  }
339  void push_back(value_type val){
340  assert(buf_);
341  check_capa_throw(sz_ + 1);
342  buf_[sz_++] = val;
343  }
350  __Myt & append(size_type count, value_type val){return replace(sz_, 0, count, val);}
357  __Myt & append(const_pointer buf, size_type count){return replace(sz_, 0, buf, count);}
363  __Myt & append(const_pointer buf){return replace(sz_, 0, buf);}
373  __Myt & append(const __Myt & other, size_type offset, size_type count){return replace(sz_, 0, other, offset, count);}
379  __Myt & append(const __Myt & other){return replace(sz_, 0, other);}
386  __Myt & operator +=(const __Myt & other){return append(other);}
394  __Myt & operator +=(const_pointer buf){return append(buf);}
401  __Myt & operator +=(value_type val){
402  push_back(val);
403  return *this;
404  }
412  __Myt & insert(size_type offset, size_type count, value_type val){return replace(offset, 0, count, val);}
420  __Myt & insert(size_type offset, const_pointer buf, size_type count){return replace(offset, 0, buf, count);}
428  __Myt & insert(size_type offset, const_pointer buf){return insert(offset, buf, traits_type::length(buf));}
439  __Myt & insert(size_type offset, const __Myt & other, size_type newOffset, size_type count){
440  return replace(offset, 0, other, newOffset, count);
441  }
448  __Myt & insert(size_type offset, const __Myt & other){return insert(offset, other, 0, other.size());}
455  iterator insert(iterator pos, value_type val){
456  replace(pos, pos, size_type(1), val);
457  return pos;
458  }
472  __Myt & replace(size_type offset, size_type count, size_type newCount, value_type val){
473  check_size_range_throw(offset, count);
474  check_capa_throw(offset + newCount);
475  check_capa_throw(sz_ + newCount - count);
476  mutate_aux(offset, count, newCount);
477  if(newCount){
478  assert(buf_);
479  assign_aux(buf_ + offset, newCount, val);
480  }
481  return *this;
482  }
496  __Myt & replace(size_type offset, size_type count, const_pointer buf, size_type newCount){
497  check_size_range_throw(offset, count);
498  check_capa_throw(offset + newCount);
499  check_capa_throw(sz_ + newCount - count);
500  mutate_aux(offset, count, newCount);
501  if(newCount){
502  assert(buf_ && buf);
503  copy_aux(buf_ + offset, buf, newCount);
504  }
505  return *this;
506  }
520  __Myt & replace(size_type offset, size_type count, const_pointer buf){
521  return replace(offset, count, buf, traits_type::length(buf));
522  }
537  __Myt & replace(size_type offset, size_type count, const __Myt & other, size_type newOffset, size_type newCount){
538  other.check_size_throw(newOffset);
539  other.check_size_throw(newOffset + newCount);
540  return replace(offset, count, other.buf_ + newOffset, newCount);
541  }
554  __Myt & replace(size_type offset, size_type count, const __Myt & other){
555  return replace(offset, count, other, size_type(0), other.size());
556  }
570  __Myt & replace(iterator first, iterator last, size_type count, value_type val){
571  check_iter_range_throw(first, last);
572  return replace(size_type(first - begin()), size_type(last - first), count, val);
573  }
587  __Myt & replace(iterator first, iterator last, const_pointer buf, size_type count){
588  check_iter_range_throw(first, last);
589  return replace(size_type(first - begin()), size_type(last - first), buf, count);
590  }
604  __Myt & replace(iterator first, iterator last, const_pointer buf){
605  return replace(first, last, buf, size_type(traits_type::length(buf)));
606  }
621  __Myt & replace(iterator first, iterator last, const __Myt & other, size_type offset, size_type count){
622  check_iter_range_throw(first, last);
623  return replace(size_type(first - begin()), size_type(last - first), other, offset, count);
624  }
637  __Myt & replace(iterator first, iterator last, const __Myt & other){
638  return replace(first, last, other, 0, other.size());
639  }
646  iterator erase(iterator first, iterator last){
647  replace(first, last, size_type(0), value_type(0));
648  return first;
649  }
655  iterator erase(iterator pos){
656  replace(pos, pos + 1, size_type(0), value_type(0));
657  return pos;
658  }
665  __Myt & erase(size_type offset = 0, size_type count = npos){
666  check_offset_throw(offset);
667  if(offset + count > sz_)
668  count = sz_ - offset;
669  mutate_aux(offset, limit_count(offset, count), 0);
670  return *this;
671  }
682  __Myt substr(size_type offset = 0, size_type count = npos){
683  check_offset_throw(offset);
684  return __Myt(buf_ + offset, capa_ - offset, limit_count(offset, count));
685  }
699  int compare(size_type offset, size_type count, const_pointer buf, size_type newCount) const{
700  check_size_range_throw(offset, count);
701  size_type c = std::min(count, newCount);
702  int ret = 0;
703  if(c){
704  assert(buf_ && buf);
705  ret = traits_type::compare(buf_ + offset, buf, c);
706  }
707  if(!ret)
708  ret = (count < newCount ? -1 : (count > newCount ? 1 : 0));
709  return ret;
710  }
723  int compare(size_type offset, size_type count, const_pointer buf) const{
724  return compare(offset, count, buf, traits_type::length(buf));
725  }
736  int compare(const_pointer buf) const{return compare(size_type(0), size(), buf);}
752  int compare(size_type offset, size_type count, const __Myt & other, size_type newOffset, size_type newCount) const{
753  other.check_size_range_throw(newOffset, newCount);
754  return compare(offset, count, const_pointer(other.buf_ + newOffset), newCount);
755  }
768  int compare(size_type offset, size_type count, const __Myt & other) const{
769  return compare(offset, count, other, 0, other.size());
770  }
781  int compare(const __Myt & other) const{return compare(size_type(0), size(), other);}
783  //TODO: find xxx, rfind
784 private:
785  void check_offset_throw(size_type i) const{
786  if(i >= sz_)
787  throw std::out_of_range("CCharBuffer offset out of range");
788  }
789  void check_size_throw(size_type i) const{
790  if(i > sz_)
791  throw std::out_of_range("CCharBuffer size out of range");
792  }
793  void check_capa_throw(size_type i) const{
794  if(i > capa_)
795  throw std::out_of_range("CCharBuffer capacity out of range");
796  }
797  void check_iter_throw(iterator it) const{
798  if(it < begin() || it > end())
799  throw std::out_of_range("CCharBuffer iterator out of range");
800  }
801  void check_size_range_throw(size_type offset, size_type count) const{
802  check_size_throw(offset);
803  if(count)
804  check_size_throw(offset + count);
805  }
806  void check_iter_range_throw(iterator first, iterator last) const{
807  assert(first <= last);
808  check_iter_throw(first);
809  if(last != first)
810  check_iter_throw(last);
811  }
812  static void assign_aux(pointer pos, size_type count, value_type val){
813  assert(pos);
814  if(1 == count)
815  traits_type::assign(*pos, val);
816  else
817  traits_type::assign(pos, count, val);
818  }
819  static void copy_aux(pointer dst, const_pointer src, size_type count){
820  assert(dst && src);
821  if(1 == count)
822  traits_type::assign(*dst, *src);
823  else
824  traits_type::copy(dst, src, count);
825  }
826  static void move_aux(pointer dst, const_pointer src, size_type count){
827  assert(dst && src);
828  if(1 == count)
829  traits_type::assign(*dst, *src);
830  else
831  traits_type::move(dst, src, count);
832  }
833  void mutate_aux(size_type offset, size_type count, size_type newCount){
834  assert(sz_ >= offset + count);
835  const size_type c = sz_ - offset - count;
836  if(c && count != newCount)
837  move_aux(buf_ + offset + newCount, buf_ + offset + count, c);
838  sz_ += newCount - count;
839  }
840  size_type limit_count(size_type offset, size_type count) const{
841  const size_type c = sz_ - offset;
842  return std::min(c, count);
843  }
844  //members
845  __Char * buf_;
846  size_t capa_;
847  size_t sz_;
848 };
849 
854 //no operator +
855 template<typename CharT>
856 bool operator ==(const CCharBuffer<CharT> & left, const CCharBuffer<CharT> & right)
857 {
858  return (left.size() == right.size() && 0 == left.compare(right));
859 }
860 
861 template<typename CharT>
862 bool operator ==(const CharT * left, const CCharBuffer<CharT> & right)
863 {
864  return (0 == right.compare(left));
865 }
866 
867 template<typename CharT>
868 bool operator ==(const CCharBuffer<CharT> & left, const CharT * right)
869 {
870  return (0 == left.compare(right));
871 }
872 
873 template<typename CharT>
874 bool operator !=(const CCharBuffer<CharT> & left, const CCharBuffer<CharT> & right)
875 {
876  return !(left == right);
877 }
878 
879 template<typename CharT>
880 bool operator !=(const CharT * left, const CCharBuffer<CharT> & right)
881 {
882  return !(left == right);
883 }
884 
885 template<typename CharT>
886 bool operator !=(const CCharBuffer<CharT> & left, const CharT * right)
887 {
888  return !(left == right);
889 }
890 
891 template<typename CharT>
892 bool operator <(const CCharBuffer<CharT> & left, const CCharBuffer<CharT> & right)
893 {
894  return (left.compare(right) < 0);
895 }
896 
897 template<typename CharT>
898 bool operator <(const CharT * left, const CCharBuffer<CharT> & right)
899 {
900  return (0 < right.compare(left));
901 }
902 
903 template<typename CharT>
904 bool operator <(const CCharBuffer<CharT> & left, const CharT * right)
905 {
906  return (left.compare(right) < 0);
907 }
908 
909 template<typename CharT>
910 bool operator <=(const CCharBuffer<CharT> & left, const CCharBuffer<CharT> & right)
911 {
912  return !(left > right);
913 }
914 
915 template<typename CharT>
916 bool operator <=(const CharT * left, const CCharBuffer<CharT> & right)
917 {
918  return !(left > right);
919 }
920 
921 template<typename CharT>
922 bool operator <=(const CCharBuffer<CharT> & left, const CharT * right)
923 {
924  return !(left > right);
925 }
926 
927 template<typename CharT>
928 bool operator >(const CCharBuffer<CharT> & left, const CCharBuffer<CharT> & right)
929 {
930  return (right < left);
931 }
932 
933 template<typename CharT>
934 bool operator >(const CharT * left, const CCharBuffer<CharT> & right)
935 {
936  return (right < left);
937 }
938 
939 template<typename CharT>
940 bool operator >(const CCharBuffer<CharT> & left, const CharT * right)
941 {
942  return (right < left);
943 }
944 
945 template<typename CharT>
946 bool operator >=(const CCharBuffer<CharT> & left, const CCharBuffer<CharT> & right)
947 {
948  return !(left < right);
949 }
950 
951 template<typename CharT>
952 bool operator >=(const CharT * left, const CCharBuffer<CharT> & right)
953 {
954  return !(left < right);
955 }
956 
957 template<typename CharT>
958 bool operator >=(const CCharBuffer<CharT> & left, const CharT * right)
959 {
960  return !(left < right);
961 }
962 
965 template<typename CharT>
966 void swap(const CCharBuffer<CharT> & left, const CCharBuffer<CharT> & right)
967 {
968  left.swap(right);
969 }
970 
971 NS_SERVER_END
972 
973 #endif
974 
CCharBuffer()
Construct a null object with zero capacity.
Definition: char_buffer.hh:73
iterator end()
Get the ending of the data.
Definition: char_buffer.hh:153
__Myt & insert(size_type offset, const_pointer buf, size_type count)
Insert the content of a buffer.
Definition: char_buffer.hh:420
bool empty() const
Test if the data is empty.
Definition: char_buffer.hh:193
__Myt substr(size_type offset=0, size_type count=npos)
Get a substring.
Definition: char_buffer.hh:682
__Myt & append(const_pointer buf, size_type count)
Append content of a buffer to the end of the data.
Definition: char_buffer.hh:357
const_reverse_iterator rbegin() const
Get the ending of the data.
Definition: char_buffer.hh:179
__Myt & replace(size_type offset, size_type count, const_pointer buf)
Replace a range of bytes with the content of a C-style string.
Definition: char_buffer.hh:520
void resize(size_type count, value_type val=0)
Resize the data.
Definition: char_buffer.hh:305
size_type copy(pointer buf, size_type count, size_type offset=0) const
Copy content of a buffer to self.
Definition: char_buffer.hh:325
size_type length() const
Get the size of the data, same as size().
Definition: char_buffer.hh:199
int compare(size_type offset, size_type count, const __Myt &other) const
Compare a range of bytes with another CCharBuffer object.
Definition: char_buffer.hh:768
__Myt & insert(size_type offset, const __Myt &other)
Insert the content of another CCharBuffer.
Definition: char_buffer.hh:448
__Myt & erase(size_type offset=0, size_type count=npos)
Erase a range of bytes.
Definition: char_buffer.hh:665
__Myt & append(const __Myt &other)
Append content of another CCharBuffer content to the end of the data.
Definition: char_buffer.hh:379
reference operator[](size_type i)
Access a byte.
Definition: char_buffer.hh:225
Provide interfaces similar to std::string for raw byte array.
Definition: char_buffer.hh:49
STL namespace.
int compare(const_pointer buf) const
Compare self with a C-style string lexicographically.
Definition: char_buffer.hh:736
__Myt & replace(iterator first, iterator last, size_type count, value_type val)
Replace a range of bytes with a number of new bytes.
Definition: char_buffer.hh:570
iterator erase(iterator first, iterator last)
Erase a range of bytes.
Definition: char_buffer.hh:646
const_reference back() const
Access the last byte.
Definition: char_buffer.hh:251
__Myt & assign(pointer buf, size_type capacity, size_type size=0)
Set this object to manage a byte buffer.
Definition: char_buffer.hh:110
__Myt & append(size_type count, value_type val)
Append a number of bytes to the end of the data.
Definition: char_buffer.hh:350
const_pointer c_str() const
Get the underlying C-style string.
Definition: char_buffer.hh:279
size_type size() const
Get the size of the data.
Definition: char_buffer.hh:205
__Myt & insert(size_type offset, size_type count, value_type val)
Insert a number of bytes.
Definition: char_buffer.hh:412
const_iterator end() const
Get the ending of the data.
Definition: char_buffer.hh:164
__Myt & assign(const __Myt &other)
Set this object to manage a buffer from another object.
Definition: char_buffer.hh:124
const_iterator begin() const
Get the beginning of the data.
Definition: char_buffer.hh:158
const_reference at(size_type i) const
Access a certain byte.
Definition: char_buffer.hh:269
reverse_iterator rend()
Get the beginning of the data.
Definition: char_buffer.hh:174
size_type capacity() const
Get the capacity of the underlying byte buffer.
Definition: char_buffer.hh:210
__Myt & replace(iterator first, iterator last, const __Myt &other)
Replace a range of bytes with the content of another CCharBuffer.
Definition: char_buffer.hh:637
size_type max_size() const
Get the maximum number of bytes.
Definition: char_buffer.hh:215
__Myt & replace(size_type offset, size_type count, const_pointer buf, size_type newCount)
Replace a range of bytes with the content of a byte buffer.
Definition: char_buffer.hh:496
int compare(const __Myt &other) const
Compare self with another CCharBuffer object.
Definition: char_buffer.hh:781
__Myt & insert(size_type offset, const_pointer buf)
Insert a C-style string.
Definition: char_buffer.hh:428
iterator erase(iterator pos)
Erase a byte.
Definition: char_buffer.hh:655
__Myt & append(const __Myt &other, size_type offset, size_type count)
Append content of another CCharBuffer content to the end of the data.
Definition: char_buffer.hh:373
__Myt & replace(iterator first, iterator last, const_pointer buf, size_type count)
Replace a range of bytes with the content of a byte buffer.
Definition: char_buffer.hh:587
__Myt & replace(size_type offset, size_type count, const __Myt &other)
Replace a range of bytes with the content of another CCharBuffer.
Definition: char_buffer.hh:554
const_pointer data() const
Get the data pointer.
Definition: char_buffer.hh:285
reference back()
Access the last byte.
Definition: char_buffer.hh:246
void push_back(value_type val)
Append a byte to the end of the data.
Definition: char_buffer.hh:339
const_reference front() const
Access the first byte.
Definition: char_buffer.hh:241
__Myt & replace(size_type offset, size_type count, size_type newCount, value_type val)
Replace a range of bytes with a number of new bytes.
Definition: char_buffer.hh:472
int compare(size_type offset, size_type count, const_pointer buf, size_type newCount) const
Compare a range of bytes with a buffer lexicographically.
Definition: char_buffer.hh:699
void clear()
Empty the data.
Definition: char_buffer.hh:297
__Myt & replace(size_type offset, size_type count, const __Myt &other, size_type newOffset, size_type newCount)
Replace a range of bytes with the content of another CCharBuffer.
Definition: char_buffer.hh:537
reverse_iterator rbegin()
Get the ending of the data.
Definition: char_buffer.hh:169
reference at(size_type i)
Access a certain byte.
Definition: char_buffer.hh:258
CCharBuffer(pointer buf)
Construct from a C-style string.
Definition: char_buffer.hh:83
__Myt & replace(iterator first, iterator last, const_pointer buf)
Replace a range of bytes with the content of a C-style string.
Definition: char_buffer.hh:604
__Myt & operator+=(const __Myt &other)
Append content of another CCharBuffer to the end of the data.
Definition: char_buffer.hh:386
const_reverse_iterator rend() const
Get the beginning of the data.
Definition: char_buffer.hh:184
int compare(size_type offset, size_type count, const_pointer buf) const
Compare a range of bytes with a C-style string lexicographically.
Definition: char_buffer.hh:723
reference front()
Access the first byte.
Definition: char_buffer.hh:236
int compare(size_type offset, size_type count, const __Myt &other, size_type newOffset, size_type newCount) const
Compare a range of bytes with another CCharBuffer object.
Definition: char_buffer.hh:752
iterator begin()
Get the beginning of the data.
Definition: char_buffer.hh:147
iterator insert(iterator pos, value_type val)
Insert a byte.
Definition: char_buffer.hh:455
CCharBuffer(pointer buf, size_type capacity, size_type size=0)
Construct from a byte buffer.
Definition: char_buffer.hh:96
void swap(__Myt &other)
Swap two CCharBuffer objects.
Definition: char_buffer.hh:133
__Myt & insert(size_type offset, const __Myt &other, size_type newOffset, size_type count)
Insert the content of another CCharBuffer.
Definition: char_buffer.hh:439
__Myt & append(const_pointer buf)
Append a C-style string to the end of the data.
Definition: char_buffer.hh:363
__Myt & replace(iterator first, iterator last, const __Myt &other, size_type offset, size_type count)
Replace a range of bytes with the content of another CCharBuffer.
Definition: char_buffer.hh:621