~ubuntu-branches/ubuntu/oneiric/mozc/oneiric

« back to all changes in this revision

Viewing changes to protobuf/files/src/google/protobuf/io/zero_copy_stream_impl_lite.cc

  • Committer: Bazaar Package Importer
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2010-07-14 03:26:47 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100714032647-13qjisj6m8cm8jdx
Tags: 0.12.410.102-1
* New upstream release (Closes: #588971).
  - Add mozc-server, mozc-utils-gui and scim-mozc packages.
* Update debian/rules.
  Add --gypdir option to build_mozc.py.
* Update debian/control.
  - Bumped standards-version to 3.9.0.
  - Update description.
* Add mozc icon (Closes: #588972).
* Add patch which revises issue 18.
  ibus_mozc_issue18.patch
* kFreeBSD build support.
  support_kfreebsd.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Protocol Buffers - Google's data interchange format
2
 
// Copyright 2008 Google Inc.  All rights reserved.
3
 
// http://code.google.com/p/protobuf/
4
 
//
5
 
// Redistribution and use in source and binary forms, with or without
6
 
// modification, are permitted provided that the following conditions are
7
 
// met:
8
 
//
9
 
//     * Redistributions of source code must retain the above copyright
10
 
// notice, this list of conditions and the following disclaimer.
11
 
//     * Redistributions in binary form must reproduce the above
12
 
// copyright notice, this list of conditions and the following disclaimer
13
 
// in the documentation and/or other materials provided with the
14
 
// distribution.
15
 
//     * Neither the name of Google Inc. nor the names of its
16
 
// contributors may be used to endorse or promote products derived from
17
 
// this software without specific prior written permission.
18
 
//
19
 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
 
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
 
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
 
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
 
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
 
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
 
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
 
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
 
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
 
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
 
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 
 
31
 
// Author: kenton@google.com (Kenton Varda)
32
 
//  Based on original Protocol Buffers design by
33
 
//  Sanjay Ghemawat, Jeff Dean, and others.
34
 
 
35
 
#include <google/protobuf/io/zero_copy_stream_impl.h>
36
 
#include <google/protobuf/stubs/common.h>
37
 
#include <google/protobuf/stubs/stl_util-inl.h>
38
 
 
39
 
namespace google {
40
 
namespace protobuf {
41
 
namespace io {
42
 
 
43
 
namespace {
44
 
 
45
 
// Default block size for Copying{In,Out}putStreamAdaptor.
46
 
static const int kDefaultBlockSize = 8192;
47
 
 
48
 
}  // namespace
49
 
 
50
 
// ===================================================================
51
 
 
52
 
ArrayInputStream::ArrayInputStream(const void* data, int size,
53
 
                                   int block_size)
54
 
  : data_(reinterpret_cast<const uint8*>(data)),
55
 
    size_(size),
56
 
    block_size_(block_size > 0 ? block_size : size),
57
 
    position_(0),
58
 
    last_returned_size_(0) {
59
 
}
60
 
 
61
 
ArrayInputStream::~ArrayInputStream() {
62
 
}
63
 
 
64
 
bool ArrayInputStream::Next(const void** data, int* size) {
65
 
  if (position_ < size_) {
66
 
    last_returned_size_ = min(block_size_, size_ - position_);
67
 
    *data = data_ + position_;
68
 
    *size = last_returned_size_;
69
 
    position_ += last_returned_size_;
70
 
    return true;
71
 
  } else {
72
 
    // We're at the end of the array.
73
 
    last_returned_size_ = 0;   // Don't let caller back up.
74
 
    return false;
75
 
  }
76
 
}
77
 
 
78
 
void ArrayInputStream::BackUp(int count) {
79
 
  GOOGLE_CHECK_GT(last_returned_size_, 0)
80
 
      << "BackUp() can only be called after a successful Next().";
81
 
  GOOGLE_CHECK_LE(count, last_returned_size_);
82
 
  GOOGLE_CHECK_GE(count, 0);
83
 
  position_ -= count;
84
 
  last_returned_size_ = 0;  // Don't let caller back up further.
85
 
}
86
 
 
87
 
bool ArrayInputStream::Skip(int count) {
88
 
  GOOGLE_CHECK_GE(count, 0);
89
 
  last_returned_size_ = 0;   // Don't let caller back up.
90
 
  if (count > size_ - position_) {
91
 
    position_ = size_;
92
 
    return false;
93
 
  } else {
94
 
    position_ += count;
95
 
    return true;
96
 
  }
97
 
}
98
 
 
99
 
int64 ArrayInputStream::ByteCount() const {
100
 
  return position_;
101
 
}
102
 
 
103
 
 
104
 
// ===================================================================
105
 
 
106
 
ArrayOutputStream::ArrayOutputStream(void* data, int size, int block_size)
107
 
  : data_(reinterpret_cast<uint8*>(data)),
108
 
    size_(size),
109
 
    block_size_(block_size > 0 ? block_size : size),
110
 
    position_(0),
111
 
    last_returned_size_(0) {
112
 
}
113
 
 
114
 
ArrayOutputStream::~ArrayOutputStream() {
115
 
}
116
 
 
117
 
bool ArrayOutputStream::Next(void** data, int* size) {
118
 
  if (position_ < size_) {
119
 
    last_returned_size_ = min(block_size_, size_ - position_);
120
 
    *data = data_ + position_;
121
 
    *size = last_returned_size_;
122
 
    position_ += last_returned_size_;
123
 
    return true;
124
 
  } else {
125
 
    // We're at the end of the array.
126
 
    last_returned_size_ = 0;   // Don't let caller back up.
127
 
    return false;
128
 
  }
129
 
}
130
 
 
131
 
void ArrayOutputStream::BackUp(int count) {
132
 
  GOOGLE_CHECK_GT(last_returned_size_, 0)
133
 
      << "BackUp() can only be called after a successful Next().";
134
 
  GOOGLE_CHECK_LE(count, last_returned_size_);
135
 
  GOOGLE_CHECK_GE(count, 0);
136
 
  position_ -= count;
137
 
  last_returned_size_ = 0;  // Don't let caller back up further.
138
 
}
139
 
 
140
 
int64 ArrayOutputStream::ByteCount() const {
141
 
  return position_;
142
 
}
143
 
 
144
 
// ===================================================================
145
 
 
146
 
StringOutputStream::StringOutputStream(string* target)
147
 
  : target_(target) {
148
 
}
149
 
 
150
 
StringOutputStream::~StringOutputStream() {
151
 
}
152
 
 
153
 
bool StringOutputStream::Next(void** data, int* size) {
154
 
  int old_size = target_->size();
155
 
 
156
 
  // Grow the string.
157
 
  if (old_size < target_->capacity()) {
158
 
    // Resize the string to match its capacity, since we can get away
159
 
    // without a memory allocation this way.
160
 
    STLStringResizeUninitialized(target_, target_->capacity());
161
 
  } else {
162
 
    // Size has reached capacity, so double the size.  Also make sure
163
 
    // that the new size is at least kMinimumSize.
164
 
    STLStringResizeUninitialized(
165
 
      target_,
166
 
      max(old_size * 2,
167
 
          kMinimumSize + 0));  // "+ 0" works around GCC4 weirdness.
168
 
  }
169
 
 
170
 
  *data = string_as_array(target_) + old_size;
171
 
  *size = target_->size() - old_size;
172
 
  return true;
173
 
}
174
 
 
175
 
void StringOutputStream::BackUp(int count) {
176
 
  GOOGLE_CHECK_GE(count, 0);
177
 
  GOOGLE_CHECK_LE(count, target_->size());
178
 
  target_->resize(target_->size() - count);
179
 
}
180
 
 
181
 
int64 StringOutputStream::ByteCount() const {
182
 
  return target_->size();
183
 
}
184
 
 
185
 
// ===================================================================
186
 
 
187
 
CopyingInputStream::~CopyingInputStream() {}
188
 
 
189
 
int CopyingInputStream::Skip(int count) {
190
 
  char junk[4096];
191
 
  int skipped = 0;
192
 
  while (skipped < count) {
193
 
    int bytes = Read(junk, min(count - skipped,
194
 
                               implicit_cast<int>(sizeof(junk))));
195
 
    if (bytes <= 0) {
196
 
      // EOF or read error.
197
 
      return skipped;
198
 
    }
199
 
    skipped += bytes;
200
 
  }
201
 
  return skipped;
202
 
}
203
 
 
204
 
CopyingInputStreamAdaptor::CopyingInputStreamAdaptor(
205
 
    CopyingInputStream* copying_stream, int block_size)
206
 
  : copying_stream_(copying_stream),
207
 
    owns_copying_stream_(false),
208
 
    failed_(false),
209
 
    position_(0),
210
 
    buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
211
 
    buffer_used_(0),
212
 
    backup_bytes_(0) {
213
 
}
214
 
 
215
 
CopyingInputStreamAdaptor::~CopyingInputStreamAdaptor() {
216
 
  if (owns_copying_stream_) {
217
 
    delete copying_stream_;
218
 
  }
219
 
}
220
 
 
221
 
bool CopyingInputStreamAdaptor::Next(const void** data, int* size) {
222
 
  if (failed_) {
223
 
    // Already failed on a previous read.
224
 
    return false;
225
 
  }
226
 
 
227
 
  AllocateBufferIfNeeded();
228
 
 
229
 
  if (backup_bytes_ > 0) {
230
 
    // We have data left over from a previous BackUp(), so just return that.
231
 
    *data = buffer_.get() + buffer_used_ - backup_bytes_;
232
 
    *size = backup_bytes_;
233
 
    backup_bytes_ = 0;
234
 
    return true;
235
 
  }
236
 
 
237
 
  // Read new data into the buffer.
238
 
  buffer_used_ = copying_stream_->Read(buffer_.get(), buffer_size_);
239
 
  if (buffer_used_ <= 0) {
240
 
    // EOF or read error.  We don't need the buffer anymore.
241
 
    if (buffer_used_ < 0) {
242
 
      // Read error (not EOF).
243
 
      failed_ = true;
244
 
    }
245
 
    FreeBuffer();
246
 
    return false;
247
 
  }
248
 
  position_ += buffer_used_;
249
 
 
250
 
  *size = buffer_used_;
251
 
  *data = buffer_.get();
252
 
  return true;
253
 
}
254
 
 
255
 
void CopyingInputStreamAdaptor::BackUp(int count) {
256
 
  GOOGLE_CHECK(backup_bytes_ == 0 && buffer_.get() != NULL)
257
 
    << " BackUp() can only be called after Next().";
258
 
  GOOGLE_CHECK_LE(count, buffer_used_)
259
 
    << " Can't back up over more bytes than were returned by the last call"
260
 
       " to Next().";
261
 
  GOOGLE_CHECK_GE(count, 0)
262
 
    << " Parameter to BackUp() can't be negative.";
263
 
 
264
 
  backup_bytes_ = count;
265
 
}
266
 
 
267
 
bool CopyingInputStreamAdaptor::Skip(int count) {
268
 
  GOOGLE_CHECK_GE(count, 0);
269
 
 
270
 
  if (failed_) {
271
 
    // Already failed on a previous read.
272
 
    return false;
273
 
  }
274
 
 
275
 
  // First skip any bytes left over from a previous BackUp().
276
 
  if (backup_bytes_ >= count) {
277
 
    // We have more data left over than we're trying to skip.  Just chop it.
278
 
    backup_bytes_ -= count;
279
 
    return true;
280
 
  }
281
 
 
282
 
  count -= backup_bytes_;
283
 
  backup_bytes_ = 0;
284
 
 
285
 
  int skipped = copying_stream_->Skip(count);
286
 
  position_ += skipped;
287
 
  return skipped == count;
288
 
}
289
 
 
290
 
int64 CopyingInputStreamAdaptor::ByteCount() const {
291
 
  return position_ - backup_bytes_;
292
 
}
293
 
 
294
 
void CopyingInputStreamAdaptor::AllocateBufferIfNeeded() {
295
 
  if (buffer_.get() == NULL) {
296
 
    buffer_.reset(new uint8[buffer_size_]);
297
 
  }
298
 
}
299
 
 
300
 
void CopyingInputStreamAdaptor::FreeBuffer() {
301
 
  GOOGLE_CHECK_EQ(backup_bytes_, 0);
302
 
  buffer_used_ = 0;
303
 
  buffer_.reset();
304
 
}
305
 
 
306
 
// ===================================================================
307
 
 
308
 
CopyingOutputStream::~CopyingOutputStream() {}
309
 
 
310
 
CopyingOutputStreamAdaptor::CopyingOutputStreamAdaptor(
311
 
    CopyingOutputStream* copying_stream, int block_size)
312
 
  : copying_stream_(copying_stream),
313
 
    owns_copying_stream_(false),
314
 
    failed_(false),
315
 
    position_(0),
316
 
    buffer_size_(block_size > 0 ? block_size : kDefaultBlockSize),
317
 
    buffer_used_(0) {
318
 
}
319
 
 
320
 
CopyingOutputStreamAdaptor::~CopyingOutputStreamAdaptor() {
321
 
  WriteBuffer();
322
 
  if (owns_copying_stream_) {
323
 
    delete copying_stream_;
324
 
  }
325
 
}
326
 
 
327
 
bool CopyingOutputStreamAdaptor::Flush() {
328
 
  return WriteBuffer();
329
 
}
330
 
 
331
 
bool CopyingOutputStreamAdaptor::Next(void** data, int* size) {
332
 
  if (buffer_used_ == buffer_size_) {
333
 
    if (!WriteBuffer()) return false;
334
 
  }
335
 
 
336
 
  AllocateBufferIfNeeded();
337
 
 
338
 
  *data = buffer_.get() + buffer_used_;
339
 
  *size = buffer_size_ - buffer_used_;
340
 
  buffer_used_ = buffer_size_;
341
 
  return true;
342
 
}
343
 
 
344
 
void CopyingOutputStreamAdaptor::BackUp(int count) {
345
 
  GOOGLE_CHECK_GE(count, 0);
346
 
  GOOGLE_CHECK_EQ(buffer_used_, buffer_size_)
347
 
    << " BackUp() can only be called after Next().";
348
 
  GOOGLE_CHECK_LE(count, buffer_used_)
349
 
    << " Can't back up over more bytes than were returned by the last call"
350
 
       " to Next().";
351
 
 
352
 
  buffer_used_ -= count;
353
 
}
354
 
 
355
 
int64 CopyingOutputStreamAdaptor::ByteCount() const {
356
 
  return position_ + buffer_used_;
357
 
}
358
 
 
359
 
bool CopyingOutputStreamAdaptor::WriteBuffer() {
360
 
  if (failed_) {
361
 
    // Already failed on a previous write.
362
 
    return false;
363
 
  }
364
 
 
365
 
  if (buffer_used_ == 0) return true;
366
 
 
367
 
  if (copying_stream_->Write(buffer_.get(), buffer_used_)) {
368
 
    position_ += buffer_used_;
369
 
    buffer_used_ = 0;
370
 
    return true;
371
 
  } else {
372
 
    failed_ = true;
373
 
    FreeBuffer();
374
 
    return false;
375
 
  }
376
 
}
377
 
 
378
 
void CopyingOutputStreamAdaptor::AllocateBufferIfNeeded() {
379
 
  if (buffer_ == NULL) {
380
 
    buffer_.reset(new uint8[buffer_size_]);
381
 
  }
382
 
}
383
 
 
384
 
void CopyingOutputStreamAdaptor::FreeBuffer() {
385
 
  buffer_used_ = 0;
386
 
  buffer_.reset();
387
 
}
388
 
 
389
 
// ===================================================================
390
 
 
391
 
}  // namespace io
392
 
}  // namespace protobuf
393
 
}  // namespace google