OLD | NEW |
1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
3 // http://code.google.com/p/protobuf/ | 3 // https://developers.google.com/protocol-buffers/ |
4 // | 4 // |
5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
7 // met: | 7 // met: |
8 // | 8 // |
9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
11 // * Redistributions in binary form must reproduce the above | 11 // * Redistributions in binary form must reproduce the above |
12 // copyright notice, this list of conditions and the following disclaimer | 12 // copyright notice, this list of conditions and the following disclaimer |
13 // in the documentation and/or other materials provided with the | 13 // in the documentation and/or other materials provided with the |
(...skipping 28 matching lines...) Expand all Loading... |
42 // Typically these classes will only be used internally by the protocol | 42 // Typically these classes will only be used internally by the protocol |
43 // buffer library in order to encode and decode protocol buffers. Clients | 43 // buffer library in order to encode and decode protocol buffers. Clients |
44 // of the library only need to know about this class if they wish to write | 44 // of the library only need to know about this class if they wish to write |
45 // custom message parsing or serialization procedures. | 45 // custom message parsing or serialization procedures. |
46 // | 46 // |
47 // CodedOutputStream example: | 47 // CodedOutputStream example: |
48 // // Write some data to "myfile". First we write a 4-byte "magic number" | 48 // // Write some data to "myfile". First we write a 4-byte "magic number" |
49 // // to identify the file type, then write a length-delimited string. The | 49 // // to identify the file type, then write a length-delimited string. The |
50 // // string is composed of a varint giving the length followed by the raw | 50 // // string is composed of a varint giving the length followed by the raw |
51 // // bytes. | 51 // // bytes. |
52 // int fd = open("myfile", O_WRONLY); | 52 // int fd = open("myfile", O_CREAT | O_WRONLY); |
53 // ZeroCopyOutputStream* raw_output = new FileOutputStream(fd); | 53 // ZeroCopyOutputStream* raw_output = new FileOutputStream(fd); |
54 // CodedOutputStream* coded_output = new CodedOutputStream(raw_output); | 54 // CodedOutputStream* coded_output = new CodedOutputStream(raw_output); |
55 // | 55 // |
56 // int magic_number = 1234; | 56 // int magic_number = 1234; |
57 // char text[] = "Hello world!"; | 57 // char text[] = "Hello world!"; |
58 // coded_output->WriteLittleEndian32(magic_number); | 58 // coded_output->WriteLittleEndian32(magic_number); |
59 // coded_output->WriteVarint32(strlen(text)); | 59 // coded_output->WriteVarint32(strlen(text)); |
60 // coded_output->WriteRaw(text, strlen(text)); | 60 // coded_output->WriteRaw(text, strlen(text)); |
61 // | 61 // |
62 // delete coded_output; | 62 // delete coded_output; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 // and so on. So, the binary number 1011000101011 would be encoded in two | 102 // and so on. So, the binary number 1011000101011 would be encoded in two |
103 // bytes as "10101011 00101100". | 103 // bytes as "10101011 00101100". |
104 // | 104 // |
105 // In theory, varint could be used to encode integers of any length. | 105 // In theory, varint could be used to encode integers of any length. |
106 // However, for practicality we set a limit at 64 bits. The maximum encoded | 106 // However, for practicality we set a limit at 64 bits. The maximum encoded |
107 // length of a number is thus 10 bytes. | 107 // length of a number is thus 10 bytes. |
108 | 108 |
109 #ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ | 109 #ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ |
110 #define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ | 110 #define GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ |
111 | 111 |
| 112 #include <assert.h> |
112 #include <string> | 113 #include <string> |
| 114 #include <utility> |
113 #ifdef _MSC_VER | 115 #ifdef _MSC_VER |
114 #if defined(_M_IX86) && \ | 116 // Assuming windows is always little-endian. |
115 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) | 117 #if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) |
116 #define PROTOBUF_LITTLE_ENDIAN 1 | 118 #define PROTOBUF_LITTLE_ENDIAN 1 |
117 #endif | 119 #endif |
118 #if _MSC_VER >= 1300 | 120 #if _MSC_VER >= 1300 |
119 // If MSVC has "/RTCc" set, it will complain about truncating casts at | 121 // If MSVC has "/RTCc" set, it will complain about truncating casts at |
120 // runtime. This file contains some intentional truncating casts. | 122 // runtime. This file contains some intentional truncating casts. |
121 #pragma runtime_checks("c", off) | 123 #pragma runtime_checks("c", off) |
122 #endif | 124 #endif |
123 #else | 125 #else |
124 #include <sys/param.h> // __BYTE_ORDER | 126 #include <sys/param.h> // __BYTE_ORDER |
125 #if defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN && \ | 127 #if ((defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \ |
| 128 (defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN)) && \ |
126 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) | 129 !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST) |
127 #define PROTOBUF_LITTLE_ENDIAN 1 | 130 #define PROTOBUF_LITTLE_ENDIAN 1 |
128 #endif | 131 #endif |
129 #endif | 132 #endif |
130 #include <google/protobuf/stubs/common.h> | 133 #include <google/protobuf/stubs/common.h> |
131 | 134 |
| 135 namespace google { |
132 | 136 |
133 namespace google { | |
134 namespace protobuf { | 137 namespace protobuf { |
135 | 138 |
136 class DescriptorPool; | 139 class DescriptorPool; |
137 class MessageFactory; | 140 class MessageFactory; |
138 | 141 |
139 namespace io { | 142 namespace io { |
140 | 143 |
141 // Defined in this file. | 144 // Defined in this file. |
142 class CodedInputStream; | 145 class CodedInputStream; |
143 class CodedOutputStream; | 146 class CodedOutputStream; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 // underlying buffer, and *size to the size of that buffer, but does not | 185 // underlying buffer, and *size to the size of that buffer, but does not |
183 // advance the stream's current position. This will always either produce | 186 // advance the stream's current position. This will always either produce |
184 // a non-empty buffer or return false. If the caller consumes any of | 187 // a non-empty buffer or return false. If the caller consumes any of |
185 // this data, it should then call Skip() to skip over the consumed bytes. | 188 // this data, it should then call Skip() to skip over the consumed bytes. |
186 // This may be useful for implementing external fast parsing routines for | 189 // This may be useful for implementing external fast parsing routines for |
187 // types of data not covered by the CodedInputStream interface. | 190 // types of data not covered by the CodedInputStream interface. |
188 bool GetDirectBufferPointer(const void** data, int* size); | 191 bool GetDirectBufferPointer(const void** data, int* size); |
189 | 192 |
190 // Like GetDirectBufferPointer, but this method is inlined, and does not | 193 // Like GetDirectBufferPointer, but this method is inlined, and does not |
191 // attempt to Refresh() if the buffer is currently empty. | 194 // attempt to Refresh() if the buffer is currently empty. |
192 inline void GetDirectBufferPointerInline(const void** data, | 195 GOOGLE_ATTRIBUTE_ALWAYS_INLINE void GetDirectBufferPointerInline(const void**
data, |
193 int* size) GOOGLE_ATTRIBUTE_ALWAYS_IN
LINE; | 196 int* size); |
194 | 197 |
195 // Read raw bytes, copying them into the given buffer. | 198 // Read raw bytes, copying them into the given buffer. |
196 bool ReadRaw(void* buffer, int size); | 199 bool ReadRaw(void* buffer, int size); |
197 | 200 |
| 201 // Like the above, with inlined optimizations. This should only be used |
| 202 // by the protobuf implementation. |
| 203 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InternalReadRawInline(void* buffer, int si
ze); |
| 204 |
198 // Like ReadRaw, but reads into a string. | 205 // Like ReadRaw, but reads into a string. |
199 // | 206 // |
200 // Implementation Note: ReadString() grows the string gradually as it | 207 // Implementation Note: ReadString() grows the string gradually as it |
201 // reads in the data, rather than allocating the entire requested size | 208 // reads in the data, rather than allocating the entire requested size |
202 // upfront. This prevents denial-of-service attacks in which a client | 209 // upfront. This prevents denial-of-service attacks in which a client |
203 // could claim that a string is going to be MAX_INT bytes long in order to | 210 // could claim that a string is going to be MAX_INT bytes long in order to |
204 // crash the server because it can't allocate this much space at once. | 211 // crash the server because it can't allocate this much space at once. |
205 bool ReadString(string* buffer, int size); | 212 bool ReadString(string* buffer, int size); |
206 // Like the above, with inlined optimizations. This should only be used | 213 // Like the above, with inlined optimizations. This should only be used |
207 // by the protobuf implementation. | 214 // by the protobuf implementation. |
208 inline bool InternalReadStringInline(string* buffer, | 215 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InternalReadStringInline(string* buffer, |
209 int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; | 216 int size); |
210 | 217 |
211 | 218 |
212 // Read a 32-bit little-endian integer. | 219 // Read a 32-bit little-endian integer. |
213 bool ReadLittleEndian32(uint32* value); | 220 bool ReadLittleEndian32(uint32* value); |
214 // Read a 64-bit little-endian integer. | 221 // Read a 64-bit little-endian integer. |
215 bool ReadLittleEndian64(uint64* value); | 222 bool ReadLittleEndian64(uint64* value); |
216 | 223 |
217 // These methods read from an externally provided buffer. The caller is | 224 // These methods read from an externally provided buffer. The caller is |
218 // responsible for ensuring that the buffer has sufficient space. | 225 // responsible for ensuring that the buffer has sufficient space. |
219 // Read a 32-bit little-endian integer. | 226 // Read a 32-bit little-endian integer. |
220 static const uint8* ReadLittleEndian32FromArray(const uint8* buffer, | 227 static const uint8* ReadLittleEndian32FromArray(const uint8* buffer, |
221 uint32* value); | 228 uint32* value); |
222 // Read a 64-bit little-endian integer. | 229 // Read a 64-bit little-endian integer. |
223 static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, | 230 static const uint8* ReadLittleEndian64FromArray(const uint8* buffer, |
224 uint64* value); | 231 uint64* value); |
225 | 232 |
226 // Read an unsigned integer with Varint encoding, truncating to 32 bits. | 233 // Read an unsigned integer with Varint encoding, truncating to 32 bits. |
227 // Reading a 32-bit value is equivalent to reading a 64-bit one and casting | 234 // Reading a 32-bit value is equivalent to reading a 64-bit one and casting |
228 // it to uint32, but may be more efficient. | 235 // it to uint32, but may be more efficient. |
229 bool ReadVarint32(uint32* value); | 236 bool ReadVarint32(uint32* value); |
230 // Read an unsigned integer with Varint encoding. | 237 // Read an unsigned integer with Varint encoding. |
231 bool ReadVarint64(uint64* value); | 238 bool ReadVarint64(uint64* value); |
232 | 239 |
233 // Read a tag. This calls ReadVarint32() and returns the result, or returns | 240 // Read a tag. This calls ReadVarint32() and returns the result, or returns |
234 // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates | 241 // zero (which is not a valid tag) if ReadVarint32() fails. Also, it updates |
235 // the last tag value, which can be checked with LastTagWas(). | 242 // the last tag value, which can be checked with LastTagWas(). |
236 // Always inline because this is only called in once place per parse loop | 243 // Always inline because this is only called in one place per parse loop |
237 // but it is called for every iteration of said loop, so it should be fast. | 244 // but it is called for every iteration of said loop, so it should be fast. |
238 // GCC doesn't want to inline this by default. | 245 // GCC doesn't want to inline this by default. |
239 uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE; | 246 GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag(); |
| 247 |
| 248 // This usually a faster alternative to ReadTag() when cutoff is a manifest |
| 249 // constant. It does particularly well for cutoff >= 127. The first part |
| 250 // of the return value is the tag that was read, though it can also be 0 in |
| 251 // the cases where ReadTag() would return 0. If the second part is true |
| 252 // then the tag is known to be in [0, cutoff]. If not, the tag either is |
| 253 // above cutoff or is 0. (There's intentional wiggle room when tag is 0, |
| 254 // because that can arise in several ways, and for best performance we want |
| 255 // to avoid an extra "is tag == 0?" check here.) |
| 256 GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair<uint32, bool> ReadTagWithCutoff( |
| 257 uint32 cutoff); |
240 | 258 |
241 // Usually returns true if calling ReadVarint32() now would produce the given | 259 // Usually returns true if calling ReadVarint32() now would produce the given |
242 // value. Will always return false if ReadVarint32() would not return the | 260 // value. Will always return false if ReadVarint32() would not return the |
243 // given value. If ExpectTag() returns true, it also advances past | 261 // given value. If ExpectTag() returns true, it also advances past |
244 // the varint. For best performance, use a compile-time constant as the | 262 // the varint. For best performance, use a compile-time constant as the |
245 // parameter. | 263 // parameter. |
246 // Always inline because this collapses to a small number of instructions | 264 // Always inline because this collapses to a small number of instructions |
247 // when given a constant parameter, but GCC doesn't want to inline by default. | 265 // when given a constant parameter, but GCC doesn't want to inline by default. |
248 bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; | 266 GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool ExpectTag(uint32 expected); |
249 | 267 |
250 // Like above, except this reads from the specified buffer. The caller is | 268 // Like above, except this reads from the specified buffer. The caller is |
251 // responsible for ensuring that the buffer is large enough to read a varint | 269 // responsible for ensuring that the buffer is large enough to read a varint |
252 // of the expected size. For best performance, use a compile-time constant as | 270 // of the expected size. For best performance, use a compile-time constant as |
253 // the expected tag parameter. | 271 // the expected tag parameter. |
254 // | 272 // |
255 // Returns a pointer beyond the expected tag if it was found, or NULL if it | 273 // Returns a pointer beyond the expected tag if it was found, or NULL if it |
256 // was not. | 274 // was not. |
257 static const uint8* ExpectTagFromArray( | 275 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static const uint8* ExpectTagFromArray( |
258 const uint8* buffer, | 276 const uint8* buffer, |
259 uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; | 277 uint32 expected); |
260 | 278 |
261 // Usually returns true if no more bytes can be read. Always returns false | 279 // Usually returns true if no more bytes can be read. Always returns false |
262 // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent | 280 // if more bytes can be read. If ExpectAtEnd() returns true, a subsequent |
263 // call to LastTagWas() will act as if ReadTag() had been called and returned | 281 // call to LastTagWas() will act as if ReadTag() had been called and returned |
264 // zero, and ConsumedEntireMessage() will return true. | 282 // zero, and ConsumedEntireMessage() will return true. |
265 bool ExpectAtEnd(); | 283 bool ExpectAtEnd(); |
266 | 284 |
267 // If the last call to ReadTag() returned the given value, returns true. | 285 // If the last call to ReadTag() or ReadTagWithCutoff() returned the |
268 // Otherwise, returns false; | 286 // given value, returns true. Otherwise, returns false; |
269 // | 287 // |
270 // This is needed because parsers for some types of embedded messages | 288 // This is needed because parsers for some types of embedded messages |
271 // (with field type TYPE_GROUP) don't actually know that they've reached the | 289 // (with field type TYPE_GROUP) don't actually know that they've reached the |
272 // end of a message until they see an ENDGROUP tag, which was actually part | 290 // end of a message until they see an ENDGROUP tag, which was actually part |
273 // of the enclosing message. The enclosing message would like to check that | 291 // of the enclosing message. The enclosing message would like to check that |
274 // tag to make sure it had the right number, so it calls LastTagWas() on | 292 // tag to make sure it had the right number, so it calls LastTagWas() on |
275 // return from the embedded parser to check. | 293 // return from the embedded parser to check. |
276 bool LastTagWas(uint32 expected); | 294 bool LastTagWas(uint32 expected); |
277 | 295 |
278 // When parsing message (but NOT a group), this method must be called | 296 // When parsing message (but NOT a group), this method must be called |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 344 |
327 // Sets the maximum number of bytes that this CodedInputStream will read | 345 // Sets the maximum number of bytes that this CodedInputStream will read |
328 // before refusing to continue. To prevent integer overflows in the | 346 // before refusing to continue. To prevent integer overflows in the |
329 // protocol buffers implementation, as well as to prevent servers from | 347 // protocol buffers implementation, as well as to prevent servers from |
330 // allocating enormous amounts of memory to hold parsed messages, the | 348 // allocating enormous amounts of memory to hold parsed messages, the |
331 // maximum message length should be limited to the shortest length that | 349 // maximum message length should be limited to the shortest length that |
332 // will not harm usability. The theoretical shortest message that could | 350 // will not harm usability. The theoretical shortest message that could |
333 // cause integer overflows is 512MB. The default limit is 64MB. Apps | 351 // cause integer overflows is 512MB. The default limit is 64MB. Apps |
334 // should set shorter limits if possible. If warning_threshold is not -1, | 352 // should set shorter limits if possible. If warning_threshold is not -1, |
335 // a warning will be printed to stderr after warning_threshold bytes are | 353 // a warning will be printed to stderr after warning_threshold bytes are |
336 // read. For backwards compatibility all negative values get squached to -1, | 354 // read. For backwards compatibility all negative values get squashed to -1, |
337 // as other negative values might have special internal meanings. | 355 // as other negative values might have special internal meanings. |
338 // An error will always be printed to stderr if the limit is reached. | 356 // An error will always be printed to stderr if the limit is reached. |
339 // | 357 // |
340 // This is unrelated to PushLimit()/PopLimit(). | 358 // This is unrelated to PushLimit()/PopLimit(). |
341 // | 359 // |
342 // Hint: If you are reading this because your program is printing a | 360 // Hint: If you are reading this because your program is printing a |
343 // warning about dangerously large protocol messages, you may be | 361 // warning about dangerously large protocol messages, you may be |
344 // confused about what to do next. The best option is to change your | 362 // confused about what to do next. The best option is to change your |
345 // design such that excessively large messages are not necessary. | 363 // design such that excessively large messages are not necessary. |
346 // For example, try to design file formats to consist of many small | 364 // For example, try to design file formats to consist of many small |
347 // messages rather than a single large one. If this is infeasible, | 365 // messages rather than a single large one. If this is infeasible, |
348 // you will need to increase the limit. Chances are, though, that | 366 // you will need to increase the limit. Chances are, though, that |
349 // your code never constructs a CodedInputStream on which the limit | 367 // your code never constructs a CodedInputStream on which the limit |
350 // can be set. You probably parse messages by calling things like | 368 // can be set. You probably parse messages by calling things like |
351 // Message::ParseFromString(). In this case, you will need to change | 369 // Message::ParseFromString(). In this case, you will need to change |
352 // your code to instead construct some sort of ZeroCopyInputStream | 370 // your code to instead construct some sort of ZeroCopyInputStream |
353 // (e.g. an ArrayInputStream), construct a CodedInputStream around | 371 // (e.g. an ArrayInputStream), construct a CodedInputStream around |
354 // that, then call Message::ParseFromCodedStream() instead. Then | 372 // that, then call Message::ParseFromCodedStream() instead. Then |
355 // you can adjust the limit. Yes, it's more work, but you're doing | 373 // you can adjust the limit. Yes, it's more work, but you're doing |
356 // something unusual. | 374 // something unusual. |
357 void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); | 375 void SetTotalBytesLimit(int total_bytes_limit, int warning_threshold); |
358 | 376 |
| 377 // The Total Bytes Limit minus the Current Position, or -1 if there |
| 378 // is no Total Bytes Limit. |
| 379 int BytesUntilTotalBytesLimit() const; |
| 380 |
359 // Recursion Limit ------------------------------------------------- | 381 // Recursion Limit ------------------------------------------------- |
360 // To prevent corrupt or malicious messages from causing stack overflows, | 382 // To prevent corrupt or malicious messages from causing stack overflows, |
361 // we must keep track of the depth of recursion when parsing embedded | 383 // we must keep track of the depth of recursion when parsing embedded |
362 // messages and groups. CodedInputStream keeps track of this because it | 384 // messages and groups. CodedInputStream keeps track of this because it |
363 // is the only object that is passed down the stack during parsing. | 385 // is the only object that is passed down the stack during parsing. |
364 | 386 |
365 // Sets the maximum recursion depth. The default is 100. | 387 // Sets the maximum recursion depth. The default is 100. |
366 void SetRecursionLimit(int limit); | 388 void SetRecursionLimit(int limit); |
367 | 389 |
368 | 390 |
369 // Increments the current recursion depth. Returns true if the depth is | 391 // Increments the current recursion depth. Returns true if the depth is |
370 // under the limit, false if it has gone over. | 392 // under the limit, false if it has gone over. |
371 bool IncrementRecursionDepth(); | 393 bool IncrementRecursionDepth(); |
372 | 394 |
373 // Decrements the recursion depth. | 395 // Decrements the recursion depth if possible. |
374 void DecrementRecursionDepth(); | 396 void DecrementRecursionDepth(); |
375 | 397 |
| 398 // Decrements the recursion depth blindly. This is faster than |
| 399 // DecrementRecursionDepth(). It should be used only if all previous |
| 400 // increments to recursion depth were successful. |
| 401 void UnsafeDecrementRecursionDepth(); |
| 402 |
| 403 // Shorthand for make_pair(PushLimit(byte_limit), --recursion_budget_). |
| 404 // Using this can reduce code size and complexity in some cases. The caller |
| 405 // is expected to check that the second part of the result is non-negative (to |
| 406 // bail out if the depth of recursion is too high) and, if all is well, to |
| 407 // later pass the first part of the result to PopLimit() or similar. |
| 408 std::pair<CodedInputStream::Limit, int> IncrementRecursionDepthAndPushLimit( |
| 409 int byte_limit); |
| 410 |
| 411 // Shorthand for PushLimit(ReadVarint32(&length) ? length : 0). |
| 412 Limit ReadLengthAndPushLimit(); |
| 413 |
| 414 // Helper that is equivalent to: { |
| 415 // bool result = ConsumedEntireMessage(); |
| 416 // PopLimit(limit); |
| 417 // UnsafeDecrementRecursionDepth(); |
| 418 // return result; } |
| 419 // Using this can reduce code size and complexity in some cases. |
| 420 // Do not use unless the current recursion depth is greater than zero. |
| 421 bool DecrementRecursionDepthAndPopLimit(Limit limit); |
| 422 |
| 423 // Helper that is equivalent to: { |
| 424 // bool result = ConsumedEntireMessage(); |
| 425 // PopLimit(limit); |
| 426 // return result; } |
| 427 // Using this can reduce code size and complexity in some cases. |
| 428 bool CheckEntireMessageConsumedAndPopLimit(Limit limit); |
| 429 |
376 // Extension Registry ---------------------------------------------- | 430 // Extension Registry ---------------------------------------------- |
377 // ADVANCED USAGE: 99.9% of people can ignore this section. | 431 // ADVANCED USAGE: 99.9% of people can ignore this section. |
378 // | 432 // |
379 // By default, when parsing extensions, the parser looks for extension | 433 // By default, when parsing extensions, the parser looks for extension |
380 // definitions in the pool which owns the outer message's Descriptor. | 434 // definitions in the pool which owns the outer message's Descriptor. |
381 // However, you may call SetExtensionRegistry() to provide an alternative | 435 // However, you may call SetExtensionRegistry() to provide an alternative |
382 // pool instead. This makes it possible, for example, to parse a message | 436 // pool instead. This makes it possible, for example, to parse a message |
383 // using a generated class, but represent some extensions using | 437 // using a generated class, but represent some extensions using |
384 // DynamicMessage. | 438 // DynamicMessage. |
385 | 439 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
448 // has been provided. | 502 // has been provided. |
449 const DescriptorPool* GetExtensionPool(); | 503 const DescriptorPool* GetExtensionPool(); |
450 | 504 |
451 // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no | 505 // Get the MessageFactory set via SetExtensionRegistry(), or NULL if no |
452 // factory has been provided. | 506 // factory has been provided. |
453 MessageFactory* GetExtensionFactory(); | 507 MessageFactory* GetExtensionFactory(); |
454 | 508 |
455 private: | 509 private: |
456 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); | 510 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedInputStream); |
457 | 511 |
458 ZeroCopyInputStream* input_; | |
459 const uint8* buffer_; | 512 const uint8* buffer_; |
460 const uint8* buffer_end_; // pointer to the end of the buffer. | 513 const uint8* buffer_end_; // pointer to the end of the buffer. |
| 514 ZeroCopyInputStream* input_; |
461 int total_bytes_read_; // total bytes read from input_, including | 515 int total_bytes_read_; // total bytes read from input_, including |
462 // the current buffer | 516 // the current buffer |
463 | 517 |
464 // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here | 518 // If total_bytes_read_ surpasses INT_MAX, we record the extra bytes here |
465 // so that we can BackUp() on destruction. | 519 // so that we can BackUp() on destruction. |
466 int overflow_bytes_; | 520 int overflow_bytes_; |
467 | 521 |
468 // LastTagWas() stuff. | 522 // LastTagWas() stuff. |
469 uint32 last_tag_; // result of last ReadTag(). | 523 uint32 last_tag_; // result of last ReadTag() or ReadTagWithCutoff(). |
470 | 524 |
471 // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly | 525 // This is set true by ReadTag{Fallback/Slow}() if it is called when exactly |
472 // at EOF, or by ExpectAtEnd() when it returns true. This happens when we | 526 // at EOF, or by ExpectAtEnd() when it returns true. This happens when we |
473 // reach the end of a message and attempt to read another tag. | 527 // reach the end of a message and attempt to read another tag. |
474 bool legitimate_message_end_; | 528 bool legitimate_message_end_; |
475 | 529 |
476 // See EnableAliasing(). | 530 // See EnableAliasing(). |
477 bool aliasing_enabled_; | 531 bool aliasing_enabled_; |
478 | 532 |
479 // Limits | 533 // Limits |
(...skipping 11 matching lines...) Expand all Loading... |
491 // Maximum number of bytes to read, period. This is unrelated to | 545 // Maximum number of bytes to read, period. This is unrelated to |
492 // current_limit_. Set using SetTotalBytesLimit(). | 546 // current_limit_. Set using SetTotalBytesLimit(). |
493 int total_bytes_limit_; | 547 int total_bytes_limit_; |
494 | 548 |
495 // If positive/0: Limit for bytes read after which a warning due to size | 549 // If positive/0: Limit for bytes read after which a warning due to size |
496 // should be logged. | 550 // should be logged. |
497 // If -1: Printing of warning disabled. Can be set by client. | 551 // If -1: Printing of warning disabled. Can be set by client. |
498 // If -2: Internal: Limit has been reached, print full size when destructing. | 552 // If -2: Internal: Limit has been reached, print full size when destructing. |
499 int total_bytes_warning_threshold_; | 553 int total_bytes_warning_threshold_; |
500 | 554 |
501 // Current recursion depth, controlled by IncrementRecursionDepth() and | 555 // Current recursion budget, controlled by IncrementRecursionDepth() and |
502 // DecrementRecursionDepth(). | 556 // similar. Starts at recursion_limit_ and goes down: if this reaches |
503 int recursion_depth_; | 557 // -1 we are over budget. |
| 558 int recursion_budget_; |
504 // Recursion depth limit, set by SetRecursionLimit(). | 559 // Recursion depth limit, set by SetRecursionLimit(). |
505 int recursion_limit_; | 560 int recursion_limit_; |
506 | 561 |
507 // See SetExtensionRegistry(). | 562 // See SetExtensionRegistry(). |
508 const DescriptorPool* extension_pool_; | 563 const DescriptorPool* extension_pool_; |
509 MessageFactory* extension_factory_; | 564 MessageFactory* extension_factory_; |
510 | 565 |
511 // Private member functions. | 566 // Private member functions. |
512 | 567 |
513 // Advance the buffer by a given number of bytes. | 568 // Advance the buffer by a given number of bytes. |
(...skipping 12 matching lines...) Expand all Loading... |
526 // Called when the buffer runs out to request more data. Implies an | 581 // Called when the buffer runs out to request more data. Implies an |
527 // Advance(BufferSize()). | 582 // Advance(BufferSize()). |
528 bool Refresh(); | 583 bool Refresh(); |
529 | 584 |
530 // When parsing varints, we optimize for the common case of small values, and | 585 // When parsing varints, we optimize for the common case of small values, and |
531 // then optimize for the case when the varint fits within the current buffer | 586 // then optimize for the case when the varint fits within the current buffer |
532 // piece. The Fallback method is used when we can't use the one-byte | 587 // piece. The Fallback method is used when we can't use the one-byte |
533 // optimization. The Slow method is yet another fallback when the buffer is | 588 // optimization. The Slow method is yet another fallback when the buffer is |
534 // not large enough. Making the slow path out-of-line speeds up the common | 589 // not large enough. Making the slow path out-of-line speeds up the common |
535 // case by 10-15%. The slow path is fairly uncommon: it only triggers when a | 590 // case by 10-15%. The slow path is fairly uncommon: it only triggers when a |
536 // message crosses multiple buffers. | 591 // message crosses multiple buffers. Note: ReadVarint32Fallback() and |
537 bool ReadVarint32Fallback(uint32* value); | 592 // ReadVarint64Fallback() are called frequently and generally not inlined, so |
538 bool ReadVarint64Fallback(uint64* value); | 593 // they have been optimized to avoid "out" parameters. The former returns -1 |
| 594 // if it fails and the uint32 it read otherwise. The latter has a bool |
| 595 // indicating success or failure as part of its return type. |
| 596 int64 ReadVarint32Fallback(uint32 first_byte_or_zero); |
| 597 std::pair<uint64, bool> ReadVarint64Fallback(); |
539 bool ReadVarint32Slow(uint32* value); | 598 bool ReadVarint32Slow(uint32* value); |
540 bool ReadVarint64Slow(uint64* value); | 599 bool ReadVarint64Slow(uint64* value); |
541 bool ReadLittleEndian32Fallback(uint32* value); | 600 bool ReadLittleEndian32Fallback(uint32* value); |
542 bool ReadLittleEndian64Fallback(uint64* value); | 601 bool ReadLittleEndian64Fallback(uint64* value); |
543 // Fallback/slow methods for reading tags. These do not update last_tag_, | 602 // Fallback/slow methods for reading tags. These do not update last_tag_, |
544 // but will set legitimate_message_end_ if we are at the end of the input | 603 // but will set legitimate_message_end_ if we are at the end of the input |
545 // stream. | 604 // stream. |
546 uint32 ReadTagFallback(); | 605 uint32 ReadTagFallback(uint32 first_byte_or_zero); |
547 uint32 ReadTagSlow(); | 606 uint32 ReadTagSlow(); |
548 bool ReadStringFallback(string* buffer, int size); | 607 bool ReadStringFallback(string* buffer, int size); |
549 | 608 |
550 // Return the size of the buffer. | 609 // Return the size of the buffer. |
551 int BufferSize() const; | 610 int BufferSize() const; |
552 | 611 |
553 static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB | 612 static const int kDefaultTotalBytesLimit = 64 << 20; // 64MB |
554 | 613 |
555 static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB | 614 static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB |
556 | 615 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 // delete coded_output; | 664 // delete coded_output; |
606 class LIBPROTOBUF_EXPORT CodedOutputStream { | 665 class LIBPROTOBUF_EXPORT CodedOutputStream { |
607 public: | 666 public: |
608 // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream. | 667 // Create an CodedOutputStream that writes to the given ZeroCopyOutputStream. |
609 explicit CodedOutputStream(ZeroCopyOutputStream* output); | 668 explicit CodedOutputStream(ZeroCopyOutputStream* output); |
610 | 669 |
611 // Destroy the CodedOutputStream and position the underlying | 670 // Destroy the CodedOutputStream and position the underlying |
612 // ZeroCopyOutputStream immediately after the last byte written. | 671 // ZeroCopyOutputStream immediately after the last byte written. |
613 ~CodedOutputStream(); | 672 ~CodedOutputStream(); |
614 | 673 |
| 674 // Trims any unused space in the underlying buffer so that its size matches |
| 675 // the number of bytes written by this stream. The underlying buffer will |
| 676 // automatically be trimmed when this stream is destroyed; this call is only |
| 677 // necessary if the underlying buffer is accessed *before* the stream is |
| 678 // destroyed. |
| 679 void Trim(); |
| 680 |
615 // Skips a number of bytes, leaving the bytes unmodified in the underlying | 681 // Skips a number of bytes, leaving the bytes unmodified in the underlying |
616 // buffer. Returns false if an underlying write error occurs. This is | 682 // buffer. Returns false if an underlying write error occurs. This is |
617 // mainly useful with GetDirectBufferPointer(). | 683 // mainly useful with GetDirectBufferPointer(). |
618 bool Skip(int count); | 684 bool Skip(int count); |
619 | 685 |
620 // Sets *data to point directly at the unwritten part of the | 686 // Sets *data to point directly at the unwritten part of the |
621 // CodedOutputStream's underlying buffer, and *size to the size of that | 687 // CodedOutputStream's underlying buffer, and *size to the size of that |
622 // buffer, but does not advance the stream's current position. This will | 688 // buffer, but does not advance the stream's current position. This will |
623 // always either produce a non-empty buffer or return false. If the caller | 689 // always either produce a non-empty buffer or return false. If the caller |
624 // writes any data to this buffer, it should then call Skip() to skip over | 690 // writes any data to this buffer, it should then call Skip() to skip over |
625 // the consumed bytes. This may be useful for implementing external fast | 691 // the consumed bytes. This may be useful for implementing external fast |
626 // serialization routines for types of data not covered by the | 692 // serialization routines for types of data not covered by the |
627 // CodedOutputStream interface. | 693 // CodedOutputStream interface. |
628 bool GetDirectBufferPointer(void** data, int* size); | 694 bool GetDirectBufferPointer(void** data, int* size); |
629 | 695 |
630 // If there are at least "size" bytes available in the current buffer, | 696 // If there are at least "size" bytes available in the current buffer, |
631 // returns a pointer directly into the buffer and advances over these bytes. | 697 // returns a pointer directly into the buffer and advances over these bytes. |
632 // The caller may then write directly into this buffer (e.g. using the | 698 // The caller may then write directly into this buffer (e.g. using the |
633 // *ToArray static methods) rather than go through CodedOutputStream. If | 699 // *ToArray static methods) rather than go through CodedOutputStream. If |
634 // there are not enough bytes available, returns NULL. The return pointer is | 700 // there are not enough bytes available, returns NULL. The return pointer is |
635 // invalidated as soon as any other non-const method of CodedOutputStream | 701 // invalidated as soon as any other non-const method of CodedOutputStream |
636 // is called. | 702 // is called. |
637 inline uint8* GetDirectBufferForNBytesAndAdvance(int size); | 703 inline uint8* GetDirectBufferForNBytesAndAdvance(int size); |
638 | 704 |
639 // Write raw bytes, copying them from the given buffer. | 705 // Write raw bytes, copying them from the given buffer. |
640 void WriteRaw(const void* buffer, int size); | 706 void WriteRaw(const void* buffer, int size); |
| 707 // Like WriteRaw() but will try to write aliased data if aliasing is |
| 708 // turned on. |
| 709 void WriteRawMaybeAliased(const void* data, int size); |
641 // Like WriteRaw() but writing directly to the target array. | 710 // Like WriteRaw() but writing directly to the target array. |
642 // This is _not_ inlined, as the compiler often optimizes memcpy into inline | 711 // This is _not_ inlined, as the compiler often optimizes memcpy into inline |
643 // copy loops. Since this gets called by every field with string or bytes | 712 // copy loops. Since this gets called by every field with string or bytes |
644 // type, inlining may lead to a significant amount of code bloat, with only a | 713 // type, inlining may lead to a significant amount of code bloat, with only a |
645 // minor performance gain. | 714 // minor performance gain. |
646 static uint8* WriteRawToArray(const void* buffer, int size, uint8* target); | 715 static uint8* WriteRawToArray(const void* buffer, int size, uint8* target); |
647 | 716 |
648 // Equivalent to WriteRaw(str.data(), str.size()). | 717 // Equivalent to WriteRaw(str.data(), str.size()). |
649 void WriteString(const string& str); | 718 void WriteString(const string& str); |
650 // Like WriteString() but writing directly to the target array. | 719 // Like WriteString() but writing directly to the target array. |
651 static uint8* WriteStringToArray(const string& str, uint8* target); | 720 static uint8* WriteStringToArray(const string& str, uint8* target); |
| 721 // Write the varint-encoded size of str followed by str. |
| 722 static uint8* WriteStringWithSizeToArray(const string& str, uint8* target); |
652 | 723 |
653 | 724 |
| 725 // Instructs the CodedOutputStream to allow the underlying |
| 726 // ZeroCopyOutputStream to hold pointers to the original structure instead of |
| 727 // copying, if it supports it (i.e. output->AllowsAliasing() is true). If the |
| 728 // underlying stream does not support aliasing, then enabling it has no |
| 729 // affect. For now, this only affects the behavior of |
| 730 // WriteRawMaybeAliased(). |
| 731 // |
| 732 // NOTE: It is caller's responsibility to ensure that the chunk of memory |
| 733 // remains live until all of the data has been consumed from the stream. |
| 734 void EnableAliasing(bool enabled); |
| 735 |
654 // Write a 32-bit little-endian integer. | 736 // Write a 32-bit little-endian integer. |
655 void WriteLittleEndian32(uint32 value); | 737 void WriteLittleEndian32(uint32 value); |
656 // Like WriteLittleEndian32() but writing directly to the target array. | 738 // Like WriteLittleEndian32() but writing directly to the target array. |
657 static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target); | 739 static uint8* WriteLittleEndian32ToArray(uint32 value, uint8* target); |
658 // Write a 64-bit little-endian integer. | 740 // Write a 64-bit little-endian integer. |
659 void WriteLittleEndian64(uint64 value); | 741 void WriteLittleEndian64(uint64 value); |
660 // Like WriteLittleEndian64() but writing directly to the target array. | 742 // Like WriteLittleEndian64() but writing directly to the target array. |
661 static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target); | 743 static uint8* WriteLittleEndian64ToArray(uint64 value, uint8* target); |
662 | 744 |
663 // Write an unsigned integer with Varint encoding. Writing a 32-bit value | 745 // Write an unsigned integer with Varint encoding. Writing a 32-bit value |
(...skipping 13 matching lines...) Expand all Loading... |
677 // Like WriteVarint32SignExtended() but writing directly to the target array. | 759 // Like WriteVarint32SignExtended() but writing directly to the target array. |
678 static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target); | 760 static uint8* WriteVarint32SignExtendedToArray(int32 value, uint8* target); |
679 | 761 |
680 // This is identical to WriteVarint32(), but optimized for writing tags. | 762 // This is identical to WriteVarint32(), but optimized for writing tags. |
681 // In particular, if the input is a compile-time constant, this method | 763 // In particular, if the input is a compile-time constant, this method |
682 // compiles down to a couple instructions. | 764 // compiles down to a couple instructions. |
683 // Always inline because otherwise the aformentioned optimization can't work, | 765 // Always inline because otherwise the aformentioned optimization can't work, |
684 // but GCC by default doesn't want to inline this. | 766 // but GCC by default doesn't want to inline this. |
685 void WriteTag(uint32 value); | 767 void WriteTag(uint32 value); |
686 // Like WriteTag() but writing directly to the target array. | 768 // Like WriteTag() but writing directly to the target array. |
687 static uint8* WriteTagToArray( | 769 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteTagToArray(uint32 value, |
688 uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; | 770 uint8* target); |
689 | 771 |
690 // Returns the number of bytes needed to encode the given value as a varint. | 772 // Returns the number of bytes needed to encode the given value as a varint. |
691 static int VarintSize32(uint32 value); | 773 static int VarintSize32(uint32 value); |
692 // Returns the number of bytes needed to encode the given value as a varint. | 774 // Returns the number of bytes needed to encode the given value as a varint. |
693 static int VarintSize64(uint64 value); | 775 static int VarintSize64(uint64 value); |
694 | 776 |
695 // If negative, 10 bytes. Otheriwse, same as VarintSize32(). | 777 // If negative, 10 bytes. Otheriwse, same as VarintSize32(). |
696 static int VarintSize32SignExtended(int32 value); | 778 static int VarintSize32SignExtended(int32 value); |
697 | 779 |
698 // Compile-time equivalent of VarintSize32(). | 780 // Compile-time equivalent of VarintSize32(). |
(...skipping 19 matching lines...) Expand all Loading... |
718 bool HadError() const { return had_error_; } | 800 bool HadError() const { return had_error_; } |
719 | 801 |
720 private: | 802 private: |
721 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); | 803 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream); |
722 | 804 |
723 ZeroCopyOutputStream* output_; | 805 ZeroCopyOutputStream* output_; |
724 uint8* buffer_; | 806 uint8* buffer_; |
725 int buffer_size_; | 807 int buffer_size_; |
726 int total_bytes_; // Sum of sizes of all buffers seen so far. | 808 int total_bytes_; // Sum of sizes of all buffers seen so far. |
727 bool had_error_; // Whether an error occurred during output. | 809 bool had_error_; // Whether an error occurred during output. |
| 810 bool aliasing_enabled_; // See EnableAliasing(). |
728 | 811 |
729 // Advance the buffer by a given number of bytes. | 812 // Advance the buffer by a given number of bytes. |
730 void Advance(int amount); | 813 void Advance(int amount); |
731 | 814 |
732 // Called when the buffer runs out to request more data. Implies an | 815 // Called when the buffer runs out to request more data. Implies an |
733 // Advance(buffer_size_). | 816 // Advance(buffer_size_). |
734 bool Refresh(); | 817 bool Refresh(); |
735 | 818 |
736 static uint8* WriteVarint32FallbackToArray(uint32 value, uint8* target); | 819 // Like WriteRaw() but may avoid copying if the underlying |
| 820 // ZeroCopyOutputStream supports it. |
| 821 void WriteAliasedRaw(const void* buffer, int size); |
| 822 |
| 823 // If this write might cross the end of the buffer, we compose the bytes first |
| 824 // then use WriteRaw(). |
| 825 void WriteVarint32SlowPath(uint32 value); |
737 | 826 |
738 // Always-inlined versions of WriteVarint* functions so that code can be | 827 // Always-inlined versions of WriteVarint* functions so that code can be |
739 // reused, while still controlling size. For instance, WriteVarint32ToArray() | 828 // reused, while still controlling size. For instance, WriteVarint32ToArray() |
740 // should not directly call this: since it is inlined itself, doing so | 829 // should not directly call this: since it is inlined itself, doing so |
741 // would greatly increase the size of generated code. Instead, it should call | 830 // would greatly increase the size of generated code. Instead, it should call |
742 // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already | 831 // WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already |
743 // out-of-line, so it should just invoke this directly to avoid any extra | 832 // out-of-line, so it should just invoke this directly to avoid any extra |
744 // function call overhead. | 833 // function call overhead. |
745 static uint8* WriteVarint32FallbackToArrayInline( | 834 GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteVarint64ToArrayInline( |
746 uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; | 835 uint64 value, uint8* target); |
747 static uint8* WriteVarint64ToArrayInline( | |
748 uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE; | |
749 | 836 |
750 static int VarintSize32Fallback(uint32 value); | 837 static int VarintSize32Fallback(uint32 value); |
751 }; | 838 }; |
752 | 839 |
753 // inline methods ==================================================== | 840 // inline methods ==================================================== |
754 // The vast majority of varints are only one byte. These inline | 841 // The vast majority of varints are only one byte. These inline |
755 // methods optimize for that case. | 842 // methods optimize for that case. |
756 | 843 |
757 inline bool CodedInputStream::ReadVarint32(uint32* value) { | 844 inline bool CodedInputStream::ReadVarint32(uint32* value) { |
758 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { | 845 uint32 v = 0; |
759 *value = *buffer_; | 846 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { |
760 Advance(1); | 847 v = *buffer_; |
761 return true; | 848 if (v < 0x80) { |
762 } else { | 849 *value = v; |
763 return ReadVarint32Fallback(value); | 850 Advance(1); |
| 851 return true; |
| 852 } |
764 } | 853 } |
| 854 int64 result = ReadVarint32Fallback(v); |
| 855 *value = static_cast<uint32>(result); |
| 856 return result >= 0; |
765 } | 857 } |
766 | 858 |
767 inline bool CodedInputStream::ReadVarint64(uint64* value) { | 859 inline bool CodedInputStream::ReadVarint64(uint64* value) { |
768 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { | 860 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && *buffer_ < 0x80) { |
769 *value = *buffer_; | 861 *value = *buffer_; |
770 Advance(1); | 862 Advance(1); |
771 return true; | 863 return true; |
772 } else { | |
773 return ReadVarint64Fallback(value); | |
774 } | 864 } |
| 865 std::pair<uint64, bool> p = ReadVarint64Fallback(); |
| 866 *value = p.first; |
| 867 return p.second; |
775 } | 868 } |
776 | 869 |
777 // static | 870 // static |
778 inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( | 871 inline const uint8* CodedInputStream::ReadLittleEndian32FromArray( |
779 const uint8* buffer, | 872 const uint8* buffer, |
780 uint32* value) { | 873 uint32* value) { |
781 #if defined(PROTOBUF_LITTLE_ENDIAN) | 874 #if defined(PROTOBUF_LITTLE_ENDIAN) |
782 memcpy(value, buffer, sizeof(*value)); | 875 memcpy(value, buffer, sizeof(*value)); |
783 return buffer + sizeof(*value); | 876 return buffer + sizeof(*value); |
784 #else | 877 #else |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 return true; | 926 return true; |
834 } else { | 927 } else { |
835 return ReadLittleEndian64Fallback(value); | 928 return ReadLittleEndian64Fallback(value); |
836 } | 929 } |
837 #else | 930 #else |
838 return ReadLittleEndian64Fallback(value); | 931 return ReadLittleEndian64Fallback(value); |
839 #endif | 932 #endif |
840 } | 933 } |
841 | 934 |
842 inline uint32 CodedInputStream::ReadTag() { | 935 inline uint32 CodedInputStream::ReadTag() { |
843 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_) && buffer_[0] < 0x80) { | 936 uint32 v = 0; |
844 last_tag_ = buffer_[0]; | 937 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { |
845 Advance(1); | 938 v = *buffer_; |
846 return last_tag_; | 939 if (v < 0x80) { |
847 } else { | 940 last_tag_ = v; |
848 last_tag_ = ReadTagFallback(); | 941 Advance(1); |
849 return last_tag_; | 942 return v; |
| 943 } |
850 } | 944 } |
| 945 last_tag_ = ReadTagFallback(v); |
| 946 return last_tag_; |
| 947 } |
| 948 |
| 949 inline std::pair<uint32, bool> CodedInputStream::ReadTagWithCutoff( |
| 950 uint32 cutoff) { |
| 951 // In performance-sensitive code we can expect cutoff to be a compile-time |
| 952 // constant, and things like "cutoff >= kMax1ByteVarint" to be evaluated at |
| 953 // compile time. |
| 954 uint32 first_byte_or_zero = 0; |
| 955 if (GOOGLE_PREDICT_TRUE(buffer_ < buffer_end_)) { |
| 956 // Hot case: buffer_ non_empty, buffer_[0] in [1, 128). |
| 957 // TODO(gpike): Is it worth rearranging this? E.g., if the number of fields |
| 958 // is large enough then is it better to check for the two-byte case first? |
| 959 first_byte_or_zero = buffer_[0]; |
| 960 if (static_cast<int8>(buffer_[0]) > 0) { |
| 961 const uint32 kMax1ByteVarint = 0x7f; |
| 962 uint32 tag = last_tag_ = buffer_[0]; |
| 963 Advance(1); |
| 964 return std::make_pair(tag, cutoff >= kMax1ByteVarint || tag <= cutoff); |
| 965 } |
| 966 // Other hot case: cutoff >= 0x80, buffer_ has at least two bytes available, |
| 967 // and tag is two bytes. The latter is tested by bitwise-and-not of the |
| 968 // first byte and the second byte. |
| 969 if (cutoff >= 0x80 && |
| 970 GOOGLE_PREDICT_TRUE(buffer_ + 1 < buffer_end_) && |
| 971 GOOGLE_PREDICT_TRUE((buffer_[0] & ~buffer_[1]) >= 0x80)) { |
| 972 const uint32 kMax2ByteVarint = (0x7f << 7) + 0x7f; |
| 973 uint32 tag = last_tag_ = (1u << 7) * buffer_[1] + (buffer_[0] - 0x80); |
| 974 Advance(2); |
| 975 // It might make sense to test for tag == 0 now, but it is so rare that |
| 976 // that we don't bother. A varint-encoded 0 should be one byte unless |
| 977 // the encoder lost its mind. The second part of the return value of |
| 978 // this function is allowed to be either true or false if the tag is 0, |
| 979 // so we don't have to check for tag == 0. We may need to check whether |
| 980 // it exceeds cutoff. |
| 981 bool at_or_below_cutoff = cutoff >= kMax2ByteVarint || tag <= cutoff; |
| 982 return std::make_pair(tag, at_or_below_cutoff); |
| 983 } |
| 984 } |
| 985 // Slow path |
| 986 last_tag_ = ReadTagFallback(first_byte_or_zero); |
| 987 return std::make_pair(last_tag_, static_cast<uint32>(last_tag_ - 1) < cutoff); |
851 } | 988 } |
852 | 989 |
853 inline bool CodedInputStream::LastTagWas(uint32 expected) { | 990 inline bool CodedInputStream::LastTagWas(uint32 expected) { |
854 return last_tag_ == expected; | 991 return last_tag_ == expected; |
855 } | 992 } |
856 | 993 |
857 inline bool CodedInputStream::ConsumedEntireMessage() { | 994 inline bool CodedInputStream::ConsumedEntireMessage() { |
858 return legitimate_message_end_; | 995 return legitimate_message_end_; |
859 } | 996 } |
860 | 997 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 buffer[1] == static_cast<uint8>(expected >> 7)) { | 1029 buffer[1] == static_cast<uint8>(expected >> 7)) { |
893 return buffer + 2; | 1030 return buffer + 2; |
894 } | 1031 } |
895 } | 1032 } |
896 return NULL; | 1033 return NULL; |
897 } | 1034 } |
898 | 1035 |
899 inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, | 1036 inline void CodedInputStream::GetDirectBufferPointerInline(const void** data, |
900 int* size) { | 1037 int* size) { |
901 *data = buffer_; | 1038 *data = buffer_; |
902 *size = buffer_end_ - buffer_; | 1039 *size = static_cast<int>(buffer_end_ - buffer_); |
903 } | 1040 } |
904 | 1041 |
905 inline bool CodedInputStream::ExpectAtEnd() { | 1042 inline bool CodedInputStream::ExpectAtEnd() { |
906 // If we are at a limit we know no more bytes can be read. Otherwise, it's | 1043 // If we are at a limit we know no more bytes can be read. Otherwise, it's |
907 // hard to say without calling Refresh(), and we'd rather not do that. | 1044 // hard to say without calling Refresh(), and we'd rather not do that. |
908 | 1045 |
909 if (buffer_ == buffer_end_ && | 1046 if (buffer_ == buffer_end_ && |
910 ((buffer_size_after_limit_ != 0) || | 1047 ((buffer_size_after_limit_ != 0) || |
911 (total_bytes_read_ == current_limit_))) { | 1048 (total_bytes_read_ == current_limit_))) { |
912 last_tag_ = 0; // Pretend we called ReadTag()... | 1049 last_tag_ = 0; // Pretend we called ReadTag()... |
(...skipping 12 matching lines...) Expand all Loading... |
925 if (buffer_size_ < size) { | 1062 if (buffer_size_ < size) { |
926 return NULL; | 1063 return NULL; |
927 } else { | 1064 } else { |
928 uint8* result = buffer_; | 1065 uint8* result = buffer_; |
929 Advance(size); | 1066 Advance(size); |
930 return result; | 1067 return result; |
931 } | 1068 } |
932 } | 1069 } |
933 | 1070 |
934 inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value, | 1071 inline uint8* CodedOutputStream::WriteVarint32ToArray(uint32 value, |
935 uint8* target) { | 1072 uint8* target) { |
936 if (value < 0x80) { | 1073 while (value >= 0x80) { |
937 *target = value; | 1074 *target = static_cast<uint8>(value | 0x80); |
938 return target + 1; | 1075 value >>= 7; |
939 } else { | 1076 ++target; |
940 return WriteVarint32FallbackToArray(value, target); | |
941 } | 1077 } |
| 1078 *target = static_cast<uint8>(value); |
| 1079 return target + 1; |
942 } | 1080 } |
943 | 1081 |
944 inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { | 1082 inline void CodedOutputStream::WriteVarint32SignExtended(int32 value) { |
945 if (value < 0) { | 1083 if (value < 0) { |
946 WriteVarint64(static_cast<uint64>(value)); | 1084 WriteVarint64(static_cast<uint64>(value)); |
947 } else { | 1085 } else { |
948 WriteVarint32(static_cast<uint32>(value)); | 1086 WriteVarint32(static_cast<uint32>(value)); |
949 } | 1087 } |
950 } | 1088 } |
951 | 1089 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 target[2] = static_cast<uint8>(part0 >> 16); | 1122 target[2] = static_cast<uint8>(part0 >> 16); |
985 target[3] = static_cast<uint8>(part0 >> 24); | 1123 target[3] = static_cast<uint8>(part0 >> 24); |
986 target[4] = static_cast<uint8>(part1); | 1124 target[4] = static_cast<uint8>(part1); |
987 target[5] = static_cast<uint8>(part1 >> 8); | 1125 target[5] = static_cast<uint8>(part1 >> 8); |
988 target[6] = static_cast<uint8>(part1 >> 16); | 1126 target[6] = static_cast<uint8>(part1 >> 16); |
989 target[7] = static_cast<uint8>(part1 >> 24); | 1127 target[7] = static_cast<uint8>(part1 >> 24); |
990 #endif | 1128 #endif |
991 return target + sizeof(value); | 1129 return target + sizeof(value); |
992 } | 1130 } |
993 | 1131 |
| 1132 inline void CodedOutputStream::WriteVarint32(uint32 value) { |
| 1133 if (buffer_size_ >= 5) { |
| 1134 // Fast path: We have enough bytes left in the buffer to guarantee that |
| 1135 // this write won't cross the end, so we can skip the checks. |
| 1136 uint8* target = buffer_; |
| 1137 uint8* end = WriteVarint32ToArray(value, target); |
| 1138 int size = end - target; |
| 1139 Advance(size); |
| 1140 } else { |
| 1141 WriteVarint32SlowPath(value); |
| 1142 } |
| 1143 } |
| 1144 |
994 inline void CodedOutputStream::WriteTag(uint32 value) { | 1145 inline void CodedOutputStream::WriteTag(uint32 value) { |
995 WriteVarint32(value); | 1146 WriteVarint32(value); |
996 } | 1147 } |
997 | 1148 |
998 inline uint8* CodedOutputStream::WriteTagToArray( | 1149 inline uint8* CodedOutputStream::WriteTagToArray( |
999 uint32 value, uint8* target) { | 1150 uint32 value, uint8* target) { |
1000 if (value < (1 << 7)) { | 1151 return WriteVarint32ToArray(value, target); |
1001 target[0] = value; | |
1002 return target + 1; | |
1003 } else if (value < (1 << 14)) { | |
1004 target[0] = static_cast<uint8>(value | 0x80); | |
1005 target[1] = static_cast<uint8>(value >> 7); | |
1006 return target + 2; | |
1007 } else { | |
1008 return WriteVarint32FallbackToArray(value, target); | |
1009 } | |
1010 } | 1152 } |
1011 | 1153 |
1012 inline int CodedOutputStream::VarintSize32(uint32 value) { | 1154 inline int CodedOutputStream::VarintSize32(uint32 value) { |
1013 if (value < (1 << 7)) { | 1155 if (value < (1 << 7)) { |
1014 return 1; | 1156 return 1; |
1015 } else { | 1157 } else { |
1016 return VarintSize32Fallback(value); | 1158 return VarintSize32Fallback(value); |
1017 } | 1159 } |
1018 } | 1160 } |
1019 | 1161 |
1020 inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { | 1162 inline int CodedOutputStream::VarintSize32SignExtended(int32 value) { |
1021 if (value < 0) { | 1163 if (value < 0) { |
1022 return 10; // TODO(kenton): Make this a symbolic constant. | 1164 return 10; // TODO(kenton): Make this a symbolic constant. |
1023 } else { | 1165 } else { |
1024 return VarintSize32(static_cast<uint32>(value)); | 1166 return VarintSize32(static_cast<uint32>(value)); |
1025 } | 1167 } |
1026 } | 1168 } |
1027 | 1169 |
1028 inline void CodedOutputStream::WriteString(const string& str) { | 1170 inline void CodedOutputStream::WriteString(const string& str) { |
1029 WriteRaw(str.data(), static_cast<int>(str.size())); | 1171 WriteRaw(str.data(), static_cast<int>(str.size())); |
1030 } | 1172 } |
1031 | 1173 |
| 1174 inline void CodedOutputStream::WriteRawMaybeAliased( |
| 1175 const void* data, int size) { |
| 1176 if (aliasing_enabled_) { |
| 1177 WriteAliasedRaw(data, size); |
| 1178 } else { |
| 1179 WriteRaw(data, size); |
| 1180 } |
| 1181 } |
| 1182 |
1032 inline uint8* CodedOutputStream::WriteStringToArray( | 1183 inline uint8* CodedOutputStream::WriteStringToArray( |
1033 const string& str, uint8* target) { | 1184 const string& str, uint8* target) { |
1034 return WriteRawToArray(str.data(), static_cast<int>(str.size()), target); | 1185 return WriteRawToArray(str.data(), static_cast<int>(str.size()), target); |
1035 } | 1186 } |
1036 | 1187 |
1037 inline int CodedOutputStream::ByteCount() const { | 1188 inline int CodedOutputStream::ByteCount() const { |
1038 return total_bytes_ - buffer_size_; | 1189 return total_bytes_ - buffer_size_; |
1039 } | 1190 } |
1040 | 1191 |
1041 inline void CodedInputStream::Advance(int amount) { | 1192 inline void CodedInputStream::Advance(int amount) { |
1042 buffer_ += amount; | 1193 buffer_ += amount; |
1043 } | 1194 } |
1044 | 1195 |
1045 inline void CodedOutputStream::Advance(int amount) { | 1196 inline void CodedOutputStream::Advance(int amount) { |
1046 buffer_ += amount; | 1197 buffer_ += amount; |
1047 buffer_size_ -= amount; | 1198 buffer_size_ -= amount; |
1048 } | 1199 } |
1049 | 1200 |
1050 inline void CodedInputStream::SetRecursionLimit(int limit) { | 1201 inline void CodedInputStream::SetRecursionLimit(int limit) { |
| 1202 recursion_budget_ += limit - recursion_limit_; |
1051 recursion_limit_ = limit; | 1203 recursion_limit_ = limit; |
1052 } | 1204 } |
1053 | 1205 |
1054 inline bool CodedInputStream::IncrementRecursionDepth() { | 1206 inline bool CodedInputStream::IncrementRecursionDepth() { |
1055 ++recursion_depth_; | 1207 --recursion_budget_; |
1056 return recursion_depth_ <= recursion_limit_; | 1208 return recursion_budget_ >= 0; |
1057 } | 1209 } |
1058 | 1210 |
1059 inline void CodedInputStream::DecrementRecursionDepth() { | 1211 inline void CodedInputStream::DecrementRecursionDepth() { |
1060 if (recursion_depth_ > 0) --recursion_depth_; | 1212 if (recursion_budget_ < recursion_limit_) ++recursion_budget_; |
| 1213 } |
| 1214 |
| 1215 inline void CodedInputStream::UnsafeDecrementRecursionDepth() { |
| 1216 assert(recursion_budget_ < recursion_limit_); |
| 1217 ++recursion_budget_; |
1061 } | 1218 } |
1062 | 1219 |
1063 inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool, | 1220 inline void CodedInputStream::SetExtensionRegistry(const DescriptorPool* pool, |
1064 MessageFactory* factory) { | 1221 MessageFactory* factory) { |
1065 extension_pool_ = pool; | 1222 extension_pool_ = pool; |
1066 extension_factory_ = factory; | 1223 extension_factory_ = factory; |
1067 } | 1224 } |
1068 | 1225 |
1069 inline const DescriptorPool* CodedInputStream::GetExtensionPool() { | 1226 inline const DescriptorPool* CodedInputStream::GetExtensionPool() { |
1070 return extension_pool_; | 1227 return extension_pool_; |
1071 } | 1228 } |
1072 | 1229 |
1073 inline MessageFactory* CodedInputStream::GetExtensionFactory() { | 1230 inline MessageFactory* CodedInputStream::GetExtensionFactory() { |
1074 return extension_factory_; | 1231 return extension_factory_; |
1075 } | 1232 } |
1076 | 1233 |
1077 inline int CodedInputStream::BufferSize() const { | 1234 inline int CodedInputStream::BufferSize() const { |
1078 return buffer_end_ - buffer_; | 1235 return static_cast<int>(buffer_end_ - buffer_); |
1079 } | 1236 } |
1080 | 1237 |
1081 inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) | 1238 inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) |
1082 : input_(input), | 1239 : buffer_(NULL), |
1083 buffer_(NULL), | |
1084 buffer_end_(NULL), | 1240 buffer_end_(NULL), |
| 1241 input_(input), |
1085 total_bytes_read_(0), | 1242 total_bytes_read_(0), |
1086 overflow_bytes_(0), | 1243 overflow_bytes_(0), |
1087 last_tag_(0), | 1244 last_tag_(0), |
1088 legitimate_message_end_(false), | 1245 legitimate_message_end_(false), |
1089 aliasing_enabled_(false), | 1246 aliasing_enabled_(false), |
1090 current_limit_(kint32max), | 1247 current_limit_(kint32max), |
1091 buffer_size_after_limit_(0), | 1248 buffer_size_after_limit_(0), |
1092 total_bytes_limit_(kDefaultTotalBytesLimit), | 1249 total_bytes_limit_(kDefaultTotalBytesLimit), |
1093 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), | 1250 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), |
1094 recursion_depth_(0), | 1251 recursion_budget_(default_recursion_limit_), |
1095 recursion_limit_(default_recursion_limit_), | 1252 recursion_limit_(default_recursion_limit_), |
1096 extension_pool_(NULL), | 1253 extension_pool_(NULL), |
1097 extension_factory_(NULL) { | 1254 extension_factory_(NULL) { |
1098 // Eagerly Refresh() so buffer space is immediately available. | 1255 // Eagerly Refresh() so buffer space is immediately available. |
1099 Refresh(); | 1256 Refresh(); |
1100 } | 1257 } |
1101 | 1258 |
1102 inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) | 1259 inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) |
1103 : input_(NULL), | 1260 : buffer_(buffer), |
1104 buffer_(buffer), | |
1105 buffer_end_(buffer + size), | 1261 buffer_end_(buffer + size), |
| 1262 input_(NULL), |
1106 total_bytes_read_(size), | 1263 total_bytes_read_(size), |
1107 overflow_bytes_(0), | 1264 overflow_bytes_(0), |
1108 last_tag_(0), | 1265 last_tag_(0), |
1109 legitimate_message_end_(false), | 1266 legitimate_message_end_(false), |
1110 aliasing_enabled_(false), | 1267 aliasing_enabled_(false), |
1111 current_limit_(size), | 1268 current_limit_(size), |
1112 buffer_size_after_limit_(0), | 1269 buffer_size_after_limit_(0), |
1113 total_bytes_limit_(kDefaultTotalBytesLimit), | 1270 total_bytes_limit_(kDefaultTotalBytesLimit), |
1114 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), | 1271 total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), |
1115 recursion_depth_(0), | 1272 recursion_budget_(default_recursion_limit_), |
1116 recursion_limit_(default_recursion_limit_), | 1273 recursion_limit_(default_recursion_limit_), |
1117 extension_pool_(NULL), | 1274 extension_pool_(NULL), |
1118 extension_factory_(NULL) { | 1275 extension_factory_(NULL) { |
1119 // Note that setting current_limit_ == size is important to prevent some | 1276 // Note that setting current_limit_ == size is important to prevent some |
1120 // code paths from trying to access input_ and segfaulting. | 1277 // code paths from trying to access input_ and segfaulting. |
1121 } | 1278 } |
1122 | 1279 |
1123 inline bool CodedInputStream::IsFlat() const { | 1280 inline bool CodedInputStream::IsFlat() const { |
1124 return input_ == NULL; | 1281 return input_ == NULL; |
1125 } | 1282 } |
1126 | 1283 |
1127 } // namespace io | 1284 } // namespace io |
1128 } // namespace protobuf | 1285 } // namespace protobuf |
1129 | 1286 |
1130 | 1287 |
1131 #if defined(_MSC_VER) && _MSC_VER >= 1300 | 1288 #if defined(_MSC_VER) && _MSC_VER >= 1300 |
1132 #pragma runtime_checks("c", restore) | 1289 #pragma runtime_checks("c", restore) |
1133 #endif // _MSC_VER | 1290 #endif // _MSC_VER |
1134 | 1291 |
1135 } // namespace google | 1292 } // namespace google |
1136 #endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ | 1293 #endif // GOOGLE_PROTOBUF_IO_CODED_STREAM_H__ |
OLD | NEW |