~statik/ubuntu/maverick/protobuf/A

« back to all changes in this revision

Viewing changes to src/google/protobuf/message.cc

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2010-02-11 11:13:19 UTC
  • mfrom: (2.2.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100211111319-zdn8hmw0gh8s4cf8
Tags: 2.2.0a-0.1ubuntu1
* Merge from Debian testing.
* Remaining Ubuntu changes:
  - Don't use python2.4.
* Ubuntu changes dropped:
  - Disable death tests on Itanium, fixed upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include <google/protobuf/message.h>
39
39
 
40
40
#include <google/protobuf/stubs/common.h>
 
41
#include <google/protobuf/stubs/once.h>
41
42
#include <google/protobuf/io/coded_stream.h>
42
43
#include <google/protobuf/io/zero_copy_stream_impl.h>
43
44
#include <google/protobuf/descriptor.pb.h>
45
46
#include <google/protobuf/reflection_ops.h>
46
47
#include <google/protobuf/wire_format.h>
47
48
#include <google/protobuf/stubs/strutil.h>
48
 
#include <google/protobuf/stubs/substitute.h>
49
49
#include <google/protobuf/stubs/map-util.h>
50
50
#include <google/protobuf/stubs/stl_util-inl.h>
51
51
 
55
55
using internal::WireFormat;
56
56
using internal::ReflectionOps;
57
57
 
58
 
static string InitializationErrorMessage(const char* action,
59
 
                                         const Message& message) {
60
 
  return strings::Substitute(
61
 
    "Can't $0 message of type \"$1\" because it is missing required "
62
 
    "fields: $2",
63
 
    action, message.GetDescriptor()->full_name(),
64
 
    message.InitializationErrorString());
65
 
}
66
 
 
67
58
Message::~Message() {}
68
59
 
69
60
void Message::MergeFrom(const Message& from) {
75
66
  ReflectionOps::Merge(from, this);
76
67
}
77
68
 
 
69
void Message::CheckTypeAndMergeFrom(const MessageLite& other) {
 
70
  MergeFrom(*down_cast<const Message*>(&other));
 
71
}
 
72
 
78
73
void Message::CopyFrom(const Message& from) {
79
74
  const Descriptor* descriptor = GetDescriptor();
80
75
  GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
84
79
  ReflectionOps::Copy(from, this);
85
80
}
86
81
 
 
82
string Message::GetTypeName() const {
 
83
  return GetDescriptor()->full_name();
 
84
}
 
85
 
87
86
void Message::Clear() {
88
87
  ReflectionOps::Clear(this);
89
88
}
116
115
  return WireFormat::ParseAndMergePartial(input, this);
117
116
}
118
117
 
119
 
bool Message::MergeFromCodedStream(io::CodedInputStream* input) {
120
 
  if (!MergePartialFromCodedStream(input)) return false;
121
 
  if (!IsInitialized()) {
122
 
    GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *this);
123
 
    return false;
124
 
  }
125
 
  return true;
126
 
}
127
 
 
128
 
bool Message::ParseFromCodedStream(io::CodedInputStream* input) {
129
 
  Clear();
130
 
  return MergeFromCodedStream(input);
131
 
}
132
 
 
133
 
bool Message::ParsePartialFromCodedStream(io::CodedInputStream* input) {
134
 
  Clear();
135
 
  return MergePartialFromCodedStream(input);
136
 
}
137
 
 
138
 
bool Message::ParseFromZeroCopyStream(io::ZeroCopyInputStream* input) {
139
 
  io::CodedInputStream decoder(input);
140
 
  return ParseFromCodedStream(&decoder) && decoder.ConsumedEntireMessage();
141
 
}
142
 
 
143
 
bool Message::ParsePartialFromZeroCopyStream(io::ZeroCopyInputStream* input) {
144
 
  io::CodedInputStream decoder(input);
145
 
  return ParsePartialFromCodedStream(&decoder) &&
146
 
         decoder.ConsumedEntireMessage();
147
 
}
148
 
 
149
 
bool Message::ParseFromBoundedZeroCopyStream(
150
 
    io::ZeroCopyInputStream* input, int size) {
151
 
  io::CodedInputStream decoder(input);
152
 
  decoder.PushLimit(size);
153
 
  return ParseFromCodedStream(&decoder) &&
154
 
         decoder.ConsumedEntireMessage() &&
155
 
         decoder.BytesUntilLimit() == 0;
156
 
}
157
 
 
158
 
bool Message::ParsePartialFromBoundedZeroCopyStream(
159
 
    io::ZeroCopyInputStream* input, int size) {
160
 
  io::CodedInputStream decoder(input);
161
 
  decoder.PushLimit(size);
162
 
  return ParsePartialFromCodedStream(&decoder) &&
163
 
         decoder.ConsumedEntireMessage() &&
164
 
         decoder.BytesUntilLimit() == 0;
165
 
}
166
 
 
167
 
bool Message::ParseFromString(const string& data) {
168
 
  io::ArrayInputStream input(data.data(), data.size());
169
 
  return ParseFromBoundedZeroCopyStream(&input, data.size());
170
 
}
171
 
 
172
 
bool Message::ParsePartialFromString(const string& data) {
173
 
  io::ArrayInputStream input(data.data(), data.size());
174
 
  return ParsePartialFromBoundedZeroCopyStream(&input, data.size());
175
 
}
176
 
 
177
 
bool Message::ParseFromArray(const void* data, int size) {
178
 
  io::ArrayInputStream input(data, size);
179
 
  return ParseFromBoundedZeroCopyStream(&input, size);
180
 
}
181
 
 
182
 
bool Message::ParsePartialFromArray(const void* data, int size) {
183
 
  io::ArrayInputStream input(data, size);
184
 
  return ParsePartialFromBoundedZeroCopyStream(&input, size);
185
 
}
186
 
 
187
118
bool Message::ParseFromFileDescriptor(int file_descriptor) {
188
119
  io::FileInputStream input(file_descriptor);
189
120
  return ParseFromZeroCopyStream(&input) && input.GetErrno() == 0;
205
136
}
206
137
 
207
138
 
208
 
 
209
139
void Message::SerializeWithCachedSizes(
210
140
    io::CodedOutputStream* output) const {
211
141
  WireFormat::SerializeWithCachedSizes(*this, GetCachedSize(), output);
212
142
}
213
143
 
214
 
uint8* Message::SerializeWithCachedSizesToArray(uint8* target) const {
215
 
  // We only optimize this when using optimize_for = SPEED.
216
 
  int size = GetCachedSize();
217
 
  io::ArrayOutputStream out(target, size);
218
 
  io::CodedOutputStream coded_out(&out);
219
 
  SerializeWithCachedSizes(&coded_out);
220
 
  GOOGLE_CHECK(!coded_out.HadError());
221
 
  return target + size;
222
 
}
223
 
 
224
144
int Message::ByteSize() const {
225
145
  int size = WireFormat::ByteSize(*this);
226
146
  SetCachedSize(size);
237
157
  return GetReflection()->SpaceUsed(*this);
238
158
}
239
159
 
240
 
bool Message::SerializeToCodedStream(io::CodedOutputStream* output) const {
241
 
  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
242
 
  return SerializePartialToCodedStream(output);
243
 
}
244
 
 
245
 
bool Message::SerializePartialToCodedStream(
246
 
    io::CodedOutputStream* output) const {
247
 
  ByteSize();  // Force size to be cached.
248
 
  SerializeWithCachedSizes(output);
249
 
  return !output->HadError();
250
 
}
251
 
 
252
 
bool Message::SerializeToZeroCopyStream(
253
 
    io::ZeroCopyOutputStream* output) const {
254
 
  io::CodedOutputStream encoder(output);
255
 
  return SerializeToCodedStream(&encoder);
256
 
}
257
 
 
258
 
bool Message::SerializePartialToZeroCopyStream(
259
 
    io::ZeroCopyOutputStream* output) const {
260
 
  io::CodedOutputStream encoder(output);
261
 
  return SerializePartialToCodedStream(&encoder);
262
 
}
263
 
 
264
 
bool Message::AppendToString(string* output) const {
265
 
  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
266
 
  return AppendPartialToString(output);
267
 
}
268
 
 
269
 
bool Message::AppendPartialToString(string* output) const {
270
 
  int old_size = output->size();
271
 
  int byte_size = ByteSize();
272
 
  STLStringResizeUninitialized(output, old_size + byte_size);
273
 
  uint8* start = reinterpret_cast<uint8*>(string_as_array(output) + old_size);
274
 
  uint8* end = SerializeWithCachedSizesToArray(start);
275
 
  GOOGLE_CHECK_EQ(end, start + byte_size);
276
 
  return true;
277
 
}
278
 
 
279
 
bool Message::SerializeToString(string* output) const {
280
 
  output->clear();
281
 
  return AppendToString(output);
282
 
}
283
 
 
284
 
bool Message::SerializePartialToString(string* output) const {
285
 
  output->clear();
286
 
  return AppendPartialToString(output);
287
 
}
288
 
 
289
 
bool Message::SerializeToArray(void* data, int size) const {
290
 
  GOOGLE_DCHECK(IsInitialized()) << InitializationErrorMessage("serialize", *this);
291
 
  return SerializePartialToArray(data, size);
292
 
}
293
 
 
294
 
bool Message::SerializePartialToArray(void* data, int size) const {
295
 
  int byte_size = ByteSize();
296
 
  if (size < byte_size) return false;
297
 
  uint8* end =
298
 
    SerializeWithCachedSizesToArray(reinterpret_cast<uint8*>(data));
299
 
  GOOGLE_CHECK_EQ(end, reinterpret_cast<uint8*>(data) + byte_size);
300
 
  return true;
301
 
}
302
 
 
303
160
bool Message::SerializeToFileDescriptor(int file_descriptor) const {
304
161
  io::FileOutputStream output(file_descriptor);
305
162
  return SerializeToZeroCopyStream(&output);
321
178
}
322
179
 
323
180
 
324
 
string Message::SerializeAsString() const {
325
 
  // If the compiler implements the (Named) Return Value Optimization,
326
 
  // the local variable 'result' will not actually reside on the stack
327
 
  // of this function, but will be overlaid with the object that the
328
 
  // caller supplied for the return value to be constructed in.
329
 
  string output;
330
 
  if (!AppendToString(&output))
331
 
    output.clear();
332
 
  return output;
333
 
}
334
 
 
335
 
string Message::SerializePartialAsString() const {
336
 
  string output;
337
 
  if (!AppendPartialToString(&output))
338
 
    output.clear();
339
 
  return output;
340
 
}
341
 
 
342
181
Reflection::~Reflection() {}
343
182
 
344
183
// ===================================================================
355
194
 
356
195
  static GeneratedMessageFactory* singleton();
357
196
 
358
 
  typedef void RegistrationFunc();
 
197
  typedef void RegistrationFunc(const string&);
359
198
  void RegisterFile(const char* file, RegistrationFunc* registration_func);
360
199
  void RegisterType(const Descriptor* descriptor, const Message* prototype);
361
200
 
372
211
  hash_map<const Descriptor*, const Message*> type_map_;
373
212
};
374
213
 
 
214
GeneratedMessageFactory* generated_message_factory_ = NULL;
 
215
GOOGLE_PROTOBUF_DECLARE_ONCE(generated_message_factory_once_init_);
 
216
 
 
217
void ShutdownGeneratedMessageFactory() {
 
218
  delete generated_message_factory_;
 
219
}
 
220
 
 
221
void InitGeneratedMessageFactory() {
 
222
  generated_message_factory_ = new GeneratedMessageFactory;
 
223
  internal::OnShutdown(&ShutdownGeneratedMessageFactory);
 
224
}
 
225
 
375
226
GeneratedMessageFactory::GeneratedMessageFactory() {}
376
227
GeneratedMessageFactory::~GeneratedMessageFactory() {}
377
228
 
378
229
GeneratedMessageFactory* GeneratedMessageFactory::singleton() {
379
 
  // No need for thread-safety here because this will be called at static
380
 
  // initialization time.  (And GCC4 makes this thread-safe anyway.)
381
 
  static GeneratedMessageFactory singleton;
382
 
  return &singleton;
 
230
  GoogleOnceInit(&generated_message_factory_once_init_,
 
231
                 &InitGeneratedMessageFactory);
 
232
  return generated_message_factory_;
383
233
}
384
234
 
385
235
void GeneratedMessageFactory::RegisterFile(
430
280
  const Message* result = FindPtrOrNull(type_map_, type);
431
281
  if (result == NULL) {
432
282
    // Nope.  OK, register everything.
433
 
    registration_func();
 
283
    registration_func(type->file()->name());
434
284
    // Should be here now.
435
285
    result = FindPtrOrNull(type_map_, type);
436
286
  }
450
300
}
451
301
 
452
302
void MessageFactory::InternalRegisterGeneratedFile(
453
 
    const char* filename, void (*register_messages)()) {
 
303
    const char* filename, void (*register_messages)(const string&)) {
454
304
  GeneratedMessageFactory::singleton()->RegisterFile(filename,
455
305
                                                     register_messages);
456
306
}