#pragma once #include #include #include #include #include #include #include #include #include #include "host_byte_order_check.h" #include "noncopyable.h" namespace utilib { class basic_stream_buffer : public noncopyable { public: basic_stream_buffer(char * p, const size_t maxLength) : p_(p), max_length_(maxLength), rd_size_(0), wr_size_(0) { if (p_ == 0) throw std::runtime_error("invalid memory pointer detected"); } ~basic_stream_buffer() { } const size_t capacity()const { return max_length_ - wr_size_; } const size_t size()const { return wr_size_ - rd_size_; } void resize(const size_t newSize) { if (size() >= newSize) wr_size_ = rd_size_ + newSize; else if (capacity() >= newSize - size()) wr_size_ = rd_size_ + newSize; else throw std::overflow_error("buffer capacity lack detected"); } void read(void * p, const size_t n) { if (!p) throw std::invalid_argument("invalid memory pointer detected"); if (size() < n) throw std::overflow_error("memory size lack detected"); ::memcpy(p, p_ + rd_size_, n); rd_size_ += n; } void rread(void * p, const size_t n) { if (!p) throw std::invalid_argument("invalid memory pointer detected"); if (size() < n) throw std::overflow_error("memory size lack detected"); std::reverse_copy(p_ + rd_size_, p_ + rd_size_ + n, (char *)p); rd_size_ += n; } void copy(const void * p, const size_t n) { if (!p) throw std::invalid_argument("invalid memory pointer detected"); if (capacity() < n) throw std::overflow_error("memory size lack detected"); ::memcpy(p_ + wr_size_, p, n); wr_size_ += n; } void rcopy(const void * p, const size_t n) { // reverse copy if (!p) throw std::invalid_argument("invalid memory pointer detected"); if (capacity() < n) throw std::overflow_error("memory size lack detected"); std::reverse_copy((char *)p, (char *)p + n, p_ + wr_size_); wr_size_ += n; } protected: char * p_; size_t max_length_; size_t rd_size_; size_t wr_size_; }; // class stream_buffer_base class basic_binary_istream : public noncopyable { public: template class array { public: array(T * p, const size_t maxSize) :p_(p), max_size_(maxSize), size_(0) { } const size_t size()const { return size_; } private: T * p_; const size_t max_size_; size_t size_; friend class basic_binary_istream; }; // class array basic_binary_istream(basic_stream_buffer & buf) : s_(buf) { } ~basic_binary_istream() { } basic_binary_istream & operator>> (bool & b) { char c = 0; this->operator >>(c); b = c == '0' ? false : true; return *this; } basic_binary_istream & operator>> (char & c) { s_.read(&c, sizeof(char)); return *this; } basic_binary_istream & operator>> (unsigned char & c) { s_.read(&c, sizeof(unsigned char)); return *this; } basic_binary_istream & operator>> (short & n) { if (!is_host_byte_order_same_as_network()) s_.read(&n, sizeof(short)); else s_.rread(&n, sizeof(short)); return *this; } basic_binary_istream & operator>> (unsigned short & n) { if (!is_host_byte_order_same_as_network()) s_.read(&n, sizeof(unsigned short)); else s_.rread(&n, sizeof(unsigned short)); return *this; } basic_binary_istream & operator>> (int & n) { if (!is_host_byte_order_same_as_network()) s_.read(&n, sizeof(int)); else s_.rread(&n, sizeof(int)); return *this; } basic_binary_istream & operator>> (unsigned int & n) { if (!is_host_byte_order_same_as_network()) s_.read(&n, sizeof(unsigned int)); else s_.rread(&n, sizeof(unsigned int)); return *this; } basic_binary_istream & operator>> (long long & l) { if (!is_host_byte_order_same_as_network()) s_.read(&l, sizeof(long long)); else s_.rread(&l, sizeof(long long)); return *this; } basic_binary_istream & operator>> (unsigned long long & l) { if (!is_host_byte_order_same_as_network()) s_.read(&l, sizeof(unsigned long long)); else s_.rread(&l, sizeof(unsigned long long)); return *this; } basic_binary_istream & operator>> (float & val) { s_.read(&val, sizeof(float)); return *this; } basic_binary_istream & operator>> (double & val) { s_.read(&val, sizeof(double)); return *this; } basic_binary_istream & operator>> (long double & val) { s_.read(&val, sizeof(long double)); return *this; } // no definition basic_binary_istream & operator>> (char *); basic_binary_istream & operator>> (wchar_t *); template basic_binary_istream & operator>> (T (&v)[N]); template basic_binary_istream & operator>> (T *); template basic_binary_istream & operator>> (array & arr) { size_t len = 0; this->operator >>(len); for(size_t i = 0; i < len && i < arr.max_size_; ++i) { *this >> arr.p_[i]; ++arr.size_; } return *this; } template basic_binary_istream & operator>> (std::basic_string & str) { str.clear(); size_t len = 0; this->operator >>(len); for(size_t i = 0; i < len; ++i) { CharType ch; *this >> ch; str.push_back(ch); } return *this; } template basic_binary_istream & operator>> (std::vector & vec) { typedef std::vector vector_type; vec.clear(); size_t len = 0; this->operator >>(len); for (size_t i = 0; i < len; ++i) { typename vector_type::value_type val; *this >> val; vec.push_back(val); } return *this; } template basic_binary_istream & operator>> (std::list & lst) { typedef std::list list_type; lst.clear(); size_t len = 0; this->operator >>(len); for (size_t i = 0; i < len; ++i) { typename list_type::value_type val; *this >> val; lst.push_back(val); } return *this; } template basic_binary_istream & operator>> (std::queue & qu) { typedef std::queue queue_type; size_t len = 0; this->operator >>(len); for(size_t i = 0; i < len; ++i) { typename queue_type::value_type val; *this >> val; qu.push(val); } return *this; } template basic_binary_istream & operator>> (std::deque & dq) { typedef std::deque deque_type; dq.clear(); size_t len = 0; this->operator >>(len); for(size_t i = 0; i < len; ++i) { typename deque_type::value_type val; *this >> val; dq.push_back(val); } return *this; } template basic_binary_istream & operator>> (const std::set & st) { typedef std::set set_type; size_t len = 0; this->operator >>(len); for(size_t i = 0; i < len; ++i) { typename set_type::value_type val; *this >> val; st.insert(val); } return *this; } template basic_binary_istream & operator>> (std::pair & par) { typedef std::pair pair_type; *this >> par.first; *this >> par.second; return *this; } template basic_binary_istream & operator>> (std::map & mp) { typedef std::map map_type; size_t len = 0; this->operator >>(len); for(size_t i = 0; i < len; ++i) { std::pair val; *this >> val.first; *this >> val.second; mp[val.first] = val.second; } return *this; } private: basic_stream_buffer & s_; }; // class basic_binary_istream } // namespace utilib