28#ifndef OZZ_OZZ_BASE_IO_ARCHIVE_H_
29#define OZZ_OZZ_BASE_IO_ARCHIVE_H_
84#include "ozz/base/endianness.h"
85#include "ozz/base/io/archive_traits.h"
86#include "ozz/base/io/stream.h"
87#include "ozz/base/platform.h"
88#include "ozz/base/span.h"
96template <
typename _Ty,
97 bool _HasTag = internal::Tag<const _Ty>::kTagLength != 0>
110 Endianness _endianness = GetNativeEndianness());
113 bool endian_swap()
const {
return endian_swap_; }
116 size_t SaveBinary(
const void* _data,
size_t _size) {
117 return stream_->Write(_data, _size);
121 template <
typename _Ty>
122 void operator<<(
const _Ty& _ty) {
129#define OZZ_IO_PRIMITIVE_TYPE(_type) \
130 void operator<<(_type _v) { \
131 _type v = endian_swap_ ? EndianSwapper<_type>::Swap(_v) : _v; \
132 OZZ_IF_DEBUG(size_t size =) stream_->Write(&v, sizeof(v)); \
133 assert(size == sizeof(v)); \
136 OZZ_IO_PRIMITIVE_TYPE(
char)
137 OZZ_IO_PRIMITIVE_TYPE(int8_t)
138 OZZ_IO_PRIMITIVE_TYPE(uint8_t)
139 OZZ_IO_PRIMITIVE_TYPE(int16_t)
140 OZZ_IO_PRIMITIVE_TYPE(uint16_t)
141 OZZ_IO_PRIMITIVE_TYPE(int32_t)
142 OZZ_IO_PRIMITIVE_TYPE(uint32_t)
143 OZZ_IO_PRIMITIVE_TYPE(int64_t)
144 OZZ_IO_PRIMITIVE_TYPE(uint64_t)
145 OZZ_IO_PRIMITIVE_TYPE(
bool)
146 OZZ_IO_PRIMITIVE_TYPE(
float)
147#undef OZZ_IO_PRIMITIVE_TYPE
150 Stream* stream()
const {
return stream_; }
153 template <
typename _Ty>
182 bool endian_swap()
const {
return endian_swap_; }
185 size_t LoadBinary(
void* _data,
size_t _size) {
186 return stream_->Read(_data, _size);
190 template <
typename _Ty>
191 void operator>>(_Ty& _ty) {
194 assert(valid &&
"Type tag does not match archive content.");
197 uint32_t version = LoadVersion<_Ty>();
202#define OZZ_IO_PRIMITIVE_TYPE(_type) \
203 void operator>>(_type& _v) { \
205 OZZ_IF_DEBUG(size_t size =) stream_->Read(&v, sizeof(v)); \
206 assert(size == sizeof(v)); \
207 _v = endian_swap_ ? EndianSwapper<_type>::Swap(v) : v; \
210 OZZ_IO_PRIMITIVE_TYPE(
char)
211 OZZ_IO_PRIMITIVE_TYPE(int8_t)
212 OZZ_IO_PRIMITIVE_TYPE(uint8_t)
213 OZZ_IO_PRIMITIVE_TYPE(int16_t)
214 OZZ_IO_PRIMITIVE_TYPE(uint16_t)
215 OZZ_IO_PRIMITIVE_TYPE(int32_t)
216 OZZ_IO_PRIMITIVE_TYPE(uint32_t)
217 OZZ_IO_PRIMITIVE_TYPE(int64_t)
218 OZZ_IO_PRIMITIVE_TYPE(uint64_t)
219 OZZ_IO_PRIMITIVE_TYPE(
bool)
220 OZZ_IO_PRIMITIVE_TYPE(
float)
221#undef OZZ_IO_PRIMITIVE_TYPE
223 template <
typename _Ty>
228 "Tag unknown for type.");
230 const int tell = stream_->Tell();
232 stream_->Seek(tell, Stream::kSet);
237 Stream* stream()
const {
return stream_; }
240 template <
typename _Ty>
241 uint32_t LoadVersion() {
242 uint32_t version = 0;
257OZZ_IO_TYPE_NOT_VERSIONABLE(
char)
258OZZ_IO_TYPE_NOT_VERSIONABLE(int8_t)
259OZZ_IO_TYPE_NOT_VERSIONABLE(uint8_t)
260OZZ_IO_TYPE_NOT_VERSIONABLE(int16_t)
261OZZ_IO_TYPE_NOT_VERSIONABLE(uint16_t)
262OZZ_IO_TYPE_NOT_VERSIONABLE(int32_t)
263OZZ_IO_TYPE_NOT_VERSIONABLE(uint32_t)
264OZZ_IO_TYPE_NOT_VERSIONABLE(int64_t)
265OZZ_IO_TYPE_NOT_VERSIONABLE(uint64_t)
266OZZ_IO_TYPE_NOT_VERSIONABLE(
bool)
267OZZ_IO_TYPE_NOT_VERSIONABLE(
float)
270template <
typename _Ty>
272 inline static void Save(
OArchive& _archive,
const _Ty* _ty,
size_t _count) {
273 for (
size_t i = 0; i < _count; ++i) {
274 _ty[i].Save(_archive);
277 inline static void Load(
IArchive& _archive, _Ty* _ty,
size_t _count,
279 for (
size_t i = 0; i < _count; ++i) {
280 _ty[i].Load(_archive, _version);
288template <
typename _Ty>
290 OZZ_INLINE
void Save(
OArchive& _archive)
const {
293 OZZ_INLINE
void Load(
IArchive& _archive, uint32_t _version)
const {
300template <
typename _Ty>
302 OZZ_INLINE
void Save(
OArchive& _archive)
const {
311template <
typename _Ty>
317#define OZZ_IO_PRIMITIVE_TYPE(_type) \
319 inline void Array<const _type>::Save(OArchive& _archive) const { \
320 if (_archive.endian_swap()) { \
323 for (size_t i = 0; i < count; ++i) { \
324 _archive << array[i]; \
327 OZZ_IF_DEBUG(size_t size =) \
328 _archive.SaveBinary(array, count * sizeof(_type)); \
329 assert(size == count * sizeof(_type)); \
334 inline void Array<_type>::Save(OArchive& _archive) const { \
335 if (_archive.endian_swap()) { \
338 for (size_t i = 0; i < count; ++i) { \
339 _archive << array[i]; \
342 OZZ_IF_DEBUG(size_t size =) \
343 _archive.SaveBinary(array, count * sizeof(_type)); \
344 assert(size == count * sizeof(_type)); \
349 inline void Array<_type>::Load(IArchive& _archive, uint32_t ) \
351 OZZ_IF_DEBUG(size_t size =) \
352 _archive.LoadBinary(array, count * sizeof(_type)); \
353 assert(size == count * sizeof(_type)); \
354 if (_archive.endian_swap()) { \
355 EndianSwapper<_type>::Swap(array, count); \
359OZZ_IO_PRIMITIVE_TYPE(
char)
360OZZ_IO_PRIMITIVE_TYPE(int8_t)
361OZZ_IO_PRIMITIVE_TYPE(uint8_t)
362OZZ_IO_PRIMITIVE_TYPE(int16_t)
363OZZ_IO_PRIMITIVE_TYPE(uint16_t)
364OZZ_IO_PRIMITIVE_TYPE(int32_t)
365OZZ_IO_PRIMITIVE_TYPE(uint32_t)
366OZZ_IO_PRIMITIVE_TYPE(int64_t)
367OZZ_IO_PRIMITIVE_TYPE(uint64_t)
368OZZ_IO_PRIMITIVE_TYPE(
bool)
369OZZ_IO_PRIMITIVE_TYPE(
float)
370#undef OZZ_IO_PRIMITIVE_TYPE
374template <
typename _Ty>
379template <
typename _Ty>
380OZZ_INLINE
const internal::Array<const _Ty> MakeArray(
const _Ty* _array,
382 const internal::Array<const _Ty> array = {_array, _count};
385template <
typename _Ty>
386OZZ_INLINE
const internal::Array<_Ty> MakeArray(span<_Ty> _array) {
387 const internal::Array<_Ty> array = {_array.data(), _array.size()};
390template <
typename _Ty>
391OZZ_INLINE
const internal::Array<const _Ty> MakeArray(span<const _Ty> _array) {
392 const internal::Array<const _Ty> array = {_array.data(), _array.size()};
395template <
typename _Ty,
size_t _count>
396OZZ_INLINE
const internal::Array<_Ty> MakeArray(_Ty (&_array)[_count]) {
397 const internal::Array<_Ty> array = {_array, _count};
400template <
typename _Ty,
size_t _count>
401OZZ_INLINE
const internal::Array<const _Ty> MakeArray(
402 const _Ty (&_array)[_count]) {
403 const internal::Array<const _Ty> array = {_array, _count};
409template <
typename _Ty>
411 static void Write(
OArchive& _archive) {
413 OZZ_IF_DEBUG(
size_t size =)
414 _archive.SaveBinary(Tag::Get(), Tag::kTagLength);
415 assert(size == Tag::kTagLength);
417 static bool Validate(
IArchive& _archive) {
419 char buf[Tag::kTagLength];
420 if (Tag::kTagLength != _archive.LoadBinary(buf, Tag::kTagLength)) {
423 const char* tag = Tag::Get();
425 for (; i < Tag::kTagLength && buf[i] == tag[i]; ++i) {
427 return i == Tag::kTagLength;
432template <
typename _Ty>
435 static bool Validate(
IArchive& ) {
return true; }
Definition archive_traits.h:214
Definition archive_traits.h:210