typedef ArenaArray Serializer; force_inline Serializer* new_serializer (Arena_Reserve new_reserve=Arena_Reserve::Size_2G); force_inline void reset_serializer (Serializer* serializer); force_inline void free_serializer (Serializer* serializer); // force_inline ArrayView to_view (Serializer* serializer); #redundant, just call to_view (ArenaArray&) 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 = &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; } 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); } // ReadString_MakeCopy...