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