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