typedef ArenaArray Serializer; force_inline Serializer* new_serializer (Arena_Reserve new_reserve) { return arena_array_new(1, new_reserve); } force_inline void reset_serializer (Serializer* serializer) { #if BUILD_DEBUG array_poison_range(*serializer, 0, serializer->count); #endif reset_keeping_memory(*serializer); } force_inline void free_serializer (Serializer* serializer) { arena_array_free(*serializer); } // force_inline ArrayView to_view (Serializer* serializer); // #redundant, just call to_view (ArenaArray&) force_inline s64 count_bytes (Serializer* serializer) { return serializer->count; } template force_inline void Add (Serializer* serializer, T item) { u8* current_point = &serializer->data[serializer->count]; s64 final_count = serializer->allocated + sizeof(T); if (serializer->allocated < final_count) { array_reserve(*serializer, final_count); } memcpy(current_point, &item, sizeof(T)); serializer->count += sizeof(T); } template force_inline void AddArray_NoSize (Serializer* serializer, ArrayView view) { u8* current_point = &serializer->data[serializer->count]; s64 final_count = serializer->allocated + (view.count * sizeof(T)); if (serializer->allocated < final_count) { array_reserve(*serializer, final_count); } memcpy(current_point, view.data, view.count * sizeof(T)); serializer->count += view.count * sizeof(T); } template force_inline void AddArray (Serializer* serializer, ArrayView view) { Add(serializer, view.count); AddArray_NoSize(serializer, view); } force_inline void AddString (Serializer* serializer, string s) { Add(serializer, s.count); AddArray_NoSize(serializer, to_view(s)); } force_inline void AddString32 (Serializer* serializer, string s) { u32 string_length = (u32)s.count; Add(serializer, string_length); AddArray_NoSize(serializer, to_view(s)); } force_inline void AddString16 (Serializer* serializer, string s) { u16 string_length = (u16)s.count; Add(serializer, string_length); AddArray_NoSize(serializer, to_view(s)); } struct Deserializer { // #downcasts to ArrayView s64 count; u8* data; s64 cursor; Deserializer (ArrayView view) { count = view.count; data = view.data; cursor = 0; } }; template force_inline void Read (Deserializer* ds, T* item) { u8* current_point = &ds->data[ds->cursor]; memcpy(item, current_point, sizeof(T)); ds->cursor += sizeof(T); } template force_inline void ReadArrayView (Deserializer* ds, ArrayView& view, s64 view_count) { view.count = view_count; view.data = (T*)&ds->data[ds->cursor]; ds->cursor += (view_count * sizeof(T)); } // Here array should be allocated and have a non-zero count! template force_inline void ReadArray (Deserializer* ds, ArrayView view) { u8* current_point = &ds->data[ds->cursor]; memcpy(view.data, current_point, view.count * sizeof(T)); ds->cursor += view.count * sizeof(T); } template force_inline ArrayView ReadSizedArray (Deserializer* ds) { // #allocates ArrayView array; Read(ds, &array.count); array.data = NewArray(array.count, false); ReadArray(ds, array); return array; } template void ReadToArenaArray (Deserializer* ds, ArenaArray* aa) { ArrayView temp; Read(ds, &temp.count); ReadArrayView(ds, temp, temp.count); copy_from_view(aa, temp); } force_inline void ReadStringView (Deserializer* ds, string& sv, s64 view_count) { sv.count = view_count; sv.data = &ds->data[ds->cursor]; ds->cursor += view_count; } force_inline void ReadString (Deserializer* ds, string& s) { // #no_alloc Read(ds, &s.count); ReadStringView(ds, s, s.count); } force_inline void ReadString32 (Deserializer* ds, string& s) { // #no_alloc u32 str_len = 0; Read(ds, &str_len); ReadStringView(ds, s, (s64)str_len); } force_inline void ReadString16 (Deserializer* ds, string& s) { // #no_alloc u16 str_len = 0; Read(ds, &str_len); ReadStringView(ds, s, (s64)str_len); } // This is specialized for filesystem storage of strings. force_inline u32 AddString_NoCount (Serializer* serializer, u8* data, s16 count) { u32 original_count = (u32)serializer->count; u8* current_point = &serializer->data[original_count]; s64 final_count = serializer->allocated + (count * sizeof(u8)); if (serializer->allocated < final_count) { array_reserve(*serializer, final_count); } memcpy(current_point, data, count * sizeof(u8)); serializer->count += count * sizeof(u8); return original_count; }