github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/cybozu/stream.hpp (about)

     1  #pragma once
     2  /**
     3  	@file
     4  	@brief stream and line stream class
     5  
     6  	@author MITSUNARI Shigeo(@herumi)
     7  */
     8  #ifndef CYBOZU_DONT_USE_STRING
     9  #include <string>
    10  #include <iosfwd>
    11  #endif
    12  #include <cybozu/exception.hpp>
    13  #include <memory.h>
    14  
    15  namespace cybozu {
    16  
    17  namespace stream_local {
    18  
    19  template <typename From, typename To>
    20  struct is_convertible {
    21  	typedef char yes;
    22  	typedef int no;
    23  
    24  	static no test(...);
    25  	static yes test(const To*);
    26  	static const bool value = sizeof(test(static_cast<const From*>(0))) == sizeof(yes);
    27  };
    28  
    29  template <bool b, class T = void>
    30  struct enable_if { typedef T type; };
    31  
    32  template <class T>
    33  struct enable_if<false, T> {};
    34  
    35  #ifndef CYBOZU_DONT_USE_STRING
    36  /* specialization for istream */
    37  template<class InputStream>
    38  size_t readSome_inner(void *buf, size_t size, InputStream& is, typename enable_if<is_convertible<InputStream, std::istream>::value>::type* = 0)
    39  {
    40  	if (size > 0x7fffffff) size = 0x7fffffff;
    41  	is.read(static_cast<char *>(buf), size);
    42  	const int64_t readSize = is.gcount();
    43  	if (readSize < 0) return 0;
    44  	if (size == 1 && readSize == 0) is.clear();
    45  	return static_cast<size_t>(readSize);
    46  }
    47  
    48  /* generic version for size_t readSome(void *, size_t) */
    49  template<class InputStream>
    50  size_t readSome_inner(void *buf, size_t size, InputStream& is, typename enable_if<!is_convertible<InputStream, std::istream>::value>::type* = 0)
    51  {
    52  	return is.readSome(buf, size);
    53  }
    54  #else
    55  template<class InputStream>
    56  size_t readSome_inner(void *buf, size_t size, InputStream& is)
    57  {
    58  	return is.readSome(buf, size);
    59  }
    60  #endif
    61  
    62  #ifndef CYBOZU_DONT_USE_EXCEPTION
    63  /* specialization for ostream */
    64  template<class OutputStream>
    65  void writeSub(OutputStream& os, const void *buf, size_t size, typename enable_if<is_convertible<OutputStream, std::ostream>::value>::type* = 0)
    66  {
    67  	if (!os.write(static_cast<const char *>(buf), size)) throw cybozu::Exception("stream:writeSub") << size;
    68  }
    69  #endif
    70  
    71  #ifndef CYBOZU_DONT_USE_STRING
    72  /* generic version for void write(const void*, size_t), which writes all data */
    73  template<class OutputStream>
    74  void writeSub(OutputStream& os, const void *buf, size_t size, typename enable_if<!is_convertible<OutputStream, std::ostream>::value>::type* = 0)
    75  {
    76  	os.write(buf, size);
    77  }
    78  
    79  template<class OutputStream>
    80  void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size, typename enable_if<is_convertible<OutputStream, std::ostream>::value>::type* = 0)
    81  {
    82  	*pb = !!os.write(static_cast<const char *>(buf), size);
    83  }
    84  
    85  /* generic version for void write(const void*, size_t), which writes all data */
    86  template<class OutputStream>
    87  void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size, typename enable_if<!is_convertible<OutputStream, std::ostream>::value>::type* = 0)
    88  {
    89  	os.write(pb, buf, size);
    90  }
    91  #else
    92  template<class OutputStream>
    93  void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size)
    94  {
    95  	os.write(pb, buf, size);
    96  }
    97  #endif
    98  
    99  } // stream_local
   100  
   101  /*
   102  	make a specializaiton of class to use new InputStream, OutputStream
   103  */
   104  template<class InputStream>
   105  struct InputStreamTag {
   106  	static size_t readSome(void *buf, size_t size, InputStream& is)
   107  	{
   108  		return stream_local::readSome_inner<InputStream>(buf, size, is);
   109  	}
   110  	static bool readChar(char *c, InputStream& is)
   111  	{
   112  		return readSome(c, 1, is) == 1;
   113  	}
   114  };
   115  
   116  template<class OutputStream>
   117  struct OutputStreamTag {
   118  	static void write(OutputStream& os, const void *buf, size_t size)
   119  	{
   120  		stream_local::writeSub<OutputStream>(os, buf, size);
   121  	}
   122  };
   123  
   124  class MemoryInputStream {
   125  	const char *p_;
   126  	size_t size_;
   127  	size_t pos;
   128  public:
   129  	MemoryInputStream(const void *p, size_t size) : p_(static_cast<const char *>(p)), size_(size), pos(0) {}
   130  	size_t readSome(void *buf, size_t size)
   131  	{
   132  		if (size > size_  - pos) size = size_ - pos;
   133  		memcpy(buf, p_ + pos, size);
   134  		pos += size;
   135  		return size;
   136  	}
   137  	size_t getPos() const { return pos; }
   138  };
   139  
   140  class MemoryOutputStream {
   141  	char *p_;
   142  	size_t size_;
   143  	size_t pos;
   144  public:
   145  	MemoryOutputStream(void *p, size_t size) : p_(static_cast<char *>(p)), size_(size), pos(0) {}
   146  	void write(bool *pb, const void *buf, size_t size)
   147  	{
   148  		if (size > size_ - pos) {
   149  			*pb = false;
   150  			return;
   151  		}
   152  		memcpy(p_ + pos, buf, size);
   153  		pos += size;
   154  		*pb = true;
   155  	}
   156  #ifndef CYBOZU_DONT_USE_EXCEPTION
   157  	void write(const void *buf, size_t size)
   158  	{
   159  		bool b;
   160  		write(&b, buf, size);
   161  		if (!b) throw cybozu::Exception("MemoryOutputStream:write") << size << size_ << pos;
   162  	}
   163  #endif
   164  	size_t getPos() const { return pos; }
   165  };
   166  
   167  #ifndef CYBOZU_DONT_USE_STRING
   168  class StringInputStream {
   169  	const std::string& str_;
   170  	size_t pos;
   171  	StringInputStream(const StringInputStream&);
   172  	void operator=(const StringInputStream&);
   173  public:
   174  	explicit StringInputStream(const std::string& str) : str_(str), pos(0) {}
   175  	size_t readSome(void *buf, size_t size)
   176  	{
   177  		const size_t remainSize = str_.size() - pos;
   178  		if (size > remainSize) size = remainSize;
   179  		memcpy(buf, &str_[pos], size);
   180  		pos += size;
   181  		return size;
   182  	}
   183  	size_t getPos() const { return pos; }
   184  };
   185  
   186  class StringOutputStream {
   187  	std::string& str_;
   188  	StringOutputStream(const StringOutputStream&);
   189  	void operator=(const StringOutputStream&);
   190  public:
   191  	explicit StringOutputStream(std::string& str) : str_(str) {}
   192  	void write(bool *pb, const void *buf, size_t size)
   193  	{
   194  		str_.append(static_cast<const char *>(buf), size);
   195  		*pb = true;
   196  	}
   197  	void write(const void *buf, size_t size)
   198  	{
   199  		str_.append(static_cast<const char *>(buf), size);
   200  	}
   201  	size_t getPos() const { return str_.size(); }
   202  };
   203  #endif
   204  
   205  template<class InputStream>
   206  size_t readSome(void *buf, size_t size, InputStream& is)
   207  {
   208  	return stream_local::readSome_inner(buf, size, is);
   209  }
   210  
   211  template<class OutputStream>
   212  void write(OutputStream& os, const void *buf, size_t size)
   213  {
   214  	stream_local::writeSub(os, buf, size);
   215  }
   216  
   217  template<class OutputStream>
   218  void write(bool *pb, OutputStream& os, const void *buf, size_t size)
   219  {
   220  	stream_local::writeSub(pb, os, buf, size);
   221  }
   222  
   223  template<typename InputStream>
   224  void read(bool *pb, void *buf, size_t size, InputStream& is)
   225  {
   226  	char *p = static_cast<char*>(buf);
   227  	while (size > 0) {
   228  		size_t readSize = cybozu::readSome(p, size, is);
   229  		if (readSize == 0) {
   230  			*pb = false;
   231  			return;
   232  		}
   233  		p += readSize;
   234  		size -= readSize;
   235  	}
   236  	*pb = true;
   237  }
   238  
   239  #ifndef CYBOZU_DONT_USE_EXCEPTION
   240  template<typename InputStream>
   241  void read(void *buf, size_t size, InputStream& is)
   242  {
   243  	bool b;
   244  	read(&b, buf, size, is);
   245  	if (!b) throw cybozu::Exception("stream:read");
   246  }
   247  #endif
   248  
   249  template<class InputStream>
   250  bool readChar(char *c, InputStream& is)
   251  {
   252  	return readSome(c, 1, is) == 1;
   253  }
   254  
   255  template<class OutputStream>
   256  void writeChar(OutputStream& os, char c)
   257  {
   258  	cybozu::write(os, &c, 1);
   259  }
   260  
   261  template<class OutputStream>
   262  void writeChar(bool *pb, OutputStream& os, char c)
   263  {
   264  	cybozu::write(pb, os, &c, 1);
   265  }
   266  
   267  } // cybozu