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 (at) 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 header_size = (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 header_size = (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 header_size = 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