25 #include "common/file.h" 26 #include "common/memstream.h" 27 #include "common/safe-bool.h" 28 #include "common/scummsys.h" 29 #include "common/type-traits.h" 33 #define COMMON_SPAN_TYPEDEFS \ 34 typedef typename super_type::value_type value_type; \ 35 typedef typename super_type::difference_type difference_type; \ 36 typedef typename super_type::index_type index_type; \ 37 typedef typename super_type::size_type size_type; \ 38 typedef typename super_type::const_iterator const_iterator; \ 39 typedef typename super_type::iterator iterator; \ 40 typedef typename super_type::pointer pointer; \ 41 typedef typename super_type::const_pointer const_pointer; \ 42 typedef typename super_type::reference reference; \ 43 typedef typename super_type::const_reference const_reference; 46 kSpanMaxSize = 0xFFFFFFFF,
47 kSpanKeepOffset = 0xFFFFFFFF
51 #pragma mark SpanValidationMode 53 enum SpanValidationMode {
59 namespace SpanInternal {
61 #pragma mark SpanIterator 65 template <
typename Span,
bool IsConst>
67 typedef typename Span::value_type span_value_type;
71 typedef typename Span::difference_type difference_type;
72 typedef typename RemoveConst<span_value_type>::type value_type;
78 inline SpanIterator(span_type *
const span,
const difference_type index) :
81 if (span !=
nullptr) {
82 span->validate(index, 0, kValidateSeek);
88 _index(other._index) {}
92 _index = other._index;
97 #pragma mark SpanIterator - Dereferencing operations 100 inline reference operator*()
const {
102 return (*_span)[_index];
105 inline pointer operator->()
const {
109 inline reference operator[](
const difference_type index)
const {
111 return *(*
this + index);
115 #pragma mark SpanIterator - Arithmetic operations 118 inline SpanIterator &operator+=(
const difference_type delta) {
119 assert(_span !=
nullptr);
120 _span->validate(_index, delta, kValidateSeek);
125 inline SpanIterator &operator-=(
const difference_type delta) {
126 return operator+=(-delta);
130 return operator+=(1);
140 return operator+=(-1);
149 inline SpanIterator operator+(
const difference_type delta)
const {
154 inline SpanIterator operator-(
const difference_type delta)
const {
155 return operator+(-delta);
158 inline difference_type operator-(
const SpanIterator &other)
const {
159 assert(_span == other._span);
160 return _index - other._index;
164 #pragma mark SpanIterator - Comparison operations 167 inline bool operator==(
const SpanIterator& other)
const {
168 return _span == other._span && _index == other._index;
171 inline bool operator!=(
const SpanIterator& other)
const {
172 return !operator==(other);
175 inline bool operator<(
const SpanIterator& other)
const {
176 assert(_span == other._span);
177 return _index < other._index;
180 inline bool operator<=(
const SpanIterator& other)
const {
181 return !other.operator<(*this);
184 inline bool operator>(
const SpanIterator& other)
const {
185 return other.operator<(*this);
188 inline bool operator>=(
const SpanIterator& other)
const {
189 return !operator<(other);
193 #pragma mark SpanIterator - Data access convenience functions 196 inline int8 getInt8()
const {
197 return _span->getInt8At(_index);
200 inline uint8 getUint8()
const {
201 return _span->getUint8At(_index);
204 inline int16 getInt16BE()
const {
205 return _span->getInt16BEAt(_index);
208 inline int16 getInt16LE()
const {
209 return _span->getInt16LEAt(_index);
212 inline uint16 getUint16BE()
const {
213 return _span->getUint16BEAt(_index);
216 inline uint16 getUint16LE()
const {
217 return _span->getUint16LEAt(_index);
220 inline uint32 getUint24LE()
const {
221 return _span->getUint24LEAt(_index);
224 inline uint32 getUint32()
const {
225 return _span->getUint32At(_index);
228 inline int32 getInt32BE()
const {
229 return _span->getInt32BEAt(_index);
232 inline int32 getInt32LE()
const {
233 return _span->getInt32LEAt(_index);
236 inline uint32 getUint32BE()
const {
237 return _span->getUint32BEAt(_index);
240 inline uint32 getUint32LE()
const {
241 return _span->getUint32LEAt(_index);
246 difference_type _index;
251 #pragma mark SpanBase 253 template <
typename ValueType,
template <
typename>
class Derived>
255 typedef Derived<ValueType> derived_type;
256 typedef typename AddConst<derived_type>::type const_derived_type;
257 typedef typename RemoveConst<derived_type>::type mutable_derived_type;
260 template <
typename T,
template <
typename>
class U>
friend class SpanBase;
261 template <
typename T,
typename U>
friend struct SafeBool;
262 #ifdef CXXTEST_RUNNING 263 friend class ::SpanTestSuite;
267 typedef ValueType value_type;
268 typedef int32 difference_type;
269 typedef uint32 index_type;
270 typedef uint32 size_type;
273 typedef value_type *pointer;
274 typedef const value_type *const_pointer;
275 typedef value_type &reference;
276 typedef const value_type &const_reference;
278 inline size_type byteSize()
const {
return impl().size() *
sizeof(value_type); }
280 #if !defined(_MSC_VER) 288 inline const_derived_type &impl()
const {
return static_cast<const_derived_type &
>(*this); }
289 inline mutable_derived_type &impl() {
return static_cast<mutable_derived_type &
>(*this); }
292 #pragma mark SpanBase - Interface 294 #if !defined(_MSC_VER) 299 inline size_type size()
const;
301 inline const_iterator cbegin()
const;
302 inline const_iterator cend()
const;
303 inline const_iterator begin()
const;
304 inline const_iterator end()
const;
305 inline iterator begin();
306 inline iterator end();
308 inline pointer data()
const;
311 #pragma mark SpanBase - Data access functions 314 inline const_reference operator[](
const index_type index)
const {
315 impl().validate(index,
sizeof(value_type));
316 return impl().data()[index];
319 inline reference operator[](
const index_type index) {
320 impl().validate(index,
sizeof(value_type));
321 return impl().data()[index];
324 inline int8 getInt8At(
const index_type index)
const {
325 STATIC_ASSERT(
sizeof(value_type) ==
sizeof(uint8), int8_can_only_be_read_from_byte_or_char_spans);
326 return (int8)getUint8At(index);
329 inline uint8 getUint8At(
const index_type index)
const {
330 STATIC_ASSERT(
sizeof(value_type) ==
sizeof(uint8), uint8_can_only_be_read_from_byte_or_char_spans);
331 impl().validate(index,
sizeof(uint8));
332 return (uint8)impl().data()[index];
335 inline int16 getInt16BEAt(
const index_type index)
const {
336 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), int16_can_only_be_read_from_int16_or_smaller_spans);
337 return (int16)impl().getUint16BEAt(index);
340 inline int16 getInt16LEAt(
const index_type index)
const {
341 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), int16_can_only_be_read_from_int16_or_smaller_spans);
342 return (int16)impl().getUint16LEAt(index);
345 inline uint16 getUint16BEAt(
const index_type index)
const {
346 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), uint16_can_only_be_read_from_int16_or_smaller_spans);
347 impl().validate(index,
sizeof(uint16));
348 return READ_BE_UINT16(impl().data() + index);
351 inline uint16 getUint16LEAt(
const index_type index)
const {
352 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint16), uint16_can_only_be_read_from_int16_or_smaller_spans);
353 impl().validate(index,
sizeof(uint16));
354 return READ_LE_UINT16(impl().data() + index);
357 inline uint32 getUint24LEAt(
const index_type index)
const {
358 STATIC_ASSERT(
sizeof(value_type) <= 3, uint24_can_only_be_read_from_int24_or_smaller_spans);
359 impl().validate(index, 3);
360 return READ_LE_UINT24(impl().data() + index);
363 inline uint32 getUint32At(
const index_type index)
const {
364 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), uint32_can_only_be_read_from_int32_or_smaller_spans);
365 impl().validate(index,
sizeof(uint32));
366 return READ_UINT32(impl().data() + index);
369 inline int32 getInt32BEAt(
const index_type index)
const {
370 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), int32_can_only_be_read_from_int32_or_smaller_spans);
371 return (int32)impl().getUint32BEAt(index);
374 inline int32 getInt32LEAt(
const index_type index)
const {
375 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), int32_can_only_be_read_from_int32_or_smaller_spans);
376 return (int32)impl().getUint32LEAt(index);
379 inline uint32 getUint32BEAt(
const index_type index)
const {
380 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), uint32_can_only_be_read_from_int32_or_smaller_spans);
381 impl().validate(index,
sizeof(uint32));
382 return READ_BE_UINT32(impl().data() + index);
385 inline uint32 getUint32LEAt(
const index_type index)
const {
386 STATIC_ASSERT(
sizeof(value_type) <=
sizeof(uint32), uint32_can_only_be_read_from_int32_or_smaller_spans);
387 impl().validate(index,
sizeof(uint32));
388 return READ_LE_UINT32(impl().data() + index);
391 inline String getStringAt(
const index_type index, size_type numEntries = kSpanMaxSize)
const {
392 STATIC_ASSERT(
sizeof(value_type) ==
sizeof(
char), strings_can_only_be_read_from_byte_or_char_spans);
393 const char *
string = (
const char *)impl().data() + index;
395 if (numEntries == kSpanMaxSize) {
396 numEntries =
strnlen(
string, impl().size() - index);
399 impl().validate(index, numEntries);
400 return String(
string, numEntries);
409 inline const_pointer
getUnsafeDataAt(
const index_type index, size_type numEntries = kSpanMaxSize)
const {
410 if (numEntries == kSpanMaxSize) {
411 numEntries = impl().size() - index;
414 impl().validate(index, numEntries *
sizeof(value_type));
415 return impl().data() + index;
418 inline pointer getUnsafeDataAt(
const index_type index, size_type numEntries = kSpanMaxSize) {
419 if (numEntries == kSpanMaxSize) {
420 numEntries = impl().size() - index;
423 impl().validate(index, numEntries *
sizeof(value_type));
424 return impl().data() + index;
427 inline MemoryReadStream toStream(
const index_type index = 0, size_type numEntries = kSpanMaxSize)
const {
428 if (numEntries == kSpanMaxSize) {
429 numEntries = impl().size() - index;
432 impl().validate(index, numEntries *
sizeof(value_type));
433 return MemoryReadStream(impl().data() + index, numEntries *
sizeof(value_type), DisposeAfterUse::NO);
437 #pragma mark SpanBase - Operators 440 template <
typename Other>
441 inline bool operator==(
const Other &other)
const {
442 return impl().data() == other.impl().data() && impl().size() == other.impl().size();
445 template <
typename Other>
446 inline bool operator!=(
const Other &other)
const {
447 return !operator==(other);
450 template <
typename Other>
451 inline difference_type operator-(
const Other &other)
const {
452 return impl().data() - other.impl().data();
455 template <
typename Other>
456 inline bool operator<(
const Other &other)
const {
457 return impl().data() < other.impl().data();
460 template <
typename Other>
461 inline bool operator<=(
const Other &other)
const {
462 return !other.operator<(*this);
465 template <
typename Other>
466 inline bool operator>(
const Other &other)
const {
467 return other.operator<(*this);
470 template <
typename Other>
471 inline bool operator>=(
const Other &other)
const {
472 return !operator<(other);
475 #if !defined(_MSC_VER) 478 inline bool operator_bool()
const {
return impl().data() !=
nullptr; }
481 #pragma mark SpanBase - Copying 489 memcpy(target, impl().data(), impl().byteSize());
496 template <
typename Other>
498 assert((impl().byteSize() %
sizeof(
typename Other::value_type)) == 0);
499 target.impl().validate(0, impl().byteSize(), kValidateWrite);
500 memcpy(target.impl().data(), impl().data(), impl().byteSize());
504 #pragma mark SpanBase - Validation 506 #if !defined(_MSC_VER) 517 const size_t maxByteOffset = index * (signed)
sizeof(value_type) + deltaInBytes;
518 return index > impl().size() || deltaInBytes > (difference_type)impl().byteSize() || maxByteOffset > impl().byteSize();
521 inline void validate(
const index_type index,
const difference_type deltaInBytes,
const SpanValidationMode mode = kValidateRead)
const {
523 if (impl().checkInvalidBounds(index, deltaInBytes)) {
524 error(
"%s", impl().getValidationMessage(index, deltaInBytes, mode).c_str());
531 #pragma mark SpanImpl 533 template <
typename ValueType,
template <
typename>
class Derived>
539 template <
typename T,
template <
typename>
class U>
friend class SpanImpl;
540 #ifdef CXXTEST_RUNNING 541 friend class ::SpanTestSuite;
547 inline SpanImpl() : super_type(), _data(
nullptr), _size(0) {}
549 inline SpanImpl(
const pointer data_,
const size_type size_) :
554 template <
typename Other>
555 inline SpanImpl(
const Other &other) :
558 _size(other.size()) {}
560 inline void clear() {
565 inline size_type size()
const {
return _size; }
566 inline pointer data()
const {
return _data; }
577 String getValidationMessage(
const index_type index,
const difference_type deltaInBytes,
const SpanValidationMode mode)
const {
578 const char *modeName =
"unknown";
581 modeName =
"reading";
584 modeName =
"writing";
587 modeName =
"seeking";
595 this->impl().name().c_str(),
597 deltaInBytes / (
int)
sizeof(value_type),
602 #pragma mark SpanImpl - Subspan 605 template <
typename NewValueType>
606 inline const Derived<NewValueType> subspan(
const index_type index, size_type numEntries = kSpanMaxSize)
const {
607 Derived<NewValueType> span;
608 populateSubspan(span, index, numEntries);
612 template <
typename NewValueType>
613 inline Derived<NewValueType> subspan(
const index_type index, size_type numEntries = kSpanMaxSize) {
614 Derived<NewValueType> span;
615 populateSubspan(span, index, numEntries);
619 inline const_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize)
const {
620 return subspan<value_type>(index, numEntries);
623 inline mutable_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize) {
624 return subspan<value_type>(index, numEntries);
627 #if !defined(_MSC_VER) 630 template <
typename NewValueType>
631 void populateSubspan(Derived<NewValueType> &span,
const index_type index, size_type numEntries)
const {
632 if (numEntries == kSpanMaxSize) {
633 numEntries = CLIP<size_type>(size() - index, 0, size());
636 assert(numEntries *
sizeof(value_type) %
sizeof(NewValueType) == 0);
637 this->validate(index, numEntries *
sizeof(value_type), kValidateSeek);
639 span._data = (NewValueType *)const_cast<mutable_value_type *>(_data + index);
640 span._size = numEntries *
sizeof(value_type) /
sizeof(NewValueType);
644 #pragma mark SpanImpl - Allocation 647 typedef typename RemoveConst<value_type>::type mutable_value_type;
648 typedef Derived<mutable_value_type> mutable_value_derived_type;
651 mutable_value_derived_type &allocate(
const size_type numEntries) {
652 assert(_data ==
nullptr);
653 assert(numEntries != kSpanMaxSize);
654 _data =
new mutable_value_type[numEntries];
656 return (mutable_value_derived_type &)
const_cast<Derived<value_type> &
>(this->impl());
659 template <
typename Other>
660 mutable_value_derived_type &allocateFromSpan(
const Other &other) {
661 assert(_data ==
nullptr);
662 assert(
sizeof(value_type) ==
sizeof(
typename Other::value_type));
663 _data =
new mutable_value_type[other.size()];
664 _size = other.size();
665 copy(other.begin(), other.end(),
const_cast<mutable_value_type *
>(_data));
666 return (mutable_value_derived_type &)
const_cast<Derived<value_type> &
>(this->impl());
669 mutable_value_derived_type &allocateFromStream(
SeekableReadStream &stream, size_type numEntries = kSpanMaxSize) {
670 if (numEntries == kSpanMaxSize) {
671 numEntries = (stream.
size() - stream.
pos()) /
sizeof(value_type);
674 const uint32 bytesRequested = numEntries *
sizeof(value_type);
675 assert(stream.
pos() + bytesRequested <= (uint)stream.
size());
676 allocate(numEntries);
677 const uint32 bytesRead = stream.
read((
void *)const_cast<mutable_value_type *>(_data), bytesRequested);
678 assert(bytesRead == bytesRequested);
679 return (mutable_value_derived_type &)
const_cast<Derived<value_type> &
>(this->impl());
689 template <
typename ValueType>
694 template <
typename T>
friend class Span;
699 inline Span() : super_type() {}
701 inline Span(
const pointer data_,
const size_type size_) : super_type(data_, size_) {}
705 template <
typename Other>
706 inline Span(
const Other &other) : super_type(other) {}
710 #pragma mark NamedSpanImpl 712 template <
typename ValueType,
template <
typename>
class Derived>
718 template <
typename T,
template <
typename>
class U>
friend class NamedSpanImpl;
719 #ifdef CXXTEST_RUNNING 720 friend class ::SpanTestSuite;
726 inline NamedSpanImpl() : super_type(), _name(), _sourceByteOffset(0) {}
728 inline NamedSpanImpl(
const pointer data_,
729 const size_type size_,
731 const size_type sourceByteOffset_ = 0) :
732 super_type(data_, size_),
734 _sourceByteOffset(sourceByteOffset_) {}
736 template <
typename Other>
737 inline NamedSpanImpl(
const Other &other) :
740 _sourceByteOffset(other.sourceByteOffset()) {}
742 inline void clear() {
745 _sourceByteOffset = 0;
748 const String &name()
const {
return _name; }
749 String &name() {
return _name; }
751 const size_type &sourceByteOffset()
const {
return _sourceByteOffset; }
752 size_type &sourceByteOffset() {
return _sourceByteOffset; }
756 size_type _sourceByteOffset;
759 #pragma mark NamedSpanImpl - Subspan 762 template <
typename NewValueType>
763 inline const Derived<NewValueType> subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset)
const {
764 Derived<NewValueType> span;
765 populateSubspan(span, index, numEntries, name_, sourceByteOffset_);
769 template <
typename NewValueType>
770 inline Derived<NewValueType> subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset) {
771 Derived<NewValueType> span;
772 populateSubspan(span, index, numEntries, name_, sourceByteOffset_);
776 inline const_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset)
const {
777 return subspan<value_type>(index, numEntries, name_, sourceByteOffset_);
780 inline mutable_derived_type subspan(
const index_type index,
const size_type numEntries = kSpanMaxSize,
const String &name_ =
String(),
const size_type sourceByteOffset_ = kSpanKeepOffset) {
781 return subspan<value_type>(index, numEntries, name_, sourceByteOffset_);
784 #if !defined(_MSC_VER) 787 template <
typename NewValueType>
788 void populateSubspan(Derived<NewValueType> &span,
const index_type index, size_type numEntries,
const String &name_,
const size_type sourceByteOffset_ = kSpanKeepOffset)
const {
789 super_type::template populateSubspan<NewValueType>(span, index, numEntries);
797 if (sourceByteOffset_ == kSpanKeepOffset) {
798 span._sourceByteOffset = _sourceByteOffset + index *
sizeof(value_type);
800 span._sourceByteOffset = sourceByteOffset_;
805 #pragma mark NamedSpanImpl - Validation 808 String getValidationMessage(
const index_type index,
const difference_type deltaInBytes,
const SpanValidationMode mode)
const {
809 const index_type indexInBytes = index *
sizeof(value_type);
810 const size_type maxSizeInBytes = this->impl().byteSize();
812 return super_type::getValidationMessage(index, deltaInBytes, mode) +
814 this->impl().sourceByteOffset() + indexInBytes,
816 this->impl().sourceByteOffset() + maxSizeInBytes);
820 #pragma mark NamedSpanImpl - Allocation 823 typedef typename RemoveConst<value_type>::type mutable_value_type;
824 typedef Derived<mutable_value_type> mutable_value_derived_type;
827 mutable_value_derived_type &allocate(
const size_type numEntries,
const String &name_ =
String()) {
828 super_type::allocate(numEntries);
830 _sourceByteOffset = 0;
831 return (mutable_value_derived_type &)
const_cast<Derived<value_type> &
>(this->impl());
834 template <
typename OtherValueType>
836 super_type::allocateFromSpan(other);
837 _name = other.name();
838 _sourceByteOffset = other.sourceByteOffset();
839 return (mutable_value_derived_type &)
const_cast<Derived<value_type> &
>(this->impl());
842 template <
typename OtherValueType,
template <
typename>
class OtherDerived>
844 super_type::allocateFromSpan(other);
845 return (mutable_value_derived_type &)
const_cast<Derived<value_type> &
>(this->impl());
849 super_type::allocateFromStream(stream, numEntries);
851 _sourceByteOffset = 0;
852 return (mutable_value_derived_type &)
const_cast<Derived<value_type> &
>(this->impl());
855 mutable_value_derived_type &allocateFromStream(
File &file,
const size_type numEntries = kSpanMaxSize) {
856 return allocateFromStream(file, numEntries, file.
getName());
861 #pragma mark NamedSpan 863 template <
typename ValueType>
867 template <
typename T>
friend class NamedSpan;
874 inline NamedSpan(
const pointer data_,
875 const size_type size_,
877 const size_type sourceByteOffset_ = 0) :
878 super_type(data_, size_, name_, sourceByteOffset_) {}
880 template <
typename Other>
881 inline NamedSpan(
const Other &other) : super_type(other) {}
885 #pragma mark SpanOwner 891 template <
typename OwnedSpan>
893 typedef typename OwnedSpan::value_type value_type;
894 typedef typename OwnedSpan::size_type size_type;
895 typedef typename OwnedSpan::index_type index_type;
896 typedef typename OwnedSpan::pointer pointer;
897 typedef typename OwnedSpan::reference reference;
898 typedef typename OwnedSpan::const_reference const_reference;
900 template <
typename T,
typename U>
friend struct SafeBool;
905 inline SpanOwner(
const OwnedSpan &span) : _span(span) {}
919 _span.allocateFromSpan(other._span);
923 if (
this == &other) {
927 delete[]
const_cast<typename RemoveConst<value_type>::type *
>(_span.data());
934 _span.allocateFromSpan(other._span);
941 delete[]
const_cast<typename RemoveConst<value_type>::type *
>(_span.data());
948 if (
this == &other) {
952 delete[]
const_cast<typename RemoveConst<value_type>::type *
>(_span.data());
962 pointer data = _span.data();
971 delete[]
const_cast<typename RemoveConst<value_type>::type *
>(_span.data());
975 #if !defined(_MSC_VER) 978 inline bool operator_bool()
const {
return _span; }
984 #pragma mark SpanOwner - Data access 987 inline const OwnedSpan &operator*()
const {
return _span; }
988 inline OwnedSpan &operator*() {
return _span; }
990 inline const OwnedSpan *operator->()
const {
return &_span; }
991 inline OwnedSpan *operator->() {
return &_span; }
993 inline const_reference operator[](
const index_type index)
const {
return _span[index]; }
994 inline reference operator[](
const index_type index) {
return _span[index]; }
bool checkInvalidBounds(const index_type index, const difference_type deltaInBytes) const
Definition: span.h:512
virtual int64 size() const =0
virtual int64 pos() const =0
void unsafeCopyDataTo(void *target) const
Definition: span.h:488
void clear()
Definition: span.h:970
static String format(MSVC_PRINTF const char *fmt,...) GCC_PRINTF(1
void copyDataTo(Other &target) const
Definition: span.h:497
pointer release()
Definition: span.h:961
Definition: type-traits.h:28
Out copy(In first, In last, Out dst)
Definition: algorithm.h:52
Definition: type-traits.h:30
const char * getName() const
Definition: file.h:126
Definition: algorithm.h:29
SpanOwner & moveFrom(SpanOwner &other)
Definition: span.h:947
Definition: memstream.h:43
void NORETURN_PRE error(MSVC_PRINTF const char *s,...) GCC_PRINTF(1
SpanOwner(const SpanOwner &other)
Definition: span.h:910
Definition: safe-bool.h:56
size_t strnlen(const char *src, size_t maxSize)
const_pointer getUnsafeDataAt(const index_type index, size_type numEntries=kSpanMaxSize) const
Definition: span.h:409
virtual uint32 read(void *dataPtr, uint32 dataSize)=0