1 | // Copyright (c) 2010, Google Inc. |
2 | // All rights reserved. |
3 | // |
4 | // Redistribution and use in source and binary forms, with or without |
5 | // modification, are permitted provided that the following conditions are |
6 | // met: |
7 | // |
8 | // * Redistributions of source code must retain the above copyright |
9 | // notice, this list of conditions and the following disclaimer. |
10 | // * Redistributions in binary form must reproduce the above |
11 | // copyright notice, this list of conditions and the following disclaimer |
12 | // in the documentation and/or other materials provided with the |
13 | // distribution. |
14 | // * Neither the name of Google Inc. nor the names of its |
15 | // contributors may be used to endorse or promote products derived from |
16 | // this software without specific prior written permission. |
17 | // |
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | // |
30 | // map_serializers_inl.h: implementation for serializing std::map and its |
31 | // wrapper classes. |
32 | // |
33 | // See map_serializers.h for documentation. |
34 | // |
35 | // Author: Siyang Xie (lambxsy@google.com) |
36 | |
37 | #ifndef PROCESSOR_MAP_SERIALIZERS_INL_H__ |
38 | #define PROCESSOR_MAP_SERIALIZERS_INL_H__ |
39 | |
40 | #include <map> |
41 | #include <string> |
42 | |
43 | #include "processor/map_serializers.h" |
44 | #include "processor/simple_serializer.h" |
45 | |
46 | #include "processor/address_map-inl.h" |
47 | #include "processor/range_map-inl.h" |
48 | #include "processor/contained_range_map-inl.h" |
49 | |
50 | #include "processor/logging.h" |
51 | |
52 | namespace google_breakpad { |
53 | |
54 | template<typename Key, typename Value> |
55 | size_t StdMapSerializer<Key, Value>::SizeOf( |
56 | const std::map<Key, Value>& m) const { |
57 | size_t size = 0; |
58 | size_t = (1 + m.size()) * sizeof(uint32_t); |
59 | size += header_size; |
60 | |
61 | typename std::map<Key, Value>::const_iterator iter; |
62 | for (iter = m.begin(); iter != m.end(); ++iter) { |
63 | size += key_serializer_.SizeOf(iter->first); |
64 | size += value_serializer_.SizeOf(iter->second); |
65 | } |
66 | return size; |
67 | } |
68 | |
69 | template<typename Key, typename Value> |
70 | char* StdMapSerializer<Key, Value>::Write(const std::map<Key, Value>& m, |
71 | char* dest) const { |
72 | if (!dest) { |
73 | BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address." ; |
74 | return NULL; |
75 | } |
76 | char* start_address = dest; |
77 | |
78 | // Write header: |
79 | // Number of nodes. |
80 | dest = SimpleSerializer<uint32_t>::Write(m.size(), dest); |
81 | // Nodes offsets. |
82 | uint32_t* offsets = reinterpret_cast<uint32_t*>(dest); |
83 | dest += sizeof(uint32_t) * m.size(); |
84 | |
85 | char* key_address = dest; |
86 | dest += sizeof(Key) * m.size(); |
87 | |
88 | // Traverse map. |
89 | typename std::map<Key, Value>::const_iterator iter; |
90 | int index = 0; |
91 | for (iter = m.begin(); iter != m.end(); ++iter, ++index) { |
92 | offsets[index] = static_cast<uint32_t>(dest - start_address); |
93 | key_address = key_serializer_.Write(iter->first, key_address); |
94 | dest = value_serializer_.Write(iter->second, dest); |
95 | } |
96 | return dest; |
97 | } |
98 | |
99 | template<typename Key, typename Value> |
100 | char* StdMapSerializer<Key, Value>::Serialize( |
101 | const std::map<Key, Value>& m, unsigned int* size) const { |
102 | // Compute size of memory to be allocated. |
103 | unsigned int size_to_alloc = SizeOf(m); |
104 | // Allocate memory. |
105 | char* serialized_data = new char[size_to_alloc]; |
106 | if (!serialized_data) { |
107 | BPLOG(INFO) << "StdMapSerializer memory allocation failed." ; |
108 | if (size) *size = 0; |
109 | return NULL; |
110 | } |
111 | // Write serialized data into memory. |
112 | Write(m, serialized_data); |
113 | |
114 | if (size) *size = size_to_alloc; |
115 | return serialized_data; |
116 | } |
117 | |
118 | template<typename Address, typename Entry> |
119 | size_t RangeMapSerializer<Address, Entry>::SizeOf( |
120 | const RangeMap<Address, Entry>& m) const { |
121 | size_t size = 0; |
122 | size_t = (1 + m.map_.size()) * sizeof(uint32_t); |
123 | size += header_size; |
124 | |
125 | typename std::map<Address, Range>::const_iterator iter; |
126 | for (iter = m.map_.begin(); iter != m.map_.end(); ++iter) { |
127 | // Size of key (high address). |
128 | size += address_serializer_.SizeOf(iter->first); |
129 | // Size of base (low address). |
130 | size += address_serializer_.SizeOf(iter->second.base()); |
131 | // Size of entry. |
132 | size += entry_serializer_.SizeOf(iter->second.entry()); |
133 | } |
134 | return size; |
135 | } |
136 | |
137 | template<typename Address, typename Entry> |
138 | char* RangeMapSerializer<Address, Entry>::Write( |
139 | const RangeMap<Address, Entry>& m, char* dest) const { |
140 | if (!dest) { |
141 | BPLOG(ERROR) << "RangeMapSerializer failed: write to NULL address." ; |
142 | return NULL; |
143 | } |
144 | char* start_address = dest; |
145 | |
146 | // Write header: |
147 | // Number of nodes. |
148 | dest = SimpleSerializer<uint32_t>::Write(m.map_.size(), dest); |
149 | // Nodes offsets. |
150 | uint32_t* offsets = reinterpret_cast<uint32_t*>(dest); |
151 | dest += sizeof(uint32_t) * m.map_.size(); |
152 | |
153 | char* key_address = dest; |
154 | dest += sizeof(Address) * m.map_.size(); |
155 | |
156 | // Traverse map. |
157 | typename std::map<Address, Range>::const_iterator iter; |
158 | int index = 0; |
159 | for (iter = m.map_.begin(); iter != m.map_.end(); ++iter, ++index) { |
160 | offsets[index] = static_cast<uint32_t>(dest - start_address); |
161 | key_address = address_serializer_.Write(iter->first, key_address); |
162 | dest = address_serializer_.Write(iter->second.base(), dest); |
163 | dest = entry_serializer_.Write(iter->second.entry(), dest); |
164 | } |
165 | return dest; |
166 | } |
167 | |
168 | template<typename Address, typename Entry> |
169 | char* RangeMapSerializer<Address, Entry>::Serialize( |
170 | const RangeMap<Address, Entry>& m, unsigned int* size) const { |
171 | // Compute size of memory to be allocated. |
172 | unsigned int size_to_alloc = SizeOf(m); |
173 | // Allocate memory. |
174 | char* serialized_data = new char[size_to_alloc]; |
175 | if (!serialized_data) { |
176 | BPLOG(INFO) << "RangeMapSerializer memory allocation failed." ; |
177 | if (size) *size = 0; |
178 | return NULL; |
179 | } |
180 | |
181 | // Write serialized data into memory. |
182 | Write(m, serialized_data); |
183 | |
184 | if (size) *size = size_to_alloc; |
185 | return serialized_data; |
186 | } |
187 | |
188 | |
189 | template<class AddrType, class EntryType> |
190 | size_t ContainedRangeMapSerializer<AddrType, EntryType>::SizeOf( |
191 | const ContainedRangeMap<AddrType, EntryType>* m) const { |
192 | size_t size = 0; |
193 | size_t = addr_serializer_.SizeOf(m->base_) |
194 | + entry_serializer_.SizeOf(m->entry_) |
195 | + sizeof(uint32_t); |
196 | size += header_size; |
197 | // In case m.map_ == NULL, we treat it as an empty map: |
198 | size += sizeof(uint32_t); |
199 | if (m->map_) { |
200 | size += m->map_->size() * sizeof(uint32_t); |
201 | typename Map::const_iterator iter; |
202 | for (iter = m->map_->begin(); iter != m->map_->end(); ++iter) { |
203 | size += addr_serializer_.SizeOf(iter->first); |
204 | // Recursive calculation of size: |
205 | size += SizeOf(iter->second); |
206 | } |
207 | } |
208 | return size; |
209 | } |
210 | |
211 | template<class AddrType, class EntryType> |
212 | char* ContainedRangeMapSerializer<AddrType, EntryType>::Write( |
213 | const ContainedRangeMap<AddrType, EntryType>* m, char* dest) const { |
214 | if (!dest) { |
215 | BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address." ; |
216 | return NULL; |
217 | } |
218 | dest = addr_serializer_.Write(m->base_, dest); |
219 | dest = SimpleSerializer<uint32_t>::Write(entry_serializer_.SizeOf(m->entry_), |
220 | dest); |
221 | dest = entry_serializer_.Write(m->entry_, dest); |
222 | |
223 | // Write map<<AddrType, ContainedRangeMap*>: |
224 | char* map_address = dest; |
225 | if (m->map_ == NULL) { |
226 | dest = SimpleSerializer<uint32_t>::Write(0, dest); |
227 | } else { |
228 | dest = SimpleSerializer<uint32_t>::Write(m->map_->size(), dest); |
229 | uint32_t* offsets = reinterpret_cast<uint32_t*>(dest); |
230 | dest += sizeof(uint32_t) * m->map_->size(); |
231 | |
232 | char* key_address = dest; |
233 | dest += sizeof(AddrType) * m->map_->size(); |
234 | |
235 | // Traverse map. |
236 | typename Map::const_iterator iter; |
237 | int index = 0; |
238 | for (iter = m->map_->begin(); iter != m->map_->end(); ++iter, ++index) { |
239 | offsets[index] = static_cast<uint32_t>(dest - map_address); |
240 | key_address = addr_serializer_.Write(iter->first, key_address); |
241 | // Recursively write. |
242 | dest = Write(iter->second, dest); |
243 | } |
244 | } |
245 | return dest; |
246 | } |
247 | |
248 | template<class AddrType, class EntryType> |
249 | char* ContainedRangeMapSerializer<AddrType, EntryType>::Serialize( |
250 | const ContainedRangeMap<AddrType, EntryType>* m, unsigned int* size) const { |
251 | unsigned int size_to_alloc = SizeOf(m); |
252 | // Allocating memory. |
253 | char* serialized_data = new char[size_to_alloc]; |
254 | if (!serialized_data) { |
255 | BPLOG(INFO) << "ContainedRangeMapSerializer memory allocation failed." ; |
256 | if (size) *size = 0; |
257 | return NULL; |
258 | } |
259 | Write(m, serialized_data); |
260 | if (size) *size = size_to_alloc; |
261 | return serialized_data; |
262 | } |
263 | |
264 | } // namespace google_breakpad |
265 | |
266 | #endif // PROCESSOR_MAP_SERIALIZERS_INL_H__ |
267 | |