Marine Library  1.0
C++ library for Linux Networking Development
data_stream.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_DATA_STREAM_H_20070905
26 #define DOZERG_DATA_STREAM_H_20070905
27 
28 #include <cassert>
29 #include <cstring> //memcpy
30 #include <vector>
31 #include "impl/data_stream_impl.hh"
32 
33 NS_SERVER_BEGIN
34 
35 //TODO:
36 //ds<<x<<y<<Manip::offset_value(off, in.size())
37 
41 namespace Manip{
42 
206  template<class T, size_t N>
207  inline NS_IMPL::CManipulatorRawPtr<T> raw(T (&c)[N]){
208  return NS_IMPL::CManipulatorRawPtr<T>(c, N);
209  }
210 
211  template<class T>
212  inline NS_IMPL::CManipulatorRawPtr<T> raw(T * c, size_t sz){
213  return NS_IMPL::CManipulatorRawPtr<T>(c, sz);
214  }
215 
216  template<class T>
217  inline NS_IMPL::CManipulatorRawPtr<T> raw(std::vector<T> & c, size_t sz){
218  const size_t old = c.size();
219  c.resize(old + sz);
220  return NS_IMPL::CManipulatorRawPtr<T>(&c[old], sz);
221  }
222 
223  template<class T>
224  inline NS_IMPL::CManipulatorRawPtr<const T> raw(const std::vector<T> & c, size_t * sz = NULL){
225  if(sz)
226  *sz = c.size();
227  return NS_IMPL::CManipulatorRawPtr<const T>(&c[0], c.size());
228  }
229 
230  template<typename Char>
231  inline NS_IMPL::CManipulatorRawPtr<Char> raw(std::basic_string<Char> & c, size_t len){
232  const size_t old = c.size();
233  c.append(len, 0);
234  return NS_IMPL::CManipulatorRawPtr<Char>(&c[old], len);
235  }
236 
237  template<typename Char>
238  inline NS_IMPL::CManipulatorRawPtr<const Char> raw(const std::basic_string<Char> & c, size_t * sz = NULL){
239  if(sz)
240  *sz = c.size();
241  return NS_IMPL::CManipulatorRawPtr<const Char>(c.c_str(), c.size());
242  }
243 
244  template<class ForwardIter>
245  inline NS_IMPL::CManipulatorRawRange<ForwardIter> raw(ForwardIter first, ForwardIter last, size_t * sz = NULL){
246  return NS_IMPL::CManipulatorRawRange<ForwardIter>(first, last, sz);
247  }
248 
249  template<class T>
250  inline NS_IMPL::CManipulatorRawCont<T> raw(T & c, size_t sz){
251  return NS_IMPL::CManipulatorRawCont<T>(c, sz, NULL);
252  }
253 
254  template<class T>
255  inline NS_IMPL::CManipulatorRawCont<const T> raw(const T & c, size_t * sz = NULL){
256  return NS_IMPL::CManipulatorRawCont<const T>(c, 0, sz);
257  }
493  template<typename LenT, class T, size_t N>
494  inline NS_IMPL::CManipulatorArrayPtr<LenT, T> array(T (&c)[N], LenT * real_sz){
495  return NS_IMPL::CManipulatorArrayPtr<LenT, T>(c, N, real_sz);
496  }
497 
498  template<typename LenT, class T, size_t N>
499  inline NS_IMPL::CManipulatorArrayPtr<LenT, const T> array(const T (&c)[N]){
500  return NS_IMPL::CManipulatorArrayPtr<LenT, const T>(c, N, NULL);
501  }
502 
503  template<typename LenT, class T>
504  inline NS_IMPL::CManipulatorArrayPtr<LenT, T> array(T * c, size_t sz, LenT * real_sz){
505  return NS_IMPL::CManipulatorArrayPtr<LenT, T>(c, sz, real_sz);
506  }
507 
508  template<typename LenT, class T>
509  inline NS_IMPL::CManipulatorArrayPtr<LenT, const T> array(const T * c, size_t sz){
510  return NS_IMPL::CManipulatorArrayPtr<LenT, const T>(c, sz, NULL);
511  }
512 
513  template<typename LenT, class T>
514  inline NS_IMPL::CManipulatorArrayCont<LenT, T> array(T & c, LenT max_size = 0){
515  return NS_IMPL::CManipulatorArrayCont<LenT, T>(c, max_size);
516  }
517 
518  template<typename LenT, class T>
519  inline NS_IMPL::CManipulatorArrayCont<LenT, const T> array(const T & c){
520  return NS_IMPL::CManipulatorArrayCont<LenT, const T>(c, 0);
521  }
522 
523  template<class T>
524  inline NS_IMPL::CManipulatorArrayCont<uint16_t, T> array(T & c, uint16_t max_size = 0){
525  return NS_IMPL::CManipulatorArrayCont<uint16_t, T>(c, max_size);
526  }
527 
528  template<class T>
529  inline NS_IMPL::CManipulatorArrayCont<uint16_t, const T> array(const T & c){
530  return NS_IMPL::CManipulatorArrayCont<uint16_t, const T>(c, 0);
531  }
532 
533  template<typename LenT, class ForwardIter>
534  inline NS_IMPL::CManipulatorArrayRange<LenT, ForwardIter> array(ForwardIter first, ForwardIter last, LenT * sz = NULL){
535  return NS_IMPL::CManipulatorArrayRange<LenT, ForwardIter>(first, last, sz);
536  }
594  inline void net_order(NS_IMPL::CDataStreamBase & ds){ds.netByteOrder(true);}
595 
596  inline void host_order(NS_IMPL::CDataStreamBase & ds){ds.netByteOrder(false);}
597 
598  inline void little_endian(NS_IMPL::CDataStreamBase & ds){ds.littleEndian(true);}
599 
600  inline void big_endian(NS_IMPL::CDataStreamBase & ds){ds.littleEndian(false);}
601 
602  template<class T>
603  inline NS_IMPL::CManipulatorValueByteOrder<T> net_order_value(T & val){
604  return NS_IMPL::CManipulatorValueByteOrder<T>(val, net_order);
605  }
606 
607  template<class T>
608  inline NS_IMPL::CManipulatorValueByteOrder<const T> net_order_value(const T & val){
609  return NS_IMPL::CManipulatorValueByteOrder<const T>(val, net_order);
610  }
611 
612  template<class T>
613  inline NS_IMPL::CManipulatorValueByteOrder<T> host_order_value(T & val){
614  return NS_IMPL::CManipulatorValueByteOrder<T>(val, host_order);
615  }
616 
617  template<class T>
618  inline NS_IMPL::CManipulatorValueByteOrder<const T> host_order_value(const T & val){
619  return NS_IMPL::CManipulatorValueByteOrder<const T>(val, host_order);
620  }
621 
622  template<class T>
623  inline NS_IMPL::CManipulatorValueByteOrder<T> little_endian_value(T & val){
624  return NS_IMPL::CManipulatorValueByteOrder<T>(val, little_endian);
625  }
626 
627  template<class T>
628  inline NS_IMPL::CManipulatorValueByteOrder<const T> little_endian_value(const T & val){
629  return NS_IMPL::CManipulatorValueByteOrder<const T>(val, little_endian);
630  }
631 
632  template<class T>
633  inline NS_IMPL::CManipulatorValueByteOrder<T> big_endian_value(T & val){
634  return NS_IMPL::CManipulatorValueByteOrder<T>(val, big_endian);
635  }
636 
637  template<class T>
638  inline NS_IMPL::CManipulatorValueByteOrder<const T> big_endian_value(const T & val){
639  return NS_IMPL::CManipulatorValueByteOrder<const T>(val, big_endian);
640  }
709  inline NS_IMPL::CManipulatorSeek seek(size_t pos){return NS_IMPL::CManipulatorSeek(pos);}
710 
711  inline NS_IMPL::CManipulatorSkip skip(ssize_t off){return NS_IMPL::CManipulatorSkip(off);}
712 
713  inline NS_IMPL::CManipulatorSkipFill skip(ssize_t off, int fill){return NS_IMPL::CManipulatorSkipFill(off, fill);}
714 
715  template<typename T>
716  inline NS_IMPL::CManipulatorSkipPtr<T> skip(T * off){return NS_IMPL::CManipulatorSkipPtr<T>(off);}
717 
718  template<typename T>
719  inline NS_IMPL::CManipulatorSkipPtrFill<T> skip(T * off, int fill){return NS_IMPL::CManipulatorSkipPtrFill<T>(off);}
720 
721  template<class T>
722  inline NS_IMPL::CManipulatorOffsetValue<T> offset_value(size_t pos, T & val){
723  return NS_IMPL::CManipulatorOffsetValue<T>(pos, val);
724  }
725 
726  template<class T>
727  inline NS_IMPL::CManipulatorOffsetValue<const T> offset_value(size_t pos, const T & val){
728  return NS_IMPL::CManipulatorOffsetValue<const T>(pos, val);
729  }
730 
731  template<class T>
732  inline NS_IMPL::CManipulatorInsert<T> insert(size_t pos, const T & val){
733  return NS_IMPL::CManipulatorInsert<T>(pos, val);
734  }
772  template<class T>
773  inline NS_IMPL::CManipulatorProtobuf<T> protobuf(T & msg, size_t size = size_t(-1)){
774  return NS_IMPL::CManipulatorProtobuf<T>(msg, size);
775  }
776 
792  template<typename T>
793  inline NS_IMPL::CManipulatorVarint<const T> varint(const T & val){
794  return NS_IMPL::CManipulatorVarint<const T>(val);
795  }
796 
810  template<typename T>
811  inline NS_IMPL::CManipulatorVarint<T> varint(T & val){
812  return NS_IMPL::CManipulatorVarint<T>(val);
813  }
814 
845  inline NS_IMPL::CManipulatorStubPush stub(size_t sz){
846  return NS_IMPL::CManipulatorStubPush(sz);
847  }
848 
884  inline NS_IMPL::CManipulatorStubPop stub_pop(bool align = false, bool check = false){
885  return NS_IMPL::CManipulatorStubPop(align, check);
886  }
887 
929  inline NS_IMPL::CManipulatorEnd<void, void> end(){
930  return NS_IMPL::CManipulatorEnd<void, void>();
931  }
932 
951  template<typename SizeT>
952  inline NS_IMPL::CManipulatorEnd<SizeT *, void> end(SizeT * sz){
953  return NS_IMPL::CManipulatorEnd<SizeT *, void>(sz);
954  }
955 
978  template<class BufT>
979  inline NS_IMPL::CManipulatorEnd<BufT, void> end(BufT & buf){
980  return NS_IMPL::CManipulatorEnd<BufT, void>(buf);
981  }
982 
1003  template<typename CharT>
1004  inline NS_IMPL::CManipulatorEnd<CharT *, size_t *> end(CharT * buf, size_t * sz){
1005  return NS_IMPL::CManipulatorEnd<CharT *, size_t *>(buf, sz);
1006  }
1009 }//namespace Manip
1010 
1033 class CInByteStream : public NS_IMPL::CDataStreamBase
1034 {
1035  typedef NS_IMPL::CDataStreamBase __MyBase;
1036  typedef CInByteStream __Myt;
1037  const char * data_;
1038  size_t len_;
1039  size_t cur_;
1040 public:
1047  : __MyBase(kByteOrderDefault, 1)
1048  , data_(NULL)
1049  , len_(0)
1050  , cur_(0)
1051  {}
1060  CInByteStream(const char * buf, size_t sz, bool net = kByteOrderDefault){
1061  setSource(buf, sz, net);
1062  }
1071  CInByteStream(const unsigned char * buf, size_t sz, bool net = kByteOrderDefault){
1072  setSource(buf, sz, net);
1073  }
1082  CInByteStream(const signed char * buf, size_t sz, bool net = kByteOrderDefault){
1083  setSource(buf, sz, net);
1084  }
1092  CInByteStream(const std::string & buf, bool net = kByteOrderDefault){
1093  setSource(buf, net);
1094  }
1104  void setSource(const char * buf, size_t sz, bool net = kByteOrderDefault){
1105  data_ = buf;
1106  len_ = sz;
1107  cur_ = 0;
1108  netByteOrder(net);
1109  status(0);
1110  }
1120  void setSource(const unsigned char * buf, size_t sz, bool net = kByteOrderDefault){
1121  setSource(reinterpret_cast<const char *>(buf), sz, net);
1122  }
1132  void setSource(const signed char * buf, size_t sz, bool net = kByteOrderDefault){
1133  setSource(reinterpret_cast<const char *>(buf), sz, net);
1134  }
1142  void setSource(const std::string & buf, bool net = kByteOrderDefault){
1143  setSource(buf.c_str(), buf.size(), net);
1144  }
1153  __Myt & bad(int code){
1154  status(code);
1155  return *this;
1156  }
1166  ssize_t seek(size_t pos){
1167  if(!checkStub(pos))
1168  return -1;
1169  if(pos > len_){
1170  status(1);
1171  return -1;
1172  }
1173  return (cur_ = pos);
1174  }
1184  ssize_t skip(ssize_t off){return seek(cur() + off);}
1191  size_t cur() const{return cur_;}
1199  const char * data() const{return (data_ + cur());}
1206  size_t left() const{return (getStub(len_) - cur());}
1211  std::string toString() const{
1212  CToString oss;
1213  oss<<"{CDataStreamBase="<<__MyBase::toString()
1214  <<", cur_="<<cur_
1215  <<", data_="<<NS_IMPL::dumpBufPart(data_, len_, cur_)
1216  <<"}";
1217  return oss.str();
1218  }
1227  __Myt & operator >>(char & c) {return readPod(c);}
1228  __Myt & operator >>(signed char & c) {return readPod(c);}
1229  __Myt & operator >>(unsigned char & c) {return readPod(c);}
1230  __Myt & operator >>(short & c) {return readPod(c);}
1231  __Myt & operator >>(unsigned short & c) {return readPod(c);}
1232  __Myt & operator >>(int & c) {return readPod(c);}
1233  __Myt & operator >>(unsigned int & c) {return readPod(c);}
1234  __Myt & operator >>(long & c) {return readPod(c);}
1235  __Myt & operator >>(unsigned long & c) {return readPod(c);}
1236  __Myt & operator >>(long long & c) {return readPod(c);}
1237  __Myt & operator >>(unsigned long long & c) {return readPod(c);}
1238  __Myt & operator >>(wchar_t & c) {return readPod(c);}
1250  __Myt & operator >>(std::string & c){return (*this>>Manip::array(c));}
1258  __Myt & operator >>(std::wstring & c){return (*this>>Manip::array(c));}
1269  template<class T, size_t N>
1270  __Myt & operator >>(T (&c)[N]){return readRaw(c, N);}
1280  __Myt & operator >>(void (*m)(__MyBase &)){
1281  if(m)
1282  m(*this);
1283  return *this;
1284  }
1285  template<class T>
1286  __Myt & operator >>(const NS_IMPL::CManipulatorRawPtr<T> & m){
1287  return readRaw(m.c_, m.sz_);
1288  }
1289  template<class T>
1290  __Myt & operator >>(const NS_IMPL::CManipulatorRawCont<T> & m){
1291  typedef typename T::value_type __Val;
1292  for(size_t i = 0;good() && i < m.sz_;++i){
1293  __Val v;
1294  if(*this>>v)
1295  m.c_.insert(m.c_.end(), v);
1296  }
1297  return *this;
1298  }
1299  template<class ForwardIter>
1300  __Myt & operator >>(const NS_IMPL::CManipulatorRawRange<ForwardIter> & m){
1301  size_t sz = 0;
1302  for(ForwardIter i = m.beg_;good() && i != m.end_;++i, ++sz)
1303  *this>>*i;
1304  if(m.sz_)
1305  *m.sz_ = sz;
1306  return *this;
1307  }
1308  template<typename LenT, class T>
1309  __Myt & operator >>(const NS_IMPL::CManipulatorArrayPtr<LenT, T> & m){
1310  LenT sz;
1311  if(*this>>sz){
1312  if(size_t(sz) > m.sz1_)
1313  return bad(1);
1314  if((*this>>Manip::raw(m.c_, sz)) && m.sz2_)
1315  *m.sz2_ = sz;
1316  }
1317  return *this;
1318  }
1319  template<typename LenT, class T>
1320  __Myt & operator >>(const NS_IMPL::CManipulatorArrayCont<LenT, T> & m){
1321  __UNUSED typedef typename T::value_type __Val; //make sure T is a Container
1322  LenT sz(0);
1323  if(*this>>sz){
1324  if(m.max_ && sz > m.max_)
1325  return bad(1);
1326  *this>>Manip::raw(m.c_, sz);
1327  }
1328  return *this;
1329  }
1330  template<class T>
1331  __Myt & operator >>(const NS_IMPL::CManipulatorValueByteOrder<T> & m){
1332  const bool old = littleEndian();
1333  *this>>m.fun_>>m.c_;
1334  littleEndian(old);
1335  return *this;
1336  }
1337  __Myt & operator >>(const NS_IMPL::CManipulatorSeek & m){
1338  seek(m.pos_);
1339  return *this;
1340  }
1341  __Myt & operator >>(const NS_IMPL::CManipulatorSkip & m){
1342  skip(m.off_);
1343  return *this;
1344  }
1345  template<typename T>
1346  __Myt & operator >>(const NS_IMPL::CManipulatorSkipPtr<T> & m){
1347  if(m.off_)
1348  skip(*m.off_);
1349  return *this;
1350  }
1351  template<class T>
1352  __Myt & operator >>(const NS_IMPL::CManipulatorOffsetValue<T> & m){
1353  const size_t old = cur();
1354  if(seek(m.pos_) >= 0 && (*this>>m.c_))
1355  seek(old);
1356  return *this;
1357  }
1358  template<class T>
1359  __Myt & operator >>(const NS_IMPL::CManipulatorProtobuf<T> & m){
1360  size_t sz = left();
1361  if(sz > m.sz_)
1362  sz = m.sz_;
1363  if(!m.c_.ParseFromArray(data(), sz))
1364  return bad(1);
1365  skip(sz);
1366  return *this;
1367  }
1368  template<typename T>
1369  __Myt & operator >>(const NS_IMPL::CManipulatorVarint<T> & m){
1370  typename NS_IMPL::CManipulatorVarint<T>::__Unsigned v = 0;
1371  if(readVarint(v))
1372  m.fromUnsigned(v);
1373  return *this;
1374  }
1375  __Myt & operator >>(const NS_IMPL::CManipulatorStubPush & m){
1376  pushStub(m.sz_ + cur());
1377  return *this;
1378  }
1379  __Myt & operator >>(const NS_IMPL::CManipulatorStubPop & m){
1380  size_t pos;
1381  if(popStub(&pos)){
1382  if(m.check_ && cur() != pos)
1383  return bad(1);
1384  seek(m.align_ ? pos : cur());
1385  }
1386  return *this;
1387  }
1388  template<class T, class S>
1389  __Myt & operator >>(const NS_IMPL::CManipulatorEnd<T, S> & m){
1390  if(clearStub() && left())
1391  status(1);
1392  return *this;
1393  }
1394  __Myt & operator >>(NS_IMPL::CManipulatorEnd<void, void> (*m)()){
1395  if(!m)
1396  return bad(1);
1397  return (*this>>m());
1398  }
1400 private:
1401  CInByteStream(const char * buf); //maybe you miss 'sz'. Disable implicit cast to std::string
1402  template<typename T>
1403  __Myt & readPod(T & c){
1404  if(ensure(sizeof(T))){
1405  memcpy(&c, data(), sizeof(T));
1406  if(sizeof(T) > 1 && needReverse())
1407  c = tools::SwapByteOrder(c);
1408  cur_ += sizeof(T);
1409  }
1410  return *this;
1411  }
1412  __Myt & readVarint(unsigned char & c){
1413  if(ensure(1)){
1414  c = data_[cur_++];
1415  if(c < (1 << 7))
1416  return *this;
1417  if(ensure(1))
1418  c |= data_[cur_++] << 7;
1419  }
1420  return *this;
1421  }
1422  template<typename T>
1423  __Myt & readVarint(T & c){
1424  if(ensure(1)){
1425  c = data_[cur_++];
1426  if(c < (1 << 7))
1427  return *this;
1428  if(ensure(1)){
1429  c = (c & ((1 << 7) - 1)) | (data_[cur_++] << 7);
1430  if(c < (1 << 14))
1431  return *this;
1432  c &= (1 << 14) - 1;
1433  for(uint8_t v = -1, s = 14;v > 0x7F && readPod(v);s += 7)
1434  c |= T(v & 0x7F) << s;
1435  }
1436  }
1437  return *this;
1438  }
1439  template<typename T>
1440  __Myt & readRaw(T * c, size_t sz){
1441  if(!sz)
1442  return *this;
1443  if(!c)
1444  return bad(1);
1446  || (sizeof(T) > 1 && needReverse())){
1447  for(size_t i = 0;good() && i < sz;++i, ++c)
1448  *this>>*c;
1449  }else{
1450  sz *= sizeof(T);
1451  if(ensure(sz)){
1452  memcpy(c, data(), sz);
1453  cur_ += sz;
1454  }
1455  }
1456  return *this;
1457  }
1458  bool ensure(size_t sz){
1459  if(checkStub(cur() + sz)){
1460  if(left() >= sz)
1461  return true;
1462  status(1);
1463  }
1464  return false;
1465  }
1466 };
1467 
1526 template<class Data>
1527 class COutByteStreamBasic : public NS_IMPL::CDataStreamBase
1528 {
1529  typedef NS_IMPL::CDataStreamBase __MyBase;
1530  typedef COutByteStreamBasic<Data> __Myt;
1531  typedef Data __Data;
1532 public:
1533  typedef typename Data::__Buf buffer_type;
1534  typedef typename Data::__Char char_type;
1542  explicit COutByteStreamBasic(size_t reserve = 1024, bool net = kByteOrderDefault)
1543  : __MyBase(net)
1544  , data_(reserve)
1545  {}
1553  explicit COutByteStreamBasic(buffer_type & buf, bool net = kByteOrderDefault)
1554  : __MyBase(net)
1555  , data_(buf)
1556  {}
1565  COutByteStreamBasic(char_type * buf, size_t sz, bool net = kByteOrderDefault)
1566  : __MyBase(net)
1567  , data_(buf, sz)
1568  {}
1577  __Myt & bad(int code){
1578  status(code);
1579  return *this;
1580  }
1590  ssize_t seek(size_t pos){
1591  if(!checkStub(pos))
1592  return -1;
1593  if(data_.seek(pos))
1594  return cur();
1595  status(1);
1596  return -1;
1597  }
1605  size_t cur() const{return data_.cur();}
1611  size_t size() const{return cur();}
1622  ssize_t skip(ssize_t off){
1623  if(!checkStub(cur() + off))
1624  return -1;
1625  if(off < 0 && size_t(-off) > cur()){
1626  bad(1);
1627  return -1;
1628  }
1629  return seek(cur() + off);
1630  }
1641  ssize_t skip(ssize_t off, int fill){
1642  const size_t old = cur();
1643  const ssize_t ret = skip(off);
1644  if(ret < 0)
1645  return ret;
1646  if(old < size_t(ret))
1647  std::fill(data_.data(old), data_.data(ret), fill);
1648  return ret;
1649  }
1654  std::string toString() const{
1655  CToString oss;
1656  oss<<"{CDataStreamBase="<<__MyBase::toString()
1657  <<", data_="<<data_.toString()
1658  <<"}";
1659  return oss.str();
1660  }
1669  __Myt & operator <<(char c) {return writePod(c);}
1670  __Myt & operator <<(signed char c) {return writePod(c);}
1671  __Myt & operator <<(unsigned char c) {return writePod(c);}
1672  __Myt & operator <<(short c) {return writePod(c);}
1673  __Myt & operator <<(unsigned short c) {return writePod(c);}
1674  __Myt & operator <<(int c) {return writePod(c);}
1675  __Myt & operator <<(unsigned int c) {return writePod(c);}
1676  __Myt & operator <<(long c) {return writePod(c);}
1677  __Myt & operator <<(unsigned long c) {return writePod(c);}
1678  __Myt & operator <<(long long c) {return writePod(c);}
1679  __Myt & operator <<(unsigned long long c) {return writePod(c);}
1680  __Myt & operator <<(wchar_t c) {return writePod(c);}
1692  __Myt & operator <<(const std::string & c){return (*this<<Manip::array(c));}
1700  __Myt & operator <<(const std::wstring & c){return (*this<<Manip::array(c));}
1711  template<class T, size_t N>
1712  __Myt & operator <<(const T (&c)[N]){return writeRaw(c, N);}
1722  template<class T>
1723  __Myt & operator <<(const NS_IMPL::CManipulatorRawPtr<T> & m){
1724  return writeRaw(m.c_, m.sz_);
1725  }
1726  template<class T>
1727  __Myt & operator <<(const NS_IMPL::CManipulatorRawCont<T> & m){
1728  const size_t sz = writeRange(m.c_.begin(), m.c_.end());
1729  if(m.sz2_)
1730  *m.sz2_ = sz;
1731  return *this;
1732  }
1733  template<class ForwardIter>
1734  __Myt & operator <<(const NS_IMPL::CManipulatorRawRange<ForwardIter> & m){
1735  const size_t sz = writeRange(m.beg_, m.end_);
1736  if(m.sz_)
1737  *m.sz_ = sz;
1738  return *this;
1739  }
1740  template<typename LenT, class T>
1741  __Myt & operator <<(const NS_IMPL::CManipulatorArrayPtr<LenT, T> & m){
1742  if(*this<<LenT(m.sz1_))
1743  writeRaw(m.c_, m.sz1_);
1744  return *this;
1745  }
1746  template<typename LenT, class T>
1747  __Myt & operator <<(const NS_IMPL::CManipulatorArrayCont<LenT, T> & m){
1748  const size_t off = cur();
1749  //NOTE: m.c_.size() may be O(N) complexity, e.g. std::list
1750  if((*this<<LenT(0)) && !m.c_.empty()){
1751  size_t sz = 0;
1752  if((*this<<Manip::raw(m.c_, &sz)))
1753  *this<<Manip::offset_value(off, LenT(sz));
1754  }
1755  return *this;
1756  }
1757  template<typename LenT, class ForwardIter>
1758  __Myt & operator <<(const NS_IMPL::CManipulatorArrayRange<LenT, ForwardIter> & m){
1759  const size_t off = cur();
1760  size_t sz = 0;
1761  if((*this<<LenT(0)<<Manip::raw(m.beg_, m.end_, &sz))){
1762  *this<<Manip::offset_value(off, LenT(sz));
1763  if(m.sz_)
1764  *m.sz_ = sz;
1765  }
1766  return *this;
1767  }
1768  __Myt & operator <<(void (*m)(__MyBase &)){
1769  if(m)
1770  m(*this);
1771  return *this;
1772  }
1773  template<class T>
1774  __Myt & operator <<(const NS_IMPL::CManipulatorValueByteOrder<T> & m){
1775  const bool old = littleEndian();
1776  *this<<m.fun_<<m.c_;
1777  littleEndian(old);
1778  return *this;
1779  }
1780  __Myt & operator <<(const NS_IMPL::CManipulatorSeek & m){
1781  seek(m.pos_);
1782  return *this;
1783  }
1784  __Myt & operator <<(const NS_IMPL::CManipulatorSkip & m){
1785  skip(m.off_);
1786  return *this;
1787  }
1788  __Myt & operator <<(const NS_IMPL::CManipulatorSkipFill & m){
1789  skip(m.off_, m.fill_);
1790  return *this;
1791  }
1792  template<typename T>
1793  __Myt & operator <<(const NS_IMPL::CManipulatorSkipPtr<T> & m){
1794  if(m.off_)
1795  skip(*m.off_);
1796  return *this;
1797  }
1798  template<typename T>
1799  __Myt & operator <<(const NS_IMPL::CManipulatorSkipPtrFill<T> & m){
1800  if(m.off_)
1801  skip(*m.off_, m.fill_);
1802  return *this;
1803  }
1804  template<class T>
1805  __Myt & operator <<(const NS_IMPL::CManipulatorOffsetValue<T> & m){
1806  const size_t old = cur();
1807  if(seek(m.pos_) >= 0 && (*this<<m.c_))
1808  seek(old);
1809  return *this;
1810  }
1811  template<class T>
1812  __Myt & operator <<(const NS_IMPL::CManipulatorInsert<T> & m){
1814  const size_t old = cur();
1815  if(old <= m.pos_){
1816  if(old == m.pos_ || seek(m.pos_) >= 0)
1817  *this<<m.c_;
1818  }else{
1819  std::string buf;
1820  __OutStream ds(buf);
1821  if(!(ds<<m.c_) || !ds.finish())
1822  return bad(1);
1823  if(!buf.empty() && ensure(buf.size()))
1824  data_.insert(m.pos_, cast(buf.c_str()), buf.size());
1825  }
1826  return *this;
1827  }
1828  template<class T>
1829  __Myt & operator <<(const NS_IMPL::CManipulatorProtobuf<T> & m){
1830  const size_t old = size();
1831  const size_t sz = m.c_.ByteSize();
1832  if(skip(sz) >= 0 && !m.c_.SerializeToArray(data_.data(old), sz)){
1833  seek(old);
1834  status(1);
1835  }
1836  return *this;
1837  }
1838  template<typename T>
1839  __Myt & operator <<(const NS_IMPL::CManipulatorVarint<T> & m){
1840  return writeVarint(m.toUnsigned());
1841  }
1842  __Myt & operator <<(const NS_IMPL::CManipulatorStubPush & m){
1843  pushStub(m.sz_ + cur());
1844  return *this;
1845  }
1846  __Myt & operator <<(const NS_IMPL::CManipulatorStubPop & m){
1847  size_t pos;
1848  if(popStub(&pos)){
1849  if(m.check_ && cur() != pos)
1850  return bad(1);
1851  seek(m.align_ ? pos : cur());
1852  }
1853  return *this;
1854  }
1855  __Myt & operator <<(const NS_IMPL::CManipulatorEnd<void, void> & m){
1856  finish();
1857  return *this;
1858  }
1859  __Myt & operator <<(NS_IMPL::CManipulatorEnd<void, void> (*m)()){
1860  if(!m)
1861  return bad(1);
1862  return (*this<<m());
1863  }
1864  template<typename SizeT>
1865  __Myt & operator <<(const NS_IMPL::CManipulatorEnd<SizeT *, void> & m){
1866  finish(m.sz_);
1867  return *this;
1868  }
1869  __Myt & operator <<(const NS_IMPL::CManipulatorEnd<buffer_type, void> & m){
1870  finish(m.buf_);
1871  return *this;
1872  }
1873  template<typename CharT>
1874  __Myt & operator <<(const NS_IMPL::CManipulatorEnd<CharT *, size_t *> & m){
1875  finish(m.buf_, m.sz_);
1876  return *this;
1877  }
1887  bool finish(){
1888  if(good() && !data_.exportData())
1889  status(1);
1890  return clearStub();
1891  }
1903  template<typename SizeT>
1904  bool finish(SizeT * sz){
1905  if(good() && !data_.exportData(sz))
1906  status(1);
1907  return clearStub();
1908  }
1919  bool finish(buffer_type & dst){
1920  if(good() && !data_.exportData(dst))
1921  status(1);
1922  return clearStub();
1923  }
1935  template<typename CharT>
1936  bool finish(CharT * dst, size_t * sz){
1937  if(good() && !data_.exportData(dst, sz))
1938  status(1);
1939  return clearStub();
1940  }
1941 private:
1942  __Myt & operator <<(bool); //prevent from abusing
1943  template<typename T>
1944  static const char_type * cast(const T * c){
1945  return reinterpret_cast<const char_type *>(c);
1946  }
1947  template<typename T>
1948  __Myt & writePod(T c){
1949  if(ensure(sizeof(T))){
1950  if(sizeof(T) > 1 && needReverse())
1951  c = tools::SwapByteOrder(c);
1952  data_.append(cast(&c), sizeof(T));
1953  }
1954  return *this;
1955  }
1956  __Myt & writeVarint(unsigned char c){
1957  if(c < 0x80){
1958  if(ensure(1))
1959  data_.append(c);
1960  }else if(ensure(2)){
1961  data_.append(c | 0x80);
1962  data_.append(c >> 7);
1963  }
1964  return *this;
1965  }
1966  __Myt & writeVarint(unsigned short c){
1967  if(c < 0x80){
1968  if(ensure(1))
1969  data_.append(c);
1970  }else if(c < (1 << 14)){
1971  if(ensure(2)){
1972  data_.append(c | 0x80);
1973  data_.append(c >> 7);
1974  }
1975  }else if(ensure(3)){
1976  data_.append(c | 0x80);
1977  data_.append((c >> 7) | 0x80);
1978  data_.append(c >> 14);
1979  }
1980  return *this;
1981  }
1982  template<typename T>
1983  __Myt & writeVarint(T c){
1984  if(c < 0x80){
1985  if(ensure(1))
1986  data_.append(c);
1987  }else if(c < (1 << 14)){
1988  if(ensure(2)){
1989  data_.append(c | 0x80);
1990  data_.append(c >> 7);
1991  }
1992  }else if(c < (1 << 21)){
1993  if(ensure(3)){
1994  data_.append(c | 0x80);
1995  data_.append((c >> 7) | 0x80);
1996  data_.append(c >> 14);
1997  }
1998  }else if(c < (1 << 28)){
1999  if(ensure(4)){
2000  data_.append(c | 0x80);
2001  data_.append((c >> 7) | 0x80);
2002  data_.append((c >> 14) | 0x80);
2003  data_.append(c >> 21);
2004  }
2005  }else if(ensure(5)){
2006  data_.append(c | 0x80);
2007  data_.append((c >> 7) | 0x80);
2008  data_.append((c >> 14) | 0x80);
2009  data_.append((c >> 21) | 0x80);
2010  c >>= 28;
2011  do{
2012  if(c < 0x80){
2013  data_.append(c);
2014  break;
2015  }else
2016  data_.append(c | 0x80);
2017  c >>= 7;
2018  }while(ensure(1));
2019  }
2020  return *this;
2021  }
2022  template<typename T>
2023  __Myt & writeRaw(const T * c, size_t sz){
2024  if(!sz)
2025  return *this;
2026  if(!c)
2027  return bad(1);
2029  || (sizeof(T) > 1 && needReverse())){
2030  for(size_t i = 0;good() && i < sz;++i,++c)
2031  *this<<*c;
2032  }else{
2033  sz *= sizeof(T);
2034  if(ensure(sz))
2035  data_.append(cast(c), sz);
2036  }
2037  return *this;
2038  }
2039  template<class ForwardIter>
2040  size_t writeRange(ForwardIter first, ForwardIter last){
2041  size_t c = 0;
2042  for(ForwardIter i = first;good() && i != last;++i, ++c)
2043  *this<<*i;
2044  return c;
2045  }
2046  bool ensure(size_t len){
2047  if(!checkStub(cur() + len))
2048  return false;
2049  if(data_.ensure(len))
2050  return true;
2051  status(1);
2052  return false;
2053  }
2054  //members
2055  __Data data_;
2056 };
2057 
2060 
2062 typedef COutByteStreamStr COutByteStream;
2063 
2066 
2069 
2072 
2075 
2076 NS_SERVER_END
2077 
2078 #endif
2079 
COutByteStreamBasic< NS_IMPL::__buf_data< std::string > > COutByteStreamStr
Use internal std::string as the underlying data buffer.
Definition: data_stream.hh:2059
ssize_t skip(ssize_t off, int fill)
Skip some bytes.
Definition: data_stream.hh:1641
NS_IMPL::CManipulatorStubPop stub_pop(bool align=false, bool check=false)
Demolish the top most stub.
Definition: data_stream.hh:884
CInByteStream(const char *buf, size_t sz, bool net=kByteOrderDefault)
Construct from a byte buffer.
Definition: data_stream.hh:1060
Definition: to_string.hh:43
size_t size() const
Get byte size of data have been written, same as cur.
Definition: data_stream.hh:1611
__Myt & bad(int code)
Set status.
Definition: data_stream.hh:1577
COutByteStreamBasic(size_t reserve=1024, bool net=kByteOrderDefault)
Constructor for COutByteStream/COutByteStreamStr, COutByteStreamVec.
Definition: data_stream.hh:1542
ssize_t seek(size_t pos)
Set current pointer.
Definition: data_stream.hh:1166
ssize_t skip(ssize_t off)
Skip some data.
Definition: data_stream.hh:1184
COutByteStreamBasic< NS_IMPL::__buf_data< CCharBuffer< char > > > COutByteStreamBuf
Use external char array as the underlying data buffer.
Definition: data_stream.hh:2074
bool finish(CharT *dst, size_t *sz)
Export data for COutByteStream/COutByteStreamStr, COutByteStreamStrRef, COutByteStreamVec, COutByteStreamVecRef, COutByteStreamBuf.
Definition: data_stream.hh:1936
std::string toString() const
Get a readable description of this object.
Definition: data_stream.hh:1654
Definition: template.hh:23
COutByteStreamBasic< NS_IMPL::__buf_data< std::vector< char > > > COutByteStreamVec
Use internal std::vector<char> as the underlying data buffer.
Definition: data_stream.hh:2068
NS_IMPL::CManipulatorProtobuf< T > protobuf(T &msg, size_t size=size_t(-1))
Pack/unpack Protocol Buffers messages.
Definition: data_stream.hh:773
COutByteStreamStr COutByteStream
Same as COutByteStreamStr.
Definition: data_stream.hh:2062
Manipulators for stream interface APIs.
Definition: data_stream.hh:41
void setSource(const signed char *buf, size_t sz, bool net=kByteOrderDefault)
Initialize with a byte buffer.
Definition: data_stream.hh:1132
bool finish(SizeT *sz)
Export data for COutByteStreamBuf, COutByteStreamStrRef, COutByteStreamVecRef.
Definition: data_stream.hh:1904
Data unpacking interfaces.
Definition: data_stream.hh:1033
bool finish()
Export data for COutByteStreamStrRef, COutByteStreamVecRef.
Definition: data_stream.hh:1887
void setSource(const char *buf, size_t sz, bool net=kByteOrderDefault)
Initialize with a byte buffer.
Definition: data_stream.hh:1104
COutByteStreamBasic< NS_IMPL::__buf_ref_data< std::string > > COutByteStreamStrRef
Use external std::string as the underlying data buffer.
Definition: data_stream.hh:2065
void setSource(const unsigned char *buf, size_t sz, bool net=kByteOrderDefault)
Initialize with a byte buffer.
Definition: data_stream.hh:1120
CInByteStream(const std::string &buf, bool net=kByteOrderDefault)
Construct from a byte buffer.
Definition: data_stream.hh:1092
void setSource(const std::string &buf, bool net=kByteOrderDefault)
Initialize with a byte buffer.
Definition: data_stream.hh:1142
const char * data() const
Get a pointer to left data.
Definition: data_stream.hh:1199
size_t cur() const
Get current pointer.
Definition: data_stream.hh:1191
std::string toString() const
Get a readable description of this object.
Definition: data_stream.hh:1211
NS_IMPL::CManipulatorStubPush stub(size_t sz)
Set up a stub.
Definition: data_stream.hh:845
CInByteStream(const signed char *buf, size_t sz, bool net=kByteOrderDefault)
Construct from a byte buffer.
Definition: data_stream.hh:1082
Implementation of CInByteStream, COutByteStreamBasic.
bool finish(buffer_type &dst)
Export data for COutByteStream/COutByteStreamStr, COutByteStreamStrRef, COutByteStreamVec, COutByteStreamVecRef.
Definition: data_stream.hh:1919
NS_IMPL::CManipulatorVarint< const T > varint(const T &val)
Pack integer using Base 128 Varints encoding.
Definition: data_stream.hh:793
COutByteStreamBasic(char_type *buf, size_t sz, bool net=kByteOrderDefault)
Constructor for COutByteStreamBuf.
Definition: data_stream.hh:1565
COutByteStreamBasic(buffer_type &buf, bool net=kByteOrderDefault)
Constructor for COutByteStreamStrRef, COutByteStreamVecRef.
Definition: data_stream.hh:1553
ssize_t seek(size_t pos)
Set current pointer.
Definition: data_stream.hh:1590
NS_IMPL::CManipulatorEnd< void, void > end()
End operations for CInByteStream, COutByteStreamStrRef, COutByteStreamVecRef.
Definition: data_stream.hh:929
size_t left() const
Get byte size of left data.
Definition: data_stream.hh:1206
COutByteStreamBasic< NS_IMPL::__buf_ref_data< std::vector< char > > > COutByteStreamVecRef
Use external std::vector<char> as the underlying data buffer.
Definition: data_stream.hh:2071
Data packing interfaces.
Definition: data_stream.hh:1527
__Myt & bad(int code)
Set status.
Definition: data_stream.hh:1153
CInByteStream()
Construct an empty object.
Definition: data_stream.hh:1046
size_t cur() const
Get current pointer.
Definition: data_stream.hh:1605
CInByteStream(const unsigned char *buf, size_t sz, bool net=kByteOrderDefault)
Construct from a byte buffer.
Definition: data_stream.hh:1071
ssize_t skip(ssize_t off)
Skip some bytes.
Definition: data_stream.hh:1622