22 explicit ByteStreamBuf(ios_base::openmode mode = 0) : Super(ios_base::in|ios_base::out|mode), _mode(mode) {}
32 seekoff(0, ios_base::beg, ios_base::out);
33 sputn(bs.data(), bs.size());
35 if (!appendMode()) seekoff(0, ios_base::beg, ios_base::out);
38 std::streamsize
sgetn(
byte* s, std::streamsize n) {
return Super::sgetn(reinterpret_cast<char*>(s), n); }
42 std::streamsize
sputn(
const byte* s, std::streamsize n) {
return Super::sputn(reinterpret_cast<const char*>(s), n); }
45 byte*
gptr()
const {
return reinterpret_cast<byte*
>(Super::gptr()); }
47 void setg(
byte* gbeg,
byte* gnext,
byte* gend) { Super::setg(reinterpret_cast<char*>(gbeg), reinterpret_cast<char*>(gnext), reinterpret_cast<char*>(gend)); }
50 byte*
pptr()
const {
return reinterpret_cast<byte*
>(Super::pptr()); }
52 void setp(
byte* new_pbase,
byte* new_epptr) { Super::setp(reinterpret_cast<char*>(new_pbase), reinterpret_cast<char*>(new_epptr)); }
55 std::basic_string<byte> str()
const;
56 void str(
const std::basic_string<byte>& s);
57 bool appendMode()
const {
return _mode & (ios_base::app | ios_base::ate); }
59 ios_base::openmode _mode;
73 int_type
get() {
return Super::get(); }
74 ByteStream&
get(
byte& c) { Super::get(reinterpret_cast<char&>(c));
return *
this; }
75 ByteStream&
get(
byte* s, std::streamsize n) { Super::get(reinterpret_cast<char*>(s), n);
return *
this; }
76 ByteStream&
get(
byte* s, std::streamsize n,
byte delim) { Super::get(reinterpret_cast<char*>(s), n, delim);
return *
this; }
77 ByteStream&
get(std::streambuf& sb) { Super::get(sb);
return *
this; }
78 ByteStream&
get(std::streambuf& sb,
byte delim) { Super::get(sb, delim);
return *
this; }
79 ByteStream&
getline(
byte* s, std::streamsize n) { Super::getline(reinterpret_cast<char*>(s), n);
return *
this; }
81 ByteStream&
ignore(std::streamsize count = 1, int_type delim = traits_type::eof()) { Super::ignore(count, delim);
return *
this; }
82 ByteStream&
read(
byte* s, std::streamsize n) { Super::read(reinterpret_cast<char*>(s), n);
return *
this; }
83 std::streamsize
readsome(
byte* s, std::streamsize n) {
return Super::readsome(reinterpret_cast<char*>(s), n); }
87 ByteStream&
seekg(off_type off, ios_base::seekdir dir) { Super::seekg(off, dir);
return *
this; }
90 ByteStream&
write(
const byte* s, std::streamsize n) { Super::write(reinterpret_cast<const char*>(s), n);
return *
this; }
92 ByteStream&
seekp(off_type off, ios_base::seekdir dir) { Super::seekp(off, dir);
return *
this; }
103 template<class T, typename std::enable_if<std::is_integral<T>::value || std::is_floating_point<T>::value,
int>::type=0>
107 BitOp::toPartsBig(val, a);
108 os.
write(a,
sizeof(T));
121 template<class T, typename std::enable_if<std::is_integral<T>::value || std::is_floating_point<T>::value,
int>::type=0>
125 is.
read(a,
sizeof(T));
126 val = BitOp::fromPartsBig<T>(a);
143 assert(v.val >= 0,
"VarSize value must be positive");
144 if (v.val <= 0)
return os <<
uint8(0);
145 else if (v.val <= numeral<uint8>().max()-3)
return os <<
uint8(v.val);
146 else if (v.val <= numeral<uint16>().max())
return os << numeral<uint8>().max() <<
uint16(v.val);
147 else if (v.val <= numeral<uint32>().max())
return os <<
uint8(numeral<uint8>().max()-1) <<
uint32(v.val);
148 else return os << uint8(numeral<uint8>().max()-2) <<
uint64(v.val);
151 template<
class VarSize_>
152 friend typename std::enable_if<std::is_same<VarSize,VarSize_>::value,
ByteStream&>::type
156 typedef typename std::remove_const<typename mt::removeRef<Int>::type>::type Int_;
161 case numeral<uint8>().max(): {
uint16 val; is >> val; v.val = numeric_cast<Int_>(val);
break; }
162 case numeral<uint8>().max()-1: {
uint32 val; is >> val; v.val = numeric_cast<Int_>(val);
break; }
163 case numeral<uint8>().max()-2: {
uint64 val; is >> val; v.val = numeric_cast<Int_>(val);
break; }
164 default: v.val = numeric_cast<Int_>(
size);
break;
174 template<class Int, typename std::enable_if<std::is_integral<typename mt::removeRef<Int>::type>::value,
int>::type=0>
176 auto varSize(Int&& val) {
return priv::VarSize<Int>{forward<Int>(val)}; }
180 template<
class T1,
class T2>
181 ByteStream& operator<<(ByteStream& os, const pair<T1,T2>& p) {
return os << p.first << p.second; }
185 template<
class Tuple,
szt... Seq>
186 void tupleToBytes(ByteStream& os, Tuple&& t, mt::idxseq<Seq...>)
187 {
mt::exec([&]() { os << get<Seq>(forward<Tuple>(t)); }...); }
189 void listToBytes(ByteStream& os,
const List& list) { os <<
bytestream::varSize(list.size());
for (
auto& e: list) os << e; }
192 template<
class Tuple>
194 typename std::enable_if<mt::isTuple<Tuple>::value, ByteStream&>::type
197 template<
class T, szt N>
199 {
for (
auto& e: a) os << e;
return os; }
201 template<class T, szt N, typename std::enable_if<!std::is_same<T,char>::value && !std::is_same<T,Char>::value,
int>::type=0>
204 template<
class T,
class Alloc>
205 ByteStream& operator<<(ByteStream& os, const vector<T,Alloc>& vec)
206 { priv::listToBytes(os, vec);
return os; }
209 { priv::listToBytes(os, str);
return os; }
212 {
auto len = std::char_traits<Char>::length(str); os <<
bytestream::varSize(len);
for (
auto& e:
range(str,str+len)) os << e;
return os; }
215 { os <<
bytestream::varSize(str.length()); os.std::iostream::write(str.data(), str.length());
return os; }
218 {
auto len = strlen(str); os <<
bytestream::varSize(len); os.std::iostream::write(str, len);
return os; }
223 template<class T, typename std::enable_if<std::is_same<T,const byte*>::value || std::is_same<T,byte*>::value,
int>::type=0>
224 ByteStream&
operator<<(ByteStream& os, T bs) { static_assert(!mt::True<T>::value,
"Unimplemented, use ByteBufConst(bs, n) instead");
return os; }
229 template<
class T,
class Compare,
class Alloc>
230 ByteStream& operator<<(ByteStream& os, const set<T,Compare,Alloc>& set)
231 { priv::listToBytes(os, set);
return os; }
233 template<
class T,
class Compare,
class Alloc>
234 ByteStream& operator<<(ByteStream& os, const multiset<T,Compare,Alloc>& set)
235 { priv::listToBytes(os, set);
return os; }
237 template<
class Key,
class Hash,
class KeyEqual,
class Alloc>
238 ByteStream& operator<<(ByteStream& os, const unordered_set<Key,Hash,KeyEqual,Alloc>& set)
239 { priv::listToBytes(os, set);
return os; }
241 template<
class Key,
class Hash,
class KeyEqual,
class Alloc>
242 ByteStream& operator<<(ByteStream& os, const unordered_multiset<Key,Hash,KeyEqual,Alloc>& set)
243 { priv::listToBytes(os, set);
return os; }
245 template<
class Key,
class T,
class Compare,
class Alloc>
246 ByteStream& operator<<(ByteStream& os, const std::map<Key,T,Compare,Alloc>&
map)
247 { priv::listToBytes(os,
map);
return os; }
249 template<
class Key,
class T,
class Compare,
class Alloc>
250 ByteStream& operator<<(ByteStream& os, const multimap<Key,T,Compare,Alloc>&
map)
251 { priv::listToBytes(os,
map);
return os; }
253 template<
class Key,
class T,
class Hash,
class KeyEqual,
class Alloc>
254 ByteStream& operator<<(ByteStream& os, const unordered_map<Key,T,Hash,KeyEqual,Alloc>&
map)
255 { priv::listToBytes(os,
map);
return os; }
257 template<
class Key,
class T,
class Hash,
class KeyEqual,
class Alloc>
258 ByteStream& operator<<(ByteStream& os, const unordered_multimap<Key,T,Hash,KeyEqual,Alloc>&
map)
259 { priv::listToBytes(os,
map);
return os; }
262 template<
class T1,
class T2>
267 template<
class Tuple,
szt... Seq>
268 void tupleFromBytes(ByteStream& is, Tuple& t, mt::idxseq<Seq...>)
269 {
mt::exec([&]() { is >> get<Seq>(t); }...); }
270 template<
class Set,
class T =
typename Set::value_type>
272 template<
class Map,
class Key =
typename Map::key_type,
class Val =
typename Map::mapped_type>
276 template<
class Tuple>
278 typename std::enable_if<mt::isTuple<Tuple>::value, ByteStream&>::type
281 template<
class T, szt N>
284 template<class T, szt N, typename std::enable_if<!std::is_same<T,char>::value && !std::is_same<T,Char>::value,
int>::type=0>
287 template<
class T,
class Alloc>
298 {
szt size; is >>
bytestream::varSize(size); str.resize(size); is.std::iostream::read(str.length() ? &str[0] :
nullptr, str.length());
return is; }
306 template<class T, typename std::enable_if<std::is_same<T,byte*>::value,
int>::type=0>
309 template<
class T,
class Compare,
class Alloc>
311 { priv::setFromBytes(is, set);
return is; }
313 template<
class T,
class Compare,
class Alloc>
315 { priv::setFromBytes(is, set);
return is; }
317 template<
class Key,
class Hash,
class KeyEqual,
class Alloc>
319 { priv::setFromBytes(is, set);
return is; }
321 template<
class Key,
class Hash,
class KeyEqual,
class Alloc>
323 { priv::setFromBytes(is, set);
return is; }
325 template<
class Key,
class T,
class Compare,
class Alloc>
327 { priv::mapFromBytes(is, map);
return is; }
329 template<
class Key,
class T,
class Compare,
class Alloc>
331 { priv::mapFromBytes(is, map);
return is; }
333 template<
class Key,
class T,
class Hash,
class KeyEqual,
class Alloc>
335 { priv::mapFromBytes(is, map);
return is; }
337 template<
class Key,
class T,
class Hash,
class KeyEqual,
class Alloc>
339 { priv::mapFromBytes(is, map);
return is; }
361 assert(allocs.empty(),
"ByteStream allocator stack not empty");
362 assert(sharedTables.empty(),
"ByteStream shared table stack not empty");
366 T*
alloc(
szt size)
const {
return allocs.size() ?
static_cast<T*
>(allocs.back()(
size)) : std::allocator<T>().allocate(size); }
368 Id curSharedTable()
const {
return sharedTables.size() ? sharedTables.back() :
idnull; }
370 szt sharedToIndex(
void* p)
373 auto& table = sharedTablesOut[curSharedTable()];
374 auto res = table.insert(make_pair(p, table.size()));
375 return res.second ? 1 : res.first->second + 2;
379 SharedPtr<T> indexToShared(
szt i)
381 if (!i)
return nullptr;
382 auto& table = sharedTablesIn[curSharedTable()];
385 table.push_back(SharedPtr<T>(
new (alloc<T>(1)) T));
386 return static_pointer_cast<T>(table.back());
388 assert(i-2 < table.size());
389 return static_pointer_cast<T>(table[i-2]);
395 sharedTables.clear();
396 sharedTablesOut.clear();
397 sharedTablesIn.clear();
400 vector<function<void* (szt)>> allocs;
401 vector<Id> sharedTables;
402 unordered_map<Id, unordered_map<void*, szt>> sharedTablesOut;
403 unordered_map<Id, vector<SharedPtr<void>>> sharedTablesIn;
408 inline auto pushAlloc(
const function<
void* (
szt)>&
alloc) {
return manipFunc([=](ByteStream& is) { priv::Manip::inst(is).allocs.push_back(
alloc); }); }
421 template<
class T,
class Fin>
422 ByteStream& operator<<(ByteStream& os, const UniquePtr<T,Fin>& p)
423 {
return p ? os <<
true << *p : os <<
false; }
425 template<
class T,
class Fin>
435 template<
class Rep,
class Period>
436 ByteStream& operator<<(ByteStream& os, const Duration<Rep,Period>& d) {
return os << d.count(); }
438 template<
class Rep,
class Period>
byte * egptr() const
Definition: ByteStream.h:46
szt fast(ByteBufConst bs, szt seed)
Quickly generate a small hash value. Each seed value produces a unique hash from the same data...
Definition: Hash.cpp:99
A contiguous region of referenced (not owned by object) memory.
Definition: Buffer.h:17
auto manipFunc(Func &&f, Args &&...args)
Helper to create a manipulator that takes arguments. eg. A manip named 'foo': auto foo(int val) { ret...
Definition: StdUtil.h:243
ByteStream & flush()
Definition: ByteStream.h:93
istream & operator>>(istream &is, Bytes &val)
Definition: Bytes.cpp:16
int sputc(byte c)
Definition: ByteStream.h:41
std::streamsize sgetn(byte *s, std::streamsize n)
Definition: ByteStream.h:38
ByteStreamBuf(ByteStreamBuf &&rhs)
Definition: ByteStream.h:25
uint8 byte
An unsigned 8-bit integer.
Definition: Bytes.h:12
Holds both a name string and its hashed value, and unlike Id the name is never compiled out...
Definition: Id.h:144
std::stringbuf Super
Definition: ByteStream.h:20
int_type get()
Definition: ByteStream.h:73
byte * epptr() const
Definition: ByteStream.h:51
unsigned int uint32
Definition: Core.h:16
Combined intrusive/non-intrusive smart pointer. Can reference and share any object automatically...
Definition: SharedPtr.h:175
ByteStream & put(byte c)
Definition: ByteStream.h:89
std::streamsize sputn(const byte *s, std::streamsize n)
Definition: ByteStream.h:42
ByteStream & seekp(pos_type pos)
Definition: ByteStream.h:91
Id created from a string literal at compile-time.
Definition: Id.h:81
ByteStream & unget()
Definition: ByteStream.h:85
ByteStreamBuf(const Bytes &bs, ios_base::openmode mode=0)
Definition: ByteStream.h:23
byte * pbase() const
Definition: ByteStream.h:49
auto popSharedTable()
Pop a shared table id from the bytestream.
Definition: ByteStream.h:415
void set(Ptr p)
Finalize old pointer and assign new. Does not finalize if old pointer is the same or null...
Definition: UniquePtr.h:73
Bytes bytes() const
Definition: ByteStream.h:29
void bytes(const Bytes &bs)
Definition: ByteStream.h:30
ByteStream(std::streambuf *sb)
Definition: ByteStream.h:68
byte * gptr() const
Definition: ByteStream.h:45
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
static auto _
Definition: Module.cpp:8
ByteStream & getline(byte *s, std::streamsize n)
Definition: ByteStream.h:79
auto pushAlloc(const function< void *(szt)> &alloc)
Push an allocator onto the input bytestream for subsequent unique/shared pointer object allocations...
Definition: ByteStream.h:409
unsigned long long uint64
Definition: Core.h:22
ByteStream & read(byte *s, std::streamsize n)
Definition: ByteStream.h:82
ByteStream & getline(byte *s, std::streamsize n, byte delim)
Definition: ByteStream.h:80
auto reset()
Reset bytestream manipulator state.
Definition: ByteStream.h:417
ByteStream & seekg(off_type off, ios_base::seekdir dir)
Definition: ByteStream.h:87
ByteStream & ignore(std::streamsize count=1, int_type delim=traits_type::eof())
Definition: ByteStream.h:81
unsigned char uint8
Definition: Core.h:12
void setg(byte *gbeg, byte *gnext, byte *gend)
Definition: ByteStream.h:47
ByteStream(ByteStream &&rhs)
Definition: ByteStream.h:69
char16_t Char
Represents a single code unit (not code point) for class String.
Definition: String.h:13
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
szt size() const
Returns the number of elements.
Definition: Buffer.h:78
#define idnull
Null id.
Definition: Id.h:124
auto pushSharedTable(const Id &id)
Push a shared table id onto the bytestream for subsequent shared pointer serialization.
Definition: ByteStream.h:413
Unicode UTF-16 string class, wrapper around std::u16string.
Definition: String.h:23
Always returns true. Can be used to force a clause to be type dependent.
Definition: Meta.h:31
An I/O stream into which objects may be serialized and subsequently deserialized. ...
Definition: ByteStream.h:63
unsigned short uint16
Definition: Core.h:14
String of bytes.
Definition: Bytes.h:26
std::streamsize readsome(byte *s, std::streamsize n)
Definition: ByteStream.h:83
Duration represented by repetitions of a period. The period must be a ratio.
Definition: Duration.h:7
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
T * alloc(szt count=1)
Allocate memory for count number of T objects. Objects are not constructed.
Definition: Allocator.h:31
ByteStream & operator=(ByteStream &&rhs)
Definition: ByteStream.h:71
ByteStream & write(const byte *s, std::streamsize n)
Definition: ByteStream.h:90
ByteStream & putback(byte c)
Definition: ByteStream.h:84
szt _hash
Definition: Id.h:77
#define debug_if(...)
Evaluate expression in debug mode only, does nothing in final mode.
Definition: Debug.h:30
int size(const StdContainer &cont)
Safely get the size of a std container as a signed integer.
Definition: StdUtil.h:19
void setp(byte *new_pbase, byte *new_epptr)
Definition: ByteStream.h:52
auto varSize(Int &&val)
Write or read a size (a positive integer) using a minimal number of bytes.
Definition: ByteStream.h:176
Base class to hold iostream manipulator state. Inherit from this class and call Subclass::inst(ios) t...
Definition: StdUtil.h:206
auto popAlloc()
Pop an allocator from the input bytestream.
Definition: ByteStream.h:411
int sputbackc(byte c)
Definition: ByteStream.h:39
ByteStream & seekg(pos_type pos)
Definition: ByteStream.h:86
byte * pptr() const
Definition: ByteStream.h:50
ByteStream & seekp(off_type off, ios_base::seekdir dir)
Definition: ByteStream.h:92
Holds a name string and its hashed value for fast comparison ops. See String Identifier.
Definition: Id.h:25
std::iostream Super
Definition: ByteStream.h:66
ByteStreamBuf(ios_base::openmode mode=0)
Definition: ByteStream.h:22
ByteStreamBuf & operator=(ByteStreamBuf &&rhs)
Definition: ByteStream.h:27
Pointer to a unique, non-shared, object. Finalizer is run upon destruction (deletes object by default...
Definition: SharedPtr.h:164
ostream & operator<<(ostream &os, const Bytes &val)
Definition: Bytes.cpp:9
Global Honeycomb namespace.
byte * eback() const
Definition: ByteStream.h:44
A stream I/O buffer of bytes, to be passed into ByteStream.
Definition: ByteStream.h:17
T * data() const
Get the referenced memory.
Definition: Buffer.h:57
OutSeq && map(Range &&, Seqs &&..., OutSeq &&, Func &&)
Transform a series of sequences into an output.