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// simple_serializer-inl.h: template specializations for following types:
31// bool, const char *(C-string), string,
32// Line, Function, PublicSymbol, WindowsFrameInfo and their linked pointers.
33//
34// See simple_serializer.h for moredocumentation.
35//
36// Author: Siyang Xie (lambxsy@google.com)
37
38#ifndef PROCESSOR_SIMPLE_SERIALIZER_INL_H__
39#define PROCESSOR_SIMPLE_SERIALIZER_INL_H__
40
41#include <string>
42
43#include "processor/simple_serializer.h"
44#include "map_serializers-inl.h"
45
46#include "google_breakpad/processor/basic_source_line_resolver.h"
47#include "processor/basic_source_line_resolver_types.h"
48#include "processor/linked_ptr.h"
49#include "processor/windows_frame_info.h"
50
51namespace google_breakpad {
52
53// Specializations of SimpleSerializer: bool
54template<>
55class SimpleSerializer<bool> {
56 public:
57  static size_t SizeOf(bool boolean) { return 1; }
58
59  static char *Write(bool boolean, char *dest) {
60    *dest = static_cast<char>(boolean? 255 : 0);
61    return ++dest;
62  }
63
64  static const char *Read(const char *source, bool *value) {
65    *value = ((*source) == 0 ? false : true);
66    return ++source;
67  }
68};
69
70// Specializations of SimpleSerializer: string
71template<>
72class SimpleSerializer<string> {
73 public:
74  static size_t SizeOf(const string &str) { return str.size() + 1; }
75
76  static char *Write(const string &str, char *dest) {
77    strcpy(dest, str.c_str());
78    return dest + SizeOf(str);
79  }
80};
81
82// Specializations of SimpleSerializer: C-string
83template<>
84class SimpleSerializer<const char*> {
85 public:
86  static size_t SizeOf(const char *cstring) {
87    return strlen(cstring) + 1;
88  }
89
90  static char *Write(const char *cstring, char *dest) {
91    strcpy(dest, cstring);
92    return dest + SizeOf(cstring);
93  }
94};
95
96// Specializations of SimpleSerializer: Line
97template<>
98class SimpleSerializer<BasicSourceLineResolver::Line> {
99  typedef BasicSourceLineResolver::Line Line;
100 public:
101  static size_t SizeOf(const Line &line) {
102    return SimpleSerializer<MemAddr>::SizeOf(line.address)
103         + SimpleSerializer<MemAddr>::SizeOf(line.size)
104         + SimpleSerializer<int32_t>::SizeOf(line.source_file_id)
105         + SimpleSerializer<int32_t>::SizeOf(line.line);
106  }
107  static char *Write(const Line &line, char *dest) {
108    dest = SimpleSerializer<MemAddr>::Write(line.address, dest);
109    dest = SimpleSerializer<MemAddr>::Write(line.size, dest);
110    dest = SimpleSerializer<int32_t>::Write(line.source_file_id, dest);
111    dest = SimpleSerializer<int32_t>::Write(line.line, dest);
112    return dest;
113  }
114};
115
116// Specializations of SimpleSerializer: PublicSymbol
117template<>
118class SimpleSerializer<BasicSourceLineResolver::PublicSymbol> {
119  typedef BasicSourceLineResolver::PublicSymbol PublicSymbol;
120 public:
121  static size_t SizeOf(const PublicSymbol &pubsymbol) {
122    return SimpleSerializer<string>::SizeOf(pubsymbol.name)
123         + SimpleSerializer<MemAddr>::SizeOf(pubsymbol.address)
124         + SimpleSerializer<int32_t>::SizeOf(pubsymbol.parameter_size);
125  }
126  static char *Write(const PublicSymbol &pubsymbol, char *dest) {
127    dest = SimpleSerializer<string>::Write(pubsymbol.name, dest);
128    dest = SimpleSerializer<MemAddr>::Write(pubsymbol.address, dest);
129    dest = SimpleSerializer<int32_t>::Write(pubsymbol.parameter_size, dest);
130    return dest;
131  }
132};
133
134// Specializations of SimpleSerializer: WindowsFrameInfo
135template<>
136class SimpleSerializer<WindowsFrameInfo> {
137 public:
138  static size_t SizeOf(const WindowsFrameInfo &wfi) {
139    unsigned int size = 0;
140    size += sizeof(int32_t);  // wfi.type_
141    size += SimpleSerializer<int32_t>::SizeOf(wfi.valid);
142    size += SimpleSerializer<uint32_t>::SizeOf(wfi.prolog_size);
143    size += SimpleSerializer<uint32_t>::SizeOf(wfi.epilog_size);
144    size += SimpleSerializer<uint32_t>::SizeOf(wfi.parameter_size);
145    size += SimpleSerializer<uint32_t>::SizeOf(wfi.saved_register_size);
146    size += SimpleSerializer<uint32_t>::SizeOf(wfi.local_size);
147    size += SimpleSerializer<uint32_t>::SizeOf(wfi.max_stack_size);
148    size += SimpleSerializer<bool>::SizeOf(wfi.allocates_base_pointer);
149    size += SimpleSerializer<string>::SizeOf(wfi.program_string);
150    return size;
151  }
152  static char *Write(const WindowsFrameInfo &wfi, char *dest) {
153    dest = SimpleSerializer<int32_t>::Write(
154        static_cast<const int32_t>(wfi.type_), dest);
155    dest = SimpleSerializer<int32_t>::Write(wfi.valid, dest);
156    dest = SimpleSerializer<uint32_t>::Write(wfi.prolog_size, dest);
157    dest = SimpleSerializer<uint32_t>::Write(wfi.epilog_size, dest);
158    dest = SimpleSerializer<uint32_t>::Write(wfi.parameter_size, dest);
159    dest = SimpleSerializer<uint32_t>::Write(wfi.saved_register_size, dest);
160    dest = SimpleSerializer<uint32_t>::Write(wfi.local_size, dest);
161    dest = SimpleSerializer<uint32_t>::Write(wfi.max_stack_size, dest);
162    dest = SimpleSerializer<bool>::Write(wfi.allocates_base_pointer, dest);
163    return SimpleSerializer<string>::Write(wfi.program_string, dest);
164  }
165};
166
167// Specializations of SimpleSerializer: Linked_ptr version of
168// Line, Function, PublicSymbol, WindowsFrameInfo.
169template<>
170class SimpleSerializer< linked_ptr<BasicSourceLineResolver::Line> > {
171  typedef BasicSourceLineResolver::Line Line;
172 public:
173  static size_t SizeOf(const linked_ptr<Line> &lineptr) {
174    if (lineptr.get() == NULL) return 0;
175    return SimpleSerializer<Line>::SizeOf(*(lineptr.get()));
176  }
177  static char *Write(const linked_ptr<Line> &lineptr, char *dest) {
178    if (lineptr.get())
179      dest = SimpleSerializer<Line>::Write(*(lineptr.get()), dest);
180    return dest;
181  }
182};
183
184template<>
185class SimpleSerializer<BasicSourceLineResolver::Function> {
186  // Convenient type names.
187  typedef BasicSourceLineResolver::Function Function;
188  typedef BasicSourceLineResolver::Line Line;
189 public:
190  static size_t SizeOf(const Function &func) {
191    unsigned int size = 0;
192    size += SimpleSerializer<string>::SizeOf(func.name);
193    size += SimpleSerializer<MemAddr>::SizeOf(func.address);
194    size += SimpleSerializer<MemAddr>::SizeOf(func.size);
195    size += SimpleSerializer<int32_t>::SizeOf(func.parameter_size);
196    size += range_map_serializer_.SizeOf(func.lines);
197    return size;
198  }
199
200  static char *Write(const Function &func, char *dest) {
201    dest = SimpleSerializer<string>::Write(func.name, dest);
202    dest = SimpleSerializer<MemAddr>::Write(func.address, dest);
203    dest = SimpleSerializer<MemAddr>::Write(func.size, dest);
204    dest = SimpleSerializer<int32_t>::Write(func.parameter_size, dest);
205    dest = range_map_serializer_.Write(func.lines, dest);
206    return dest;
207  }
208 private:
209  // This static member is defined in module_serializer.cc.
210  static RangeMapSerializer< MemAddr, linked_ptr<Line> > range_map_serializer_;
211};
212
213template<>
214class SimpleSerializer< linked_ptr<BasicSourceLineResolver::Function> > {
215  typedef BasicSourceLineResolver::Function Function;
216 public:
217  static size_t SizeOf(const linked_ptr<Function> &func) {
218    if (!func.get()) return 0;
219    return SimpleSerializer<Function>::SizeOf(*(func.get()));
220  }
221
222  static char *Write(const linked_ptr<Function> &func, char *dest) {
223    if (func.get())
224      dest = SimpleSerializer<Function>::Write(*(func.get()), dest);
225    return dest;
226  }
227};
228
229template<>
230class SimpleSerializer< linked_ptr<BasicSourceLineResolver::PublicSymbol> > {
231  typedef BasicSourceLineResolver::PublicSymbol PublicSymbol;
232 public:
233  static size_t SizeOf(const linked_ptr<PublicSymbol> &pubsymbol) {
234    if (pubsymbol.get() == NULL) return 0;
235    return SimpleSerializer<PublicSymbol>::SizeOf(*(pubsymbol.get()));
236  }
237  static char *Write(const linked_ptr<PublicSymbol> &pubsymbol, char *dest) {
238    if (pubsymbol.get())
239      dest = SimpleSerializer<PublicSymbol>::Write(*(pubsymbol.get()), dest);
240    return dest;
241  }
242};
243
244template<>
245class SimpleSerializer< linked_ptr<WindowsFrameInfo> > {
246 public:
247  static size_t SizeOf(const linked_ptr<WindowsFrameInfo> &wfi) {
248    if (wfi.get() == NULL) return 0;
249    return SimpleSerializer<WindowsFrameInfo>::SizeOf(*(wfi.get()));
250  }
251  static char *Write(const linked_ptr<WindowsFrameInfo> &wfi, char *dest) {
252    if (wfi.get())
253      dest = SimpleSerializer<WindowsFrameInfo>::Write(*(wfi.get()), dest);
254    return dest;
255  }
256};
257
258}  // namespace google_breakpad
259
260#endif  // PROCESSOR_SIMPLE_SERIALIZER_INL_H__
261