Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
86 Kevin 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
package com.google.protobuf;
32
 
33
import java.io.OutputStream;
34
import java.io.IOException;
35
import java.io.UnsupportedEncodingException;
36
import java.io.InputStream;
37
 
38
/**
39
 * Encodes and writes protocol message fields.
40
 *
41
 * <p>This class contains two kinds of methods:  methods that write specific
42
 * protocol message constructs and field types (e.g. {@link #writeTag} and
43
 * {@link #writeInt32}) and methods that write low-level values (e.g.
44
 * {@link #writeRawVarint32} and {@link #writeRawBytes}).  If you are
45
 * writing encoded protocol messages, you should use the former methods, but if
46
 * you are writing some other format of your own design, use the latter.
47
 *
48
 * <p>This class is totally unsynchronized.
49
 *
50
 * @author kneton@google.com Kenton Varda
51
 */
52
public final class CodedOutputStream {
53
  private final byte[] buffer;
54
  private final int limit;
55
  private int position;
56
 
57
  private final OutputStream output;
58
 
59
  /**
60
   * The buffer size used in {@link #newInstance(OutputStream)}.
61
   */
62
  public static final int DEFAULT_BUFFER_SIZE = 4096;
63
 
64
  /**
65
   * Returns the buffer size to efficiently write dataLength bytes to this
66
   * CodedOutputStream. Used by AbstractMessageLite.
67
   *
68
   * @return the buffer size to efficiently write dataLength bytes to this
69
   *         CodedOutputStream.
70
   */
71
  static int computePreferredBufferSize(int dataLength) {
72
    if (dataLength > DEFAULT_BUFFER_SIZE) return DEFAULT_BUFFER_SIZE;
73
    return dataLength;
74
  }
75
 
76
  private CodedOutputStream(final byte[] buffer, final int offset,
77
                            final int length) {
78
    output = null;
79
    this.buffer = buffer;
80
    position = offset;
81
    limit = offset + length;
82
  }
83
 
84
  private CodedOutputStream(final OutputStream output, final byte[] buffer) {
85
    this.output = output;
86
    this.buffer = buffer;
87
    position = 0;
88
    limit = buffer.length;
89
  }
90
 
91
  /**
92
   * Create a new {@code CodedOutputStream} wrapping the given
93
   * {@code OutputStream}.
94
   */
95
  public static CodedOutputStream newInstance(final OutputStream output) {
96
    return newInstance(output, DEFAULT_BUFFER_SIZE);
97
  }
98
 
99
  /**
100
   * Create a new {@code CodedOutputStream} wrapping the given
101
   * {@code OutputStream} with a given buffer size.
102
   */
103
  public static CodedOutputStream newInstance(final OutputStream output,
104
      final int bufferSize) {
105
    return new CodedOutputStream(output, new byte[bufferSize]);
106
  }
107
 
108
  /**
109
   * Create a new {@code CodedOutputStream} that writes directly to the given
110
   * byte array.  If more bytes are written than fit in the array,
111
   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
112
   * array is faster than writing to an {@code OutputStream}.  See also
113
   * {@link ByteString#newCodedBuilder}.
114
   */
115
  public static CodedOutputStream newInstance(final byte[] flatArray) {
116
    return newInstance(flatArray, 0, flatArray.length);
117
  }
118
 
119
  /**
120
   * Create a new {@code CodedOutputStream} that writes directly to the given
121
   * byte array slice.  If more bytes are written than fit in the slice,
122
   * {@link OutOfSpaceException} will be thrown.  Writing directly to a flat
123
   * array is faster than writing to an {@code OutputStream}.  See also
124
   * {@link ByteString#newCodedBuilder}.
125
   */
126
  public static CodedOutputStream newInstance(final byte[] flatArray,
127
                                              final int offset,
128
                                              final int length) {
129
    return new CodedOutputStream(flatArray, offset, length);
130
  }
131
 
132
  // -----------------------------------------------------------------
133
 
134
  /** Write a {@code double} field, including tag, to the stream. */
135
  public void writeDouble(final int fieldNumber, final double value)
136
                          throws IOException {
137
    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
138
    writeDoubleNoTag(value);
139
  }
140
 
141
  /** Write a {@code float} field, including tag, to the stream. */
142
  public void writeFloat(final int fieldNumber, final float value)
143
                         throws IOException {
144
    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
145
    writeFloatNoTag(value);
146
  }
147
 
148
  /** Write a {@code uint64} field, including tag, to the stream. */
149
  public void writeUInt64(final int fieldNumber, final long value)
150
                          throws IOException {
151
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
152
    writeUInt64NoTag(value);
153
  }
154
 
155
  /** Write an {@code int64} field, including tag, to the stream. */
156
  public void writeInt64(final int fieldNumber, final long value)
157
                         throws IOException {
158
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
159
    writeInt64NoTag(value);
160
  }
161
 
162
  /** Write an {@code int32} field, including tag, to the stream. */
163
  public void writeInt32(final int fieldNumber, final int value)
164
                         throws IOException {
165
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
166
    writeInt32NoTag(value);
167
  }
168
 
169
  /** Write a {@code fixed64} field, including tag, to the stream. */
170
  public void writeFixed64(final int fieldNumber, final long value)
171
                           throws IOException {
172
    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
173
    writeFixed64NoTag(value);
174
  }
175
 
176
  /** Write a {@code fixed32} field, including tag, to the stream. */
177
  public void writeFixed32(final int fieldNumber, final int value)
178
                           throws IOException {
179
    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
180
    writeFixed32NoTag(value);
181
  }
182
 
183
  /** Write a {@code bool} field, including tag, to the stream. */
184
  public void writeBool(final int fieldNumber, final boolean value)
185
                        throws IOException {
186
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
187
    writeBoolNoTag(value);
188
  }
189
 
190
  /** Write a {@code string} field, including tag, to the stream. */
191
  public void writeString(final int fieldNumber, final String value)
192
                          throws IOException {
193
    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
194
    writeStringNoTag(value);
195
  }
196
 
197
  /** Write a {@code group} field, including tag, to the stream. */
198
  public void writeGroup(final int fieldNumber, final MessageLite value)
199
                         throws IOException {
200
    writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
201
    writeGroupNoTag(value);
202
    writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
203
  }
204
 
205
  /**
206
   * Write a group represented by an {@link UnknownFieldSet}.
207
   *
208
   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
209
   *             call {@link #writeGroup}.
210
   */
211
  @Deprecated
212
  public void writeUnknownGroup(final int fieldNumber,
213
                                final MessageLite value)
214
                                throws IOException {
215
    writeGroup(fieldNumber, value);
216
  }
217
 
218
  /** Write an embedded message field, including tag, to the stream. */
219
  public void writeMessage(final int fieldNumber, final MessageLite value)
220
                           throws IOException {
221
    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
222
    writeMessageNoTag(value);
223
  }
224
 
225
  /** Write a {@code bytes} field, including tag, to the stream. */
226
  public void writeBytes(final int fieldNumber, final ByteString value)
227
                         throws IOException {
228
    writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
229
    writeBytesNoTag(value);
230
  }
231
 
232
  /** Write a {@code uint32} field, including tag, to the stream. */
233
  public void writeUInt32(final int fieldNumber, final int value)
234
                          throws IOException {
235
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
236
    writeUInt32NoTag(value);
237
  }
238
 
239
  /**
240
   * Write an enum field, including tag, to the stream.  Caller is responsible
241
   * for converting the enum value to its numeric value.
242
   */
243
  public void writeEnum(final int fieldNumber, final int value)
244
                        throws IOException {
245
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
246
    writeEnumNoTag(value);
247
  }
248
 
249
  /** Write an {@code sfixed32} field, including tag, to the stream. */
250
  public void writeSFixed32(final int fieldNumber, final int value)
251
                            throws IOException {
252
    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
253
    writeSFixed32NoTag(value);
254
  }
255
 
256
  /** Write an {@code sfixed64} field, including tag, to the stream. */
257
  public void writeSFixed64(final int fieldNumber, final long value)
258
                            throws IOException {
259
    writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
260
    writeSFixed64NoTag(value);
261
  }
262
 
263
  /** Write an {@code sint32} field, including tag, to the stream. */
264
  public void writeSInt32(final int fieldNumber, final int value)
265
                          throws IOException {
266
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
267
    writeSInt32NoTag(value);
268
  }
269
 
270
  /** Write an {@code sint64} field, including tag, to the stream. */
271
  public void writeSInt64(final int fieldNumber, final long value)
272
                          throws IOException {
273
    writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
274
    writeSInt64NoTag(value);
275
  }
276
 
277
  /**
278
   * Write a MessageSet extension field to the stream.  For historical reasons,
279
   * the wire format differs from normal fields.
280
   */
281
  public void writeMessageSetExtension(final int fieldNumber,
282
                                       final MessageLite value)
283
                                       throws IOException {
284
    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
285
    writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
286
    writeMessage(WireFormat.MESSAGE_SET_MESSAGE, value);
287
    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
288
  }
289
 
290
  /**
291
   * Write an unparsed MessageSet extension field to the stream.  For
292
   * historical reasons, the wire format differs from normal fields.
293
   */
294
  public void writeRawMessageSetExtension(final int fieldNumber,
295
                                          final ByteString value)
296
                                          throws IOException {
297
    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_START_GROUP);
298
    writeUInt32(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber);
299
    writeBytes(WireFormat.MESSAGE_SET_MESSAGE, value);
300
    writeTag(WireFormat.MESSAGE_SET_ITEM, WireFormat.WIRETYPE_END_GROUP);
301
  }
302
 
303
  // -----------------------------------------------------------------
304
 
305
  /** Write a {@code double} field to the stream. */
306
  public void writeDoubleNoTag(final double value) throws IOException {
307
    writeRawLittleEndian64(Double.doubleToRawLongBits(value));
308
  }
309
 
310
  /** Write a {@code float} field to the stream. */
311
  public void writeFloatNoTag(final float value) throws IOException {
312
    writeRawLittleEndian32(Float.floatToRawIntBits(value));
313
  }
314
 
315
  /** Write a {@code uint64} field to the stream. */
316
  public void writeUInt64NoTag(final long value) throws IOException {
317
    writeRawVarint64(value);
318
  }
319
 
320
  /** Write an {@code int64} field to the stream. */
321
  public void writeInt64NoTag(final long value) throws IOException {
322
    writeRawVarint64(value);
323
  }
324
 
325
  /** Write an {@code int32} field to the stream. */
326
  public void writeInt32NoTag(final int value) throws IOException {
327
    if (value >= 0) {
328
      writeRawVarint32(value);
329
    } else {
330
      // Must sign-extend.
331
      writeRawVarint64(value);
332
    }
333
  }
334
 
335
  /** Write a {@code fixed64} field to the stream. */
336
  public void writeFixed64NoTag(final long value) throws IOException {
337
    writeRawLittleEndian64(value);
338
  }
339
 
340
  /** Write a {@code fixed32} field to the stream. */
341
  public void writeFixed32NoTag(final int value) throws IOException {
342
    writeRawLittleEndian32(value);
343
  }
344
 
345
  /** Write a {@code bool} field to the stream. */
346
  public void writeBoolNoTag(final boolean value) throws IOException {
347
    writeRawByte(value ? 1 : 0);
348
  }
349
 
350
  /** Write a {@code string} field to the stream. */
351
  public void writeStringNoTag(final String value) throws IOException {
352
    // Unfortunately there does not appear to be any way to tell Java to encode
353
    // UTF-8 directly into our buffer, so we have to let it create its own byte
354
    // array and then copy.
355
    final byte[] bytes = value.getBytes("UTF-8");
356
    writeRawVarint32(bytes.length);
357
    writeRawBytes(bytes);
358
  }
359
 
360
  /** Write a {@code group} field to the stream. */
361
  public void writeGroupNoTag(final MessageLite value) throws IOException {
362
    value.writeTo(this);
363
  }
364
 
365
  /**
366
   * Write a group represented by an {@link UnknownFieldSet}.
367
   *
368
   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
369
   *             call {@link #writeGroupNoTag}.
370
   */
371
  @Deprecated
372
  public void writeUnknownGroupNoTag(final MessageLite value)
373
      throws IOException {
374
    writeGroupNoTag(value);
375
  }
376
 
377
  /** Write an embedded message field to the stream. */
378
  public void writeMessageNoTag(final MessageLite value) throws IOException {
379
    writeRawVarint32(value.getSerializedSize());
380
    value.writeTo(this);
381
  }
382
 
383
  /** Write a {@code bytes} field to the stream. */
384
  public void writeBytesNoTag(final ByteString value) throws IOException {
385
    writeRawVarint32(value.size());
386
    writeRawBytes(value);
387
  }
388
 
389
  /** Write a {@code uint32} field to the stream. */
390
  public void writeUInt32NoTag(final int value) throws IOException {
391
    writeRawVarint32(value);
392
  }
393
 
394
  /**
395
   * Write an enum field to the stream.  Caller is responsible
396
   * for converting the enum value to its numeric value.
397
   */
398
  public void writeEnumNoTag(final int value) throws IOException {
399
    writeInt32NoTag(value);
400
  }
401
 
402
  /** Write an {@code sfixed32} field to the stream. */
403
  public void writeSFixed32NoTag(final int value) throws IOException {
404
    writeRawLittleEndian32(value);
405
  }
406
 
407
  /** Write an {@code sfixed64} field to the stream. */
408
  public void writeSFixed64NoTag(final long value) throws IOException {
409
    writeRawLittleEndian64(value);
410
  }
411
 
412
  /** Write an {@code sint32} field to the stream. */
413
  public void writeSInt32NoTag(final int value) throws IOException {
414
    writeRawVarint32(encodeZigZag32(value));
415
  }
416
 
417
  /** Write an {@code sint64} field to the stream. */
418
  public void writeSInt64NoTag(final long value) throws IOException {
419
    writeRawVarint64(encodeZigZag64(value));
420
  }
421
 
422
  // =================================================================
423
 
424
  /**
425
   * Compute the number of bytes that would be needed to encode a
426
   * {@code double} field, including tag.
427
   */
428
  public static int computeDoubleSize(final int fieldNumber,
429
                                      final double value) {
430
    return computeTagSize(fieldNumber) + computeDoubleSizeNoTag(value);
431
  }
432
 
433
  /**
434
   * Compute the number of bytes that would be needed to encode a
435
   * {@code float} field, including tag.
436
   */
437
  public static int computeFloatSize(final int fieldNumber, final float value) {
438
    return computeTagSize(fieldNumber) + computeFloatSizeNoTag(value);
439
  }
440
 
441
  /**
442
   * Compute the number of bytes that would be needed to encode a
443
   * {@code uint64} field, including tag.
444
   */
445
  public static int computeUInt64Size(final int fieldNumber, final long value) {
446
    return computeTagSize(fieldNumber) + computeUInt64SizeNoTag(value);
447
  }
448
 
449
  /**
450
   * Compute the number of bytes that would be needed to encode an
451
   * {@code int64} field, including tag.
452
   */
453
  public static int computeInt64Size(final int fieldNumber, final long value) {
454
    return computeTagSize(fieldNumber) + computeInt64SizeNoTag(value);
455
  }
456
 
457
  /**
458
   * Compute the number of bytes that would be needed to encode an
459
   * {@code int32} field, including tag.
460
   */
461
  public static int computeInt32Size(final int fieldNumber, final int value) {
462
    return computeTagSize(fieldNumber) + computeInt32SizeNoTag(value);
463
  }
464
 
465
  /**
466
   * Compute the number of bytes that would be needed to encode a
467
   * {@code fixed64} field, including tag.
468
   */
469
  public static int computeFixed64Size(final int fieldNumber,
470
                                       final long value) {
471
    return computeTagSize(fieldNumber) + computeFixed64SizeNoTag(value);
472
  }
473
 
474
  /**
475
   * Compute the number of bytes that would be needed to encode a
476
   * {@code fixed32} field, including tag.
477
   */
478
  public static int computeFixed32Size(final int fieldNumber,
479
                                       final int value) {
480
    return computeTagSize(fieldNumber) + computeFixed32SizeNoTag(value);
481
  }
482
 
483
  /**
484
   * Compute the number of bytes that would be needed to encode a
485
   * {@code bool} field, including tag.
486
   */
487
  public static int computeBoolSize(final int fieldNumber,
488
                                    final boolean value) {
489
    return computeTagSize(fieldNumber) + computeBoolSizeNoTag(value);
490
  }
491
 
492
  /**
493
   * Compute the number of bytes that would be needed to encode a
494
   * {@code string} field, including tag.
495
   */
496
  public static int computeStringSize(final int fieldNumber,
497
                                      final String value) {
498
    return computeTagSize(fieldNumber) + computeStringSizeNoTag(value);
499
  }
500
 
501
  /**
502
   * Compute the number of bytes that would be needed to encode a
503
   * {@code group} field, including tag.
504
   */
505
  public static int computeGroupSize(final int fieldNumber,
506
                                     final MessageLite value) {
507
    return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
508
  }
509
 
510
  /**
511
   * Compute the number of bytes that would be needed to encode a
512
   * {@code group} field represented by an {@code UnknownFieldSet}, including
513
   * tag.
514
   *
515
   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
516
   *             call {@link #computeGroupSize}.
517
   */
518
  @Deprecated
519
  public static int computeUnknownGroupSize(final int fieldNumber,
520
                                            final MessageLite value) {
521
    return computeGroupSize(fieldNumber, value);
522
  }
523
 
524
  /**
525
   * Compute the number of bytes that would be needed to encode an
526
   * embedded message field, including tag.
527
   */
528
  public static int computeMessageSize(final int fieldNumber,
529
                                       final MessageLite value) {
530
    return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
531
  }
532
 
533
  /**
534
   * Compute the number of bytes that would be needed to encode a
535
   * {@code bytes} field, including tag.
536
   */
537
  public static int computeBytesSize(final int fieldNumber,
538
                                     final ByteString value) {
539
    return computeTagSize(fieldNumber) + computeBytesSizeNoTag(value);
540
  }
541
 
542
  /**
543
   * Compute the number of bytes that would be needed to encode a
544
   * {@code uint32} field, including tag.
545
   */
546
  public static int computeUInt32Size(final int fieldNumber, final int value) {
547
    return computeTagSize(fieldNumber) + computeUInt32SizeNoTag(value);
548
  }
549
 
550
  /**
551
   * Compute the number of bytes that would be needed to encode an
552
   * enum field, including tag.  Caller is responsible for converting the
553
   * enum value to its numeric value.
554
   */
555
  public static int computeEnumSize(final int fieldNumber, final int value) {
556
    return computeTagSize(fieldNumber) + computeEnumSizeNoTag(value);
557
  }
558
 
559
  /**
560
   * Compute the number of bytes that would be needed to encode an
561
   * {@code sfixed32} field, including tag.
562
   */
563
  public static int computeSFixed32Size(final int fieldNumber,
564
                                        final int value) {
565
    return computeTagSize(fieldNumber) + computeSFixed32SizeNoTag(value);
566
  }
567
 
568
  /**
569
   * Compute the number of bytes that would be needed to encode an
570
   * {@code sfixed64} field, including tag.
571
   */
572
  public static int computeSFixed64Size(final int fieldNumber,
573
                                        final long value) {
574
    return computeTagSize(fieldNumber) + computeSFixed64SizeNoTag(value);
575
  }
576
 
577
  /**
578
   * Compute the number of bytes that would be needed to encode an
579
   * {@code sint32} field, including tag.
580
   */
581
  public static int computeSInt32Size(final int fieldNumber, final int value) {
582
    return computeTagSize(fieldNumber) + computeSInt32SizeNoTag(value);
583
  }
584
 
585
  /**
586
   * Compute the number of bytes that would be needed to encode an
587
   * {@code sint64} field, including tag.
588
   */
589
  public static int computeSInt64Size(final int fieldNumber, final long value) {
590
    return computeTagSize(fieldNumber) + computeSInt64SizeNoTag(value);
591
  }
592
 
593
  /**
594
   * Compute the number of bytes that would be needed to encode a
595
   * MessageSet extension to the stream.  For historical reasons,
596
   * the wire format differs from normal fields.
597
   */
598
  public static int computeMessageSetExtensionSize(
599
      final int fieldNumber, final MessageLite value) {
600
    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
601
           computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
602
           computeMessageSize(WireFormat.MESSAGE_SET_MESSAGE, value);
603
  }
604
 
605
  /**
606
   * Compute the number of bytes that would be needed to encode an
607
   * unparsed MessageSet extension field to the stream.  For
608
   * historical reasons, the wire format differs from normal fields.
609
   */
610
  public static int computeRawMessageSetExtensionSize(
611
      final int fieldNumber, final ByteString value) {
612
    return computeTagSize(WireFormat.MESSAGE_SET_ITEM) * 2 +
613
           computeUInt32Size(WireFormat.MESSAGE_SET_TYPE_ID, fieldNumber) +
614
           computeBytesSize(WireFormat.MESSAGE_SET_MESSAGE, value);
615
  }
616
 
617
  // -----------------------------------------------------------------
618
 
619
  /**
620
   * Compute the number of bytes that would be needed to encode a
621
   * {@code double} field, including tag.
622
   */
623
  public static int computeDoubleSizeNoTag(final double value) {
624
    return LITTLE_ENDIAN_64_SIZE;
625
  }
626
 
627
  /**
628
   * Compute the number of bytes that would be needed to encode a
629
   * {@code float} field, including tag.
630
   */
631
  public static int computeFloatSizeNoTag(final float value) {
632
    return LITTLE_ENDIAN_32_SIZE;
633
  }
634
 
635
  /**
636
   * Compute the number of bytes that would be needed to encode a
637
   * {@code uint64} field, including tag.
638
   */
639
  public static int computeUInt64SizeNoTag(final long value) {
640
    return computeRawVarint64Size(value);
641
  }
642
 
643
  /**
644
   * Compute the number of bytes that would be needed to encode an
645
   * {@code int64} field, including tag.
646
   */
647
  public static int computeInt64SizeNoTag(final long value) {
648
    return computeRawVarint64Size(value);
649
  }
650
 
651
  /**
652
   * Compute the number of bytes that would be needed to encode an
653
   * {@code int32} field, including tag.
654
   */
655
  public static int computeInt32SizeNoTag(final int value) {
656
    if (value >= 0) {
657
      return computeRawVarint32Size(value);
658
    } else {
659
      // Must sign-extend.
660
      return 10;
661
    }
662
  }
663
 
664
  /**
665
   * Compute the number of bytes that would be needed to encode a
666
   * {@code fixed64} field.
667
   */
668
  public static int computeFixed64SizeNoTag(final long value) {
669
    return LITTLE_ENDIAN_64_SIZE;
670
  }
671
 
672
  /**
673
   * Compute the number of bytes that would be needed to encode a
674
   * {@code fixed32} field.
675
   */
676
  public static int computeFixed32SizeNoTag(final int value) {
677
    return LITTLE_ENDIAN_32_SIZE;
678
  }
679
 
680
  /**
681
   * Compute the number of bytes that would be needed to encode a
682
   * {@code bool} field.
683
   */
684
  public static int computeBoolSizeNoTag(final boolean value) {
685
    return 1;
686
  }
687
 
688
  /**
689
   * Compute the number of bytes that would be needed to encode a
690
   * {@code string} field.
691
   */
692
  public static int computeStringSizeNoTag(final String value) {
693
    try {
694
      final byte[] bytes = value.getBytes("UTF-8");
695
      return computeRawVarint32Size(bytes.length) +
696
             bytes.length;
697
    } catch (UnsupportedEncodingException e) {
698
      throw new RuntimeException("UTF-8 not supported.", e);
699
    }
700
  }
701
 
702
  /**
703
   * Compute the number of bytes that would be needed to encode a
704
   * {@code group} field.
705
   */
706
  public static int computeGroupSizeNoTag(final MessageLite value) {
707
    return value.getSerializedSize();
708
  }
709
 
710
  /**
711
   * Compute the number of bytes that would be needed to encode a
712
   * {@code group} field represented by an {@code UnknownFieldSet}, including
713
   * tag.
714
   *
715
   * @deprecated UnknownFieldSet now implements MessageLite, so you can just
716
   *             call {@link #computeUnknownGroupSizeNoTag}.
717
   */
718
  @Deprecated
719
  public static int computeUnknownGroupSizeNoTag(final MessageLite value) {
720
    return computeGroupSizeNoTag(value);
721
  }
722
 
723
  /**
724
   * Compute the number of bytes that would be needed to encode an embedded
725
   * message field.
726
   */
727
  public static int computeMessageSizeNoTag(final MessageLite value) {
728
    final int size = value.getSerializedSize();
729
    return computeRawVarint32Size(size) + size;
730
  }
731
 
732
  /**
733
   * Compute the number of bytes that would be needed to encode a
734
   * {@code bytes} field.
735
   */
736
  public static int computeBytesSizeNoTag(final ByteString value) {
737
    return computeRawVarint32Size(value.size()) +
738
           value.size();
739
  }
740
 
741
  /**
742
   * Compute the number of bytes that would be needed to encode a
743
   * {@code uint32} field.
744
   */
745
  public static int computeUInt32SizeNoTag(final int value) {
746
    return computeRawVarint32Size(value);
747
  }
748
 
749
  /**
750
   * Compute the number of bytes that would be needed to encode an enum field.
751
   * Caller is responsible for converting the enum value to its numeric value.
752
   */
753
  public static int computeEnumSizeNoTag(final int value) {
754
    return computeInt32SizeNoTag(value);
755
  }
756
 
757
  /**
758
   * Compute the number of bytes that would be needed to encode an
759
   * {@code sfixed32} field.
760
   */
761
  public static int computeSFixed32SizeNoTag(final int value) {
762
    return LITTLE_ENDIAN_32_SIZE;
763
  }
764
 
765
  /**
766
   * Compute the number of bytes that would be needed to encode an
767
   * {@code sfixed64} field.
768
   */
769
  public static int computeSFixed64SizeNoTag(final long value) {
770
    return LITTLE_ENDIAN_64_SIZE;
771
  }
772
 
773
  /**
774
   * Compute the number of bytes that would be needed to encode an
775
   * {@code sint32} field.
776
   */
777
  public static int computeSInt32SizeNoTag(final int value) {
778
    return computeRawVarint32Size(encodeZigZag32(value));
779
  }
780
 
781
  /**
782
   * Compute the number of bytes that would be needed to encode an
783
   * {@code sint64} field.
784
   */
785
  public static int computeSInt64SizeNoTag(final long value) {
786
    return computeRawVarint64Size(encodeZigZag64(value));
787
  }
788
 
789
  // =================================================================
790
 
791
  /**
792
   * Internal helper that writes the current buffer to the output. The
793
   * buffer position is reset to its initial value when this returns.
794
   */
795
  private void refreshBuffer() throws IOException {
796
    if (output == null) {
797
      // We're writing to a single buffer.
798
      throw new OutOfSpaceException();
799
    }
800
 
801
    // Since we have an output stream, this is our buffer
802
    // and buffer offset == 0
803
    output.write(buffer, 0, position);
804
    position = 0;
805
  }
806
 
807
  /**
808
   * Flushes the stream and forces any buffered bytes to be written.  This
809
   * does not flush the underlying OutputStream.
810
   */
811
  public void flush() throws IOException {
812
    if (output != null) {
813
      refreshBuffer();
814
    }
815
  }
816
 
817
  /**
818
   * If writing to a flat array, return the space left in the array.
819
   * Otherwise, throws {@code UnsupportedOperationException}.
820
   */
821
  public int spaceLeft() {
822
    if (output == null) {
823
      return limit - position;
824
    } else {
825
      throw new UnsupportedOperationException(
826
        "spaceLeft() can only be called on CodedOutputStreams that are " +
827
        "writing to a flat array.");
828
    }
829
  }
830
 
831
  /**
832
   * Verifies that {@link #spaceLeft()} returns zero.  It's common to create
833
   * a byte array that is exactly big enough to hold a message, then write to
834
   * it with a {@code CodedOutputStream}.  Calling {@code checkNoSpaceLeft()}
835
   * after writing verifies that the message was actually as big as expected,
836
   * which can help catch bugs.
837
   */
838
  public void checkNoSpaceLeft() {
839
    if (spaceLeft() != 0) {
840
      throw new IllegalStateException(
841
        "Did not write as much data as expected.");
842
    }
843
  }
844
 
845
  /**
846
   * If you create a CodedOutputStream around a simple flat array, you must
847
   * not attempt to write more bytes than the array has space.  Otherwise,
848
   * this exception will be thrown.
849
   */
850
  public static class OutOfSpaceException extends IOException {
851
    private static final long serialVersionUID = -6947486886997889499L;
852
 
853
    OutOfSpaceException() {
854
      super("CodedOutputStream was writing to a flat byte array and ran " +
855
            "out of space.");
856
    }
857
  }
858
 
859
  /** Write a single byte. */
860
  public void writeRawByte(final byte value) throws IOException {
861
    if (position == limit) {
862
      refreshBuffer();
863
    }
864
 
865
    buffer[position++] = value;
866
  }
867
 
868
  /** Write a single byte, represented by an integer value. */
869
  public void writeRawByte(final int value) throws IOException {
870
    writeRawByte((byte) value);
871
  }
872
 
873
  /** Write a byte string. */
874
  public void writeRawBytes(final ByteString value) throws IOException {
875
    writeRawBytes(value, 0, value.size());
876
  }
877
 
878
  /** Write an array of bytes. */
879
  public void writeRawBytes(final byte[] value) throws IOException {
880
    writeRawBytes(value, 0, value.length);
881
  }
882
 
883
  /** Write part of an array of bytes. */
884
  public void writeRawBytes(final byte[] value, int offset, int length)
885
                            throws IOException {
886
    if (limit - position >= length) {
887
      // We have room in the current buffer.
888
      System.arraycopy(value, offset, buffer, position, length);
889
      position += length;
890
    } else {
891
      // Write extends past current buffer.  Fill the rest of this buffer and
892
      // flush.
893
      final int bytesWritten = limit - position;
894
      System.arraycopy(value, offset, buffer, position, bytesWritten);
895
      offset += bytesWritten;
896
      length -= bytesWritten;
897
      position = limit;
898
      refreshBuffer();
899
 
900
      // Now deal with the rest.
901
      // Since we have an output stream, this is our buffer
902
      // and buffer offset == 0
903
      if (length <= limit) {
904
        // Fits in new buffer.
905
        System.arraycopy(value, offset, buffer, 0, length);
906
        position = length;
907
      } else {
908
        // Write is very big.  Let's do it all at once.
909
        output.write(value, offset, length);
910
      }
911
    }
912
  }
913
 
914
  /** Write part of a byte string. */
915
  public void writeRawBytes(final ByteString value, int offset, int length)
916
                            throws IOException {
917
    if (limit - position >= length) {
918
      // We have room in the current buffer.
919
      value.copyTo(buffer, offset, position, length);
920
      position += length;
921
    } else {
922
      // Write extends past current buffer.  Fill the rest of this buffer and
923
      // flush.
924
      final int bytesWritten = limit - position;
925
      value.copyTo(buffer, offset, position, bytesWritten);
926
      offset += bytesWritten;
927
      length -= bytesWritten;
928
      position = limit;
929
      refreshBuffer();
930
 
931
      // Now deal with the rest.
932
      // Since we have an output stream, this is our buffer
933
      // and buffer offset == 0
934
      if (length <= limit) {
935
        // Fits in new buffer.
936
        value.copyTo(buffer, offset, 0, length);
937
        position = length;
938
      } else {
939
        // Write is very big, but we can't do it all at once without allocating
940
        // an a copy of the byte array since ByteString does not give us access
941
        // to the underlying bytes. Use the InputStream interface on the
942
        // ByteString and our buffer to copy between the two.
943
        InputStream inputStreamFrom = value.newInput();
944
        if (offset != inputStreamFrom.skip(offset)) {
945
          throw new IllegalStateException("Skip failed? Should never happen.");
946
        }
947
        // Use the buffer as the temporary buffer to avoid allocating memory.
948
        while (length > 0) {
949
          int bytesToRead = Math.min(length, limit);
950
          int bytesRead = inputStreamFrom.read(buffer, 0, bytesToRead);
951
          if (bytesRead != bytesToRead) {
952
            throw new IllegalStateException("Read failed? Should never happen");
953
          }
954
          output.write(buffer, 0, bytesRead);
955
          length -= bytesRead;
956
        }
957
      }
958
    }
959
  }
960
 
961
  /** Encode and write a tag. */
962
  public void writeTag(final int fieldNumber, final int wireType)
963
                       throws IOException {
964
    writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
965
  }
966
 
967
  /** Compute the number of bytes that would be needed to encode a tag. */
968
  public static int computeTagSize(final int fieldNumber) {
969
    return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
970
  }
971
 
972
  /**
973
   * Encode and write a varint.  {@code value} is treated as
974
   * unsigned, so it won't be sign-extended if negative.
975
   */
976
  public void writeRawVarint32(int value) throws IOException {
977
    while (true) {
978
      if ((value & ~0x7F) == 0) {
979
        writeRawByte(value);
980
        return;
981
      } else {
982
        writeRawByte((value & 0x7F) | 0x80);
983
        value >>>= 7;
984
      }
985
    }
986
  }
987
 
988
  /**
989
   * Compute the number of bytes that would be needed to encode a varint.
990
   * {@code value} is treated as unsigned, so it won't be sign-extended if
991
   * negative.
992
   */
993
  public static int computeRawVarint32Size(final int value) {
994
    if ((value & (0xffffffff <<  7)) == 0) return 1;
995
    if ((value & (0xffffffff << 14)) == 0) return 2;
996
    if ((value & (0xffffffff << 21)) == 0) return 3;
997
    if ((value & (0xffffffff << 28)) == 0) return 4;
998
    return 5;
999
  }
1000
 
1001
  /** Encode and write a varint. */
1002
  public void writeRawVarint64(long value) throws IOException {
1003
    while (true) {
1004
      if ((value & ~0x7FL) == 0) {
1005
        writeRawByte((int)value);
1006
        return;
1007
      } else {
1008
        writeRawByte(((int)value & 0x7F) | 0x80);
1009
        value >>>= 7;
1010
      }
1011
    }
1012
  }
1013
 
1014
  /** Compute the number of bytes that would be needed to encode a varint. */
1015
  public static int computeRawVarint64Size(final long value) {
1016
    if ((value & (0xffffffffffffffffL <<  7)) == 0) return 1;
1017
    if ((value & (0xffffffffffffffffL << 14)) == 0) return 2;
1018
    if ((value & (0xffffffffffffffffL << 21)) == 0) return 3;
1019
    if ((value & (0xffffffffffffffffL << 28)) == 0) return 4;
1020
    if ((value & (0xffffffffffffffffL << 35)) == 0) return 5;
1021
    if ((value & (0xffffffffffffffffL << 42)) == 0) return 6;
1022
    if ((value & (0xffffffffffffffffL << 49)) == 0) return 7;
1023
    if ((value & (0xffffffffffffffffL << 56)) == 0) return 8;
1024
    if ((value & (0xffffffffffffffffL << 63)) == 0) return 9;
1025
    return 10;
1026
  }
1027
 
1028
  /** Write a little-endian 32-bit integer. */
1029
  public void writeRawLittleEndian32(final int value) throws IOException {
1030
    writeRawByte((value      ) & 0xFF);
1031
    writeRawByte((value >>  8) & 0xFF);
1032
    writeRawByte((value >> 16) & 0xFF);
1033
    writeRawByte((value >> 24) & 0xFF);
1034
  }
1035
 
1036
  public static final int LITTLE_ENDIAN_32_SIZE = 4;
1037
 
1038
  /** Write a little-endian 64-bit integer. */
1039
  public void writeRawLittleEndian64(final long value) throws IOException {
1040
    writeRawByte((int)(value      ) & 0xFF);
1041
    writeRawByte((int)(value >>  8) & 0xFF);
1042
    writeRawByte((int)(value >> 16) & 0xFF);
1043
    writeRawByte((int)(value >> 24) & 0xFF);
1044
    writeRawByte((int)(value >> 32) & 0xFF);
1045
    writeRawByte((int)(value >> 40) & 0xFF);
1046
    writeRawByte((int)(value >> 48) & 0xFF);
1047
    writeRawByte((int)(value >> 56) & 0xFF);
1048
  }
1049
 
1050
  public static final int LITTLE_ENDIAN_64_SIZE = 8;
1051
 
1052
  /**
1053
   * Encode a ZigZag-encoded 32-bit value.  ZigZag encodes signed integers
1054
   * into values that can be efficiently encoded with varint.  (Otherwise,
1055
   * negative values must be sign-extended to 64 bits to be varint encoded,
1056
   * thus always taking 10 bytes on the wire.)
1057
   *
1058
   * @param n A signed 32-bit integer.
1059
   * @return An unsigned 32-bit integer, stored in a signed int because
1060
   *         Java has no explicit unsigned support.
1061
   */
1062
  public static int encodeZigZag32(final int n) {
1063
    // Note:  the right-shift must be arithmetic
1064
    return (n << 1) ^ (n >> 31);
1065
  }
1066
 
1067
  /**
1068
   * Encode a ZigZag-encoded 64-bit value.  ZigZag encodes signed integers
1069
   * into values that can be efficiently encoded with varint.  (Otherwise,
1070
   * negative values must be sign-extended to 64 bits to be varint encoded,
1071
   * thus always taking 10 bytes on the wire.)
1072
   *
1073
   * @param n A signed 64-bit integer.
1074
   * @return An unsigned 64-bit integer, stored in a signed int because
1075
   *         Java has no explicit unsigned support.
1076
   */
1077
  public static long encodeZigZag64(final long n) {
1078
    // Note:  the right-shift must be arithmetic
1079
    return (n << 1) ^ (n >> 63);
1080
  }
1081
}