1 // Copyright 2017 The Android Open Source Project
2 //
3 // This software is licensed under the terms of the GNU General Public
4 // License version 2, as published by the Free Software Foundation, and
5 // may be copied, distributed, and modified under those terms.
6 //
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License for more details.
11
12 #pragma once
13
14 #include "android/base/containers/SmallVector.h"
15 #include "android/base/files/MemStream.h"
16 #include "android/base/files/Stream.h"
17 #include "android/base/TypeTraits.h"
18
19 #include <string>
20 #include <vector>
21
22 namespace android {
23 namespace base {
24
25 //
26 // Save/load operations for different types.
27 //
28
29 void saveStream(Stream* stream, const MemStream& memStream);
30 void loadStream(Stream* stream, MemStream* memStream);
31
32 void saveBufferRaw(Stream* stream, char* buffer, uint32_t len);
33 bool loadBufferRaw(Stream* stream, char* buffer);
34
35 template <class T, class = enable_if<std::is_standard_layout<T>>>
saveBuffer(Stream * stream,const std::vector<T> & buffer)36 void saveBuffer(Stream* stream, const std::vector<T>& buffer) {
37 stream->putBe32(buffer.size());
38 stream->write(buffer.data(), sizeof(T) * buffer.size());
39 }
40
41 template <class T, class = enable_if<std::is_standard_layout<T>>>
loadBuffer(Stream * stream,std::vector<T> * buffer)42 bool loadBuffer(Stream* stream, std::vector<T>* buffer) {
43 auto len = stream->getBe32();
44 buffer->resize(len);
45 int ret = (int)stream->read(buffer->data(), len * sizeof(T));
46 return ret == len * sizeof(T);
47 }
48
49 template <class T, class = enable_if<std::is_standard_layout<T>>>
saveBuffer(Stream * stream,const SmallVector<T> & buffer)50 void saveBuffer(Stream* stream, const SmallVector<T>& buffer) {
51 stream->putBe32(buffer.size());
52 stream->write(buffer.data(), sizeof(T) * buffer.size());
53 }
54
55 template <class T, class = enable_if<std::is_standard_layout<T>>>
loadBuffer(Stream * stream,SmallVector<T> * buffer)56 bool loadBuffer(Stream* stream, SmallVector<T>* buffer) {
57 auto len = stream->getBe32();
58 buffer->clear();
59 buffer->resize_noinit(len);
60 int ret = (int)stream->read(buffer->data(), len * sizeof(T));
61 return ret == len * sizeof(T);
62 }
63
64 template <class T, class SaveFunc>
saveBuffer(Stream * stream,const std::vector<T> & buffer,SaveFunc && saver)65 void saveBuffer(Stream* stream, const std::vector<T>& buffer, SaveFunc&& saver) {
66 stream->putBe32(buffer.size());
67 for (const auto& val : buffer) {
68 saver(stream, val);
69 }
70 }
71
72 template <class T>
saveBuffer(Stream * stream,const T * buffer,size_t numElts)73 void saveBuffer(Stream* stream, const T* buffer, size_t numElts) {
74 stream->putBe32(numElts);
75 stream->write(buffer, sizeof(T) * numElts);
76 }
77
78 template <class T>
loadBufferPtr(Stream * stream,T * out)79 void loadBufferPtr(Stream* stream, T* out) {
80 auto len = stream->getBe32();
81 stream->read(out, len * sizeof(T));
82 }
83
84 template <class T, class LoadFunc>
loadBuffer(Stream * stream,std::vector<T> * buffer,LoadFunc && loader)85 void loadBuffer(Stream* stream, std::vector<T>* buffer, LoadFunc&& loader) {
86 auto len = stream->getBe32();
87 buffer->clear();
88 buffer->reserve(len);
89 for (uint32_t i = 0; i < len; i++) {
90 buffer->emplace_back(loader(stream));
91 }
92 }
93
94 template <class Collection, class SaveFunc>
saveCollection(Stream * stream,const Collection & c,SaveFunc && saver)95 void saveCollection(Stream* stream, const Collection& c, SaveFunc&& saver) {
96 stream->putBe32(c.size());
97 for (const auto& val : c) {
98 saver(stream, val);
99 }
100 }
101
102 template <class Collection, class LoadFunc>
loadCollection(Stream * stream,Collection * c,LoadFunc && loader)103 void loadCollection(Stream* stream, Collection* c, LoadFunc&& loader) {
104 const int size = stream->getBe32();
105 for (int i = 0; i < size; ++i) {
106 c->emplace(loader(stream));
107 }
108 }
109
110 void saveStringArray(Stream* stream, const char* const* strings, uint32_t count);
111 std::vector<std::string> loadStringArray(Stream* stream);
112
113 } // namespace base
114 } // namespace android
115