1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/processor/map_serializers-inl.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,266 @@ 1.4 +// Copyright (c) 2010, Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 +// 1.33 +// map_serializers_inl.h: implementation for serializing std::map and its 1.34 +// wrapper classes. 1.35 +// 1.36 +// See map_serializers.h for documentation. 1.37 +// 1.38 +// Author: Siyang Xie (lambxsy@google.com) 1.39 + 1.40 +#ifndef PROCESSOR_MAP_SERIALIZERS_INL_H__ 1.41 +#define PROCESSOR_MAP_SERIALIZERS_INL_H__ 1.42 + 1.43 +#include <map> 1.44 +#include <string> 1.45 + 1.46 +#include "processor/map_serializers.h" 1.47 +#include "processor/simple_serializer.h" 1.48 + 1.49 +#include "processor/address_map-inl.h" 1.50 +#include "processor/range_map-inl.h" 1.51 +#include "processor/contained_range_map-inl.h" 1.52 + 1.53 +#include "processor/logging.h" 1.54 + 1.55 +namespace google_breakpad { 1.56 + 1.57 +template<typename Key, typename Value> 1.58 +size_t StdMapSerializer<Key, Value>::SizeOf( 1.59 + const std::map<Key, Value> &m) const { 1.60 + size_t size = 0; 1.61 + size_t header_size = (1 + m.size()) * sizeof(uint32_t); 1.62 + size += header_size; 1.63 + 1.64 + typename std::map<Key, Value>::const_iterator iter; 1.65 + for (iter = m.begin(); iter != m.end(); ++iter) { 1.66 + size += key_serializer_.SizeOf(iter->first); 1.67 + size += value_serializer_.SizeOf(iter->second); 1.68 + } 1.69 + return size; 1.70 +} 1.71 + 1.72 +template<typename Key, typename Value> 1.73 +char *StdMapSerializer<Key, Value>::Write(const std::map<Key, Value> &m, 1.74 + char *dest) const { 1.75 + if (!dest) { 1.76 + BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address."; 1.77 + return NULL; 1.78 + } 1.79 + char *start_address = dest; 1.80 + 1.81 + // Write header: 1.82 + // Number of nodes. 1.83 + dest = SimpleSerializer<uint32_t>::Write(m.size(), dest); 1.84 + // Nodes offsets. 1.85 + uint32_t *offsets = reinterpret_cast<uint32_t*>(dest); 1.86 + dest += sizeof(uint32_t) * m.size(); 1.87 + 1.88 + char *key_address = dest; 1.89 + dest += sizeof(Key) * m.size(); 1.90 + 1.91 + // Traverse map. 1.92 + typename std::map<Key, Value>::const_iterator iter; 1.93 + int index = 0; 1.94 + for (iter = m.begin(); iter != m.end(); ++iter, ++index) { 1.95 + offsets[index] = static_cast<uint32_t>(dest - start_address); 1.96 + key_address = key_serializer_.Write(iter->first, key_address); 1.97 + dest = value_serializer_.Write(iter->second, dest); 1.98 + } 1.99 + return dest; 1.100 +} 1.101 + 1.102 +template<typename Key, typename Value> 1.103 +char *StdMapSerializer<Key, Value>::Serialize( 1.104 + const std::map<Key, Value> &m, unsigned int *size) const { 1.105 + // Compute size of memory to be allocated. 1.106 + unsigned int size_to_alloc = SizeOf(m); 1.107 + // Allocate memory. 1.108 + char *serialized_data = new char[size_to_alloc]; 1.109 + if (!serialized_data) { 1.110 + BPLOG(INFO) << "StdMapSerializer memory allocation failed."; 1.111 + if (size) *size = 0; 1.112 + return NULL; 1.113 + } 1.114 + // Write serialized data into memory. 1.115 + Write(m, serialized_data); 1.116 + 1.117 + if (size) *size = size_to_alloc; 1.118 + return serialized_data; 1.119 +} 1.120 + 1.121 +template<typename Address, typename Entry> 1.122 +size_t RangeMapSerializer<Address, Entry>::SizeOf( 1.123 + const RangeMap<Address, Entry> &m) const { 1.124 + size_t size = 0; 1.125 + size_t header_size = (1 + m.map_.size()) * sizeof(uint32_t); 1.126 + size += header_size; 1.127 + 1.128 + typename std::map<Address, Range>::const_iterator iter; 1.129 + for (iter = m.map_.begin(); iter != m.map_.end(); ++iter) { 1.130 + // Size of key (high address). 1.131 + size += address_serializer_.SizeOf(iter->first); 1.132 + // Size of base (low address). 1.133 + size += address_serializer_.SizeOf(iter->second.base()); 1.134 + // Size of entry. 1.135 + size += entry_serializer_.SizeOf(iter->second.entry()); 1.136 + } 1.137 + return size; 1.138 +} 1.139 + 1.140 +template<typename Address, typename Entry> 1.141 +char *RangeMapSerializer<Address, Entry>::Write( 1.142 + const RangeMap<Address, Entry> &m, char *dest) const { 1.143 + if (!dest) { 1.144 + BPLOG(ERROR) << "RangeMapSerializer failed: write to NULL address."; 1.145 + return NULL; 1.146 + } 1.147 + char *start_address = dest; 1.148 + 1.149 + // Write header: 1.150 + // Number of nodes. 1.151 + dest = SimpleSerializer<uint32_t>::Write(m.map_.size(), dest); 1.152 + // Nodes offsets. 1.153 + uint32_t *offsets = reinterpret_cast<uint32_t*>(dest); 1.154 + dest += sizeof(uint32_t) * m.map_.size(); 1.155 + 1.156 + char *key_address = dest; 1.157 + dest += sizeof(Address) * m.map_.size(); 1.158 + 1.159 + // Traverse map. 1.160 + typename std::map<Address, Range>::const_iterator iter; 1.161 + int index = 0; 1.162 + for (iter = m.map_.begin(); iter != m.map_.end(); ++iter, ++index) { 1.163 + offsets[index] = static_cast<uint32_t>(dest - start_address); 1.164 + key_address = address_serializer_.Write(iter->first, key_address); 1.165 + dest = address_serializer_.Write(iter->second.base(), dest); 1.166 + dest = entry_serializer_.Write(iter->second.entry(), dest); 1.167 + } 1.168 + return dest; 1.169 +} 1.170 + 1.171 +template<typename Address, typename Entry> 1.172 +char *RangeMapSerializer<Address, Entry>::Serialize( 1.173 + const RangeMap<Address, Entry> &m, unsigned int *size) const { 1.174 + // Compute size of memory to be allocated. 1.175 + unsigned int size_to_alloc = SizeOf(m); 1.176 + // Allocate memory. 1.177 + char *serialized_data = new char[size_to_alloc]; 1.178 + if (!serialized_data) { 1.179 + BPLOG(INFO) << "RangeMapSerializer memory allocation failed."; 1.180 + if (size) *size = 0; 1.181 + return NULL; 1.182 + } 1.183 + 1.184 + // Write serialized data into memory. 1.185 + Write(m, serialized_data); 1.186 + 1.187 + if (size) *size = size_to_alloc; 1.188 + return serialized_data; 1.189 +} 1.190 + 1.191 + 1.192 +template<class AddrType, class EntryType> 1.193 +size_t ContainedRangeMapSerializer<AddrType, EntryType>::SizeOf( 1.194 + const ContainedRangeMap<AddrType, EntryType> *m) const { 1.195 + size_t size = 0; 1.196 + size_t header_size = addr_serializer_.SizeOf(m->base_) 1.197 + + entry_serializer_.SizeOf(m->entry_) 1.198 + + sizeof(uint32_t); 1.199 + size += header_size; 1.200 + // In case m.map_ == NULL, we treat it as an empty map: 1.201 + size += sizeof(uint32_t); 1.202 + if (m->map_) { 1.203 + size += m->map_->size() * sizeof(uint32_t); 1.204 + typename Map::const_iterator iter; 1.205 + for (iter = m->map_->begin(); iter != m->map_->end(); ++iter) { 1.206 + size += addr_serializer_.SizeOf(iter->first); 1.207 + // Recursive calculation of size: 1.208 + size += SizeOf(iter->second); 1.209 + } 1.210 + } 1.211 + return size; 1.212 +} 1.213 + 1.214 +template<class AddrType, class EntryType> 1.215 +char *ContainedRangeMapSerializer<AddrType, EntryType>::Write( 1.216 + const ContainedRangeMap<AddrType, EntryType> *m, char *dest) const { 1.217 + if (!dest) { 1.218 + BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address."; 1.219 + return NULL; 1.220 + } 1.221 + dest = addr_serializer_.Write(m->base_, dest); 1.222 + dest = SimpleSerializer<uint32_t>::Write(entry_serializer_.SizeOf(m->entry_), 1.223 + dest); 1.224 + dest = entry_serializer_.Write(m->entry_, dest); 1.225 + 1.226 + // Write map<<AddrType, ContainedRangeMap*>: 1.227 + char *map_address = dest; 1.228 + if (m->map_ == NULL) { 1.229 + dest = SimpleSerializer<uint32_t>::Write(0, dest); 1.230 + } else { 1.231 + dest = SimpleSerializer<uint32_t>::Write(m->map_->size(), dest); 1.232 + uint32_t *offsets = reinterpret_cast<uint32_t*>(dest); 1.233 + dest += sizeof(uint32_t) * m->map_->size(); 1.234 + 1.235 + char *key_address = dest; 1.236 + dest += sizeof(AddrType) * m->map_->size(); 1.237 + 1.238 + // Traverse map. 1.239 + typename Map::const_iterator iter; 1.240 + int index = 0; 1.241 + for (iter = m->map_->begin(); iter != m->map_->end(); ++iter, ++index) { 1.242 + offsets[index] = static_cast<uint32_t>(dest - map_address); 1.243 + key_address = addr_serializer_.Write(iter->first, key_address); 1.244 + // Recursively write. 1.245 + dest = Write(iter->second, dest); 1.246 + } 1.247 + } 1.248 + return dest; 1.249 +} 1.250 + 1.251 +template<class AddrType, class EntryType> 1.252 +char *ContainedRangeMapSerializer<AddrType, EntryType>::Serialize( 1.253 + const ContainedRangeMap<AddrType, EntryType> *m, unsigned int *size) const { 1.254 + unsigned int size_to_alloc = SizeOf(m); 1.255 + // Allocating memory. 1.256 + char *serialized_data = new char[size_to_alloc]; 1.257 + if (!serialized_data) { 1.258 + BPLOG(INFO) << "ContainedRangeMapSerializer memory allocation failed."; 1.259 + if (size) *size = 0; 1.260 + return NULL; 1.261 + } 1.262 + Write(m, serialized_data); 1.263 + if (size) *size = size_to_alloc; 1.264 + return serialized_data; 1.265 +} 1.266 + 1.267 +} // namespace google_breakpad 1.268 + 1.269 +#endif // PROCESSOR_MAP_SERIALIZERS_INL_H__