~statik/ubuntu/maverick/protobuf/A

« back to all changes in this revision

Viewing changes to src/google/protobuf/io/coded_stream.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:
80
80
    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
81
81
    recursion_depth_(0),
82
82
    recursion_limit_(kDefaultRecursionLimit) {
 
83
  // Eagerly Refresh() so buffer space is immediately available.
 
84
  Refresh();
 
85
}
 
86
 
 
87
CodedInputStream::CodedInputStream(const uint8* buffer, int size)
 
88
  : input_(NULL),
 
89
    buffer_(buffer),
 
90
    buffer_size_(size),
 
91
    total_bytes_read_(size),
 
92
    overflow_bytes_(0),
 
93
    last_tag_(0),
 
94
    legitimate_message_end_(false),
 
95
    aliasing_enabled_(false),
 
96
    current_limit_(size),
 
97
    buffer_size_after_limit_(0),
 
98
    total_bytes_limit_(kDefaultTotalBytesLimit),
 
99
    total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold),
 
100
    recursion_depth_(0),
 
101
    recursion_limit_(kDefaultRecursionLimit) {
 
102
  // Note that setting current_limit_ == size is important to prevent some
 
103
  // code paths from trying to access input_ and segfaulting.
83
104
}
84
105
 
85
106
CodedInputStream::~CodedInputStream() {
 
107
  if (input_ != NULL) {
 
108
    BackUpInputToCurrentPosition();
 
109
  }
 
110
}
 
111
 
 
112
 
 
113
void CodedInputStream::BackUpInputToCurrentPosition() {
86
114
  int backup_bytes = buffer_size_ + buffer_size_after_limit_ + overflow_bytes_;
87
115
  if (backup_bytes > 0) {
88
 
    // We still have bytes left over from the last buffer.  Back up over
89
 
    // them.
90
116
    input_->BackUp(backup_bytes);
 
117
 
 
118
    // total_bytes_read_ doesn't include overflow_bytes_.
 
119
    total_bytes_read_ -= buffer_size_ + buffer_size_after_limit_;
 
120
    buffer_size_ = 0;
 
121
    buffer_size_after_limit_ = 0;
 
122
    overflow_bytes_ = 0;
91
123
  }
92
124
}
93
125
 
94
 
 
95
126
inline void CodedInputStream::RecomputeBufferLimits() {
96
127
  buffer_size_ += buffer_size_after_limit_;
97
128
  int closest_limit = min(current_limit_, total_bytes_limit_);
193
224
  int bytes_until_limit = closest_limit - total_bytes_read_;
194
225
  if (bytes_until_limit < count) {
195
226
    // We hit the limit.  Skip up to it then fail.
196
 
    total_bytes_read_ = closest_limit;
197
 
    input_->Skip(bytes_until_limit);
 
227
    if (bytes_until_limit > 0) {
 
228
      total_bytes_read_ = closest_limit;
 
229
      input_->Skip(bytes_until_limit);
 
230
    }
198
231
    return false;
199
232
  }
200
233
 
216
249
    memcpy(buffer, buffer_, buffer_size_);
217
250
    buffer = reinterpret_cast<uint8*>(buffer) + buffer_size_;
218
251
    size -= buffer_size_;
 
252
    Advance(buffer_size_);
219
253
    if (!Refresh()) return false;
220
254
  }
221
255
 
247
281
      buffer->append(reinterpret_cast<const char*>(buffer_), buffer_size_);
248
282
    }
249
283
    size -= buffer_size_;
 
284
    Advance(buffer_size_);
250
285
    if (!Refresh()) return false;
251
286
  }
252
287
 
441
476
}
442
477
 
443
478
bool CodedInputStream::Refresh() {
444
 
  if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0) {
 
479
  GOOGLE_DCHECK_EQ(buffer_size_, 0);
 
480
 
 
481
  if (buffer_size_after_limit_ > 0 || overflow_bytes_ > 0 ||
 
482
      total_bytes_read_ == current_limit_) {
445
483
    // We've hit a limit.  Stop.
446
 
    buffer_ += buffer_size_;
447
 
    buffer_size_ = 0;
448
 
 
449
484
    int current_position = total_bytes_read_ - buffer_size_after_limit_;
450
485
 
451
486
    if (current_position >= total_bytes_limit_ &&
570
605
  bool use_fast = buffer_size_ >= sizeof(value);
571
606
  uint8* ptr = use_fast ? buffer_ : bytes;
572
607
 
573
 
  ptr[0] = static_cast<uint8>(value      );
574
 
  ptr[1] = static_cast<uint8>(value >>  8);
575
 
  ptr[2] = static_cast<uint8>(value >> 16);
576
 
  ptr[3] = static_cast<uint8>(value >> 24);
 
608
  WriteLittleEndian32ToArray(value, ptr);
577
609
 
578
610
  if (use_fast) {
579
611
    Advance(sizeof(value));
582
614
  }
583
615
}
584
616
 
585
 
uint8* CodedOutputStream::WriteLittleEndian32ToArray(
586
 
    uint32 value, uint8* target) {
587
 
  target[0] = static_cast<uint8>(value      );
588
 
  target[1] = static_cast<uint8>(value >>  8);
589
 
  target[2] = static_cast<uint8>(value >> 16);
590
 
  target[3] = static_cast<uint8>(value >> 24);
591
 
  return target + sizeof(value);
592
 
}
593
 
 
594
617
void CodedOutputStream::WriteLittleEndian64(uint64 value) {
595
618
  uint8 bytes[sizeof(value)];
596
619
 
597
 
  uint32 part0 = static_cast<uint32>(value);
598
 
  uint32 part1 = static_cast<uint32>(value >> 32);
599
 
 
600
620
  bool use_fast = buffer_size_ >= sizeof(value);
601
621
  uint8* ptr = use_fast ? buffer_ : bytes;
602
622
 
603
 
  ptr[0] = static_cast<uint8>(part0      );
604
 
  ptr[1] = static_cast<uint8>(part0 >>  8);
605
 
  ptr[2] = static_cast<uint8>(part0 >> 16);
606
 
  ptr[3] = static_cast<uint8>(part0 >> 24);
607
 
  ptr[4] = static_cast<uint8>(part1      );
608
 
  ptr[5] = static_cast<uint8>(part1 >>  8);
609
 
  ptr[6] = static_cast<uint8>(part1 >> 16);
610
 
  ptr[7] = static_cast<uint8>(part1 >> 24);
 
623
  WriteLittleEndian64ToArray(value, ptr);
611
624
 
612
625
  if (use_fast) {
613
626
    Advance(sizeof(value));
616
629
  }
617
630
}
618
631
 
619
 
uint8* CodedOutputStream::WriteLittleEndian64ToArray(
620
 
    uint64 value, uint8* target) {
621
 
  uint32 part0 = static_cast<uint32>(value);
622
 
  uint32 part1 = static_cast<uint32>(value >> 32);
623
 
 
624
 
  target[0] = static_cast<uint8>(part0      );
625
 
  target[1] = static_cast<uint8>(part0 >>  8);
626
 
  target[2] = static_cast<uint8>(part0 >> 16);
627
 
  target[3] = static_cast<uint8>(part0 >> 24);
628
 
  target[4] = static_cast<uint8>(part1      );
629
 
  target[5] = static_cast<uint8>(part1 >>  8);
630
 
  target[6] = static_cast<uint8>(part1 >> 16);
631
 
  target[7] = static_cast<uint8>(part1 >> 24);
632
 
 
633
 
  return target + sizeof(value);
634
 
}
635
 
 
636
632
inline uint8* CodedOutputStream::WriteVarint32FallbackToArrayInline(
637
633
    uint32 value, uint8* target) {
638
634
  target[0] = static_cast<uint8>(value | 0x80);