OLD | NEW |
1 #region Copyright notice and license | 1 #region Copyright notice and license |
2 // Protocol Buffers - Google's data interchange format | 2 // Protocol Buffers - Google's data interchange format |
3 // Copyright 2008 Google Inc. All rights reserved. | 3 // Copyright 2008 Google Inc. All rights reserved. |
4 // https://developers.google.com/protocol-buffers/ | 4 // https://developers.google.com/protocol-buffers/ |
5 // | 5 // |
6 // Redistribution and use in source and binary forms, with or without | 6 // Redistribution and use in source and binary forms, with or without |
7 // modification, are permitted provided that the following conditions are | 7 // modification, are permitted provided that the following conditions are |
8 // met: | 8 // met: |
9 // | 9 // |
10 // * Redistributions of source code must retain the above copyright | 10 // * Redistributions of source code must retain the above copyright |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 /// this does not include combined "write tag and value" methods. Generated | 48 /// this does not include combined "write tag and value" methods. Generated |
49 /// code knows the exact byte representations of the tags they're going to w
rite, | 49 /// code knows the exact byte representations of the tags they're going to w
rite, |
50 /// so there's no need to re-encode them each time. Manually-written code ca
lling | 50 /// so there's no need to re-encode them each time. Manually-written code ca
lling |
51 /// this class should just call one of the <c>WriteTag</c> overloads before
each value. | 51 /// this class should just call one of the <c>WriteTag</c> overloads before
each value. |
52 /// </para> | 52 /// </para> |
53 /// <para> | 53 /// <para> |
54 /// Repeated fields and map fields are not handled by this class; use <c>Rep
eatedField<T></c> | 54 /// Repeated fields and map fields are not handled by this class; use <c>Rep
eatedField<T></c> |
55 /// and <c>MapField<TKey, TValue></c> to serialize such fields. | 55 /// and <c>MapField<TKey, TValue></c> to serialize such fields. |
56 /// </para> | 56 /// </para> |
57 /// </remarks> | 57 /// </remarks> |
58 public sealed partial class CodedOutputStream | 58 public sealed partial class CodedOutputStream : IDisposable |
59 { | 59 { |
60 // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a diffe
rence.) | 60 // "Local" copy of Encoding.UTF8, for efficiency. (Yes, it makes a diffe
rence.) |
61 internal static readonly Encoding Utf8Encoding = Encoding.UTF8; | 61 internal static readonly Encoding Utf8Encoding = Encoding.UTF8; |
62 | 62 |
63 /// <summary> | 63 /// <summary> |
64 /// The buffer size used by CreateInstance(Stream). | 64 /// The buffer size used by CreateInstance(Stream). |
65 /// </summary> | 65 /// </summary> |
66 public static readonly int DefaultBufferSize = 4096; | 66 public static readonly int DefaultBufferSize = 4096; |
67 | 67 |
| 68 private readonly bool leaveOpen; |
68 private readonly byte[] buffer; | 69 private readonly byte[] buffer; |
69 private readonly int limit; | 70 private readonly int limit; |
70 private int position; | 71 private int position; |
71 private readonly Stream output; | 72 private readonly Stream output; |
72 | 73 |
73 #region Construction | 74 #region Construction |
74 /// <summary> | 75 /// <summary> |
75 /// Creates a new CodedOutputStream that writes directly to the given | 76 /// Creates a new CodedOutputStream that writes directly to the given |
76 /// byte array. If more bytes are written than fit in the array, | 77 /// byte array. If more bytes are written than fit in the array, |
77 /// OutOfSpaceException will be thrown. | 78 /// OutOfSpaceException will be thrown. |
78 /// </summary> | 79 /// </summary> |
79 public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArra
y.Length) | 80 public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArra
y.Length) |
80 { | 81 { |
81 } | 82 } |
82 | 83 |
83 /// <summary> | 84 /// <summary> |
84 /// Creates a new CodedOutputStream that writes directly to the given | 85 /// Creates a new CodedOutputStream that writes directly to the given |
85 /// byte array slice. If more bytes are written than fit in the array, | 86 /// byte array slice. If more bytes are written than fit in the array, |
86 /// OutOfSpaceException will be thrown. | 87 /// OutOfSpaceException will be thrown. |
87 /// </summary> | 88 /// </summary> |
88 private CodedOutputStream(byte[] buffer, int offset, int length) | 89 private CodedOutputStream(byte[] buffer, int offset, int length) |
89 { | 90 { |
90 this.output = null; | 91 this.output = null; |
91 this.buffer = buffer; | 92 this.buffer = buffer; |
92 this.position = offset; | 93 this.position = offset; |
93 this.limit = offset + length; | 94 this.limit = offset + length; |
94 } | 95 leaveOpen = true; // Simple way of avoiding trying to dispose of a n
ull reference |
95 | 96 } |
96 private CodedOutputStream(Stream output, byte[] buffer) | 97 |
97 { | 98 private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen) |
98 this.output = output; | 99 { |
| 100 this.output = ProtoPreconditions.CheckNotNull(output, nameof(output)
); |
99 this.buffer = buffer; | 101 this.buffer = buffer; |
100 this.position = 0; | 102 this.position = 0; |
101 this.limit = buffer.Length; | 103 this.limit = buffer.Length; |
102 } | 104 this.leaveOpen = leaveOpen; |
103 | 105 } |
104 /// <summary> | 106 |
105 /// Creates a new CodedOutputStream which write to the given stream. | 107 /// <summary> |
106 /// </summary> | 108 /// Creates a new <see cref="CodedOutputStream" /> which write to the gi
ven stream, and disposes of that |
107 public CodedOutputStream(Stream output) : this(output, DefaultBufferSize
) | 109 /// stream when the returned <c>CodedOutputStream</c> is disposed. |
| 110 /// </summary> |
| 111 /// <param name="output">The stream to write to. It will be disposed whe
n the returned <c>CodedOutputStream is disposed.</c></param> |
| 112 public CodedOutputStream(Stream output) : this(output, DefaultBufferSize
, false) |
108 { | 113 { |
109 } | 114 } |
110 | 115 |
111 /// <summary> | 116 /// <summary> |
112 /// Creates a new CodedOutputStream which write to the given stream and
uses | 117 /// Creates a new CodedOutputStream which write to the given stream and
uses |
113 /// the specified buffer size. | 118 /// the specified buffer size. |
114 /// </summary> | 119 /// </summary> |
115 public CodedOutputStream(Stream output, int bufferSize) : this(output, n
ew byte[bufferSize]) | 120 /// <param name="output">The stream to write to. It will be disposed whe
n the returned <c>CodedOutputStream is disposed.</c></param> |
116 { | 121 /// <param name="bufferSize">The size of buffer to use internally.</para
m> |
117 } | 122 public CodedOutputStream(Stream output, int bufferSize) : this(output, n
ew byte[bufferSize], false) |
| 123 { |
| 124 } |
| 125 |
| 126 /// <summary> |
| 127 /// Creates a new CodedOutputStream which write to the given stream. |
| 128 /// </summary> |
| 129 /// <param name="output">The stream to write to.</param> |
| 130 /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is
left open when the returned <c>CodedOutputStream</c> is disposed; |
| 131 /// if <c>false</c>, the provided stream is disposed as well.</param> |
| 132 public CodedOutputStream(Stream output, bool leaveOpen) : this(output, D
efaultBufferSize, leaveOpen) |
| 133 { |
| 134 } |
| 135 |
| 136 /// <summary> |
| 137 /// Creates a new CodedOutputStream which write to the given stream and
uses |
| 138 /// the specified buffer size. |
| 139 /// </summary> |
| 140 /// <param name="output">The stream to write to.</param> |
| 141 /// <param name="bufferSize">The size of buffer to use internally.</para
m> |
| 142 /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is
left open when the returned <c>CodedOutputStream</c> is disposed; |
| 143 /// if <c>false</c>, the provided stream is disposed as well.</param> |
| 144 public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen)
: this(output, new byte[bufferSize], leaveOpen) |
| 145 { |
| 146 } |
118 #endregion | 147 #endregion |
119 | 148 |
120 /// <summary> | 149 /// <summary> |
121 /// Returns the current position in the stream, or the position in the o
utput buffer | 150 /// Returns the current position in the stream, or the position in the o
utput buffer |
122 /// </summary> | 151 /// </summary> |
123 public long Position | 152 public long Position |
124 { | 153 { |
125 get | 154 get |
126 { | 155 { |
127 if (output != null) | 156 if (output != null) |
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 /// </summary> | 682 /// </summary> |
654 public sealed class OutOfSpaceException : IOException | 683 public sealed class OutOfSpaceException : IOException |
655 { | 684 { |
656 internal OutOfSpaceException() | 685 internal OutOfSpaceException() |
657 : base("CodedOutputStream was writing to a flat byte array and r
an out of space.") | 686 : base("CodedOutputStream was writing to a flat byte array and r
an out of space.") |
658 { | 687 { |
659 } | 688 } |
660 } | 689 } |
661 | 690 |
662 /// <summary> | 691 /// <summary> |
| 692 /// Flushes any buffered data and optionally closes the underlying strea
m, if any. |
| 693 /// </summary> |
| 694 /// <remarks> |
| 695 /// <para> |
| 696 /// By default, any underlying stream is closed by this method. To confi
gure this behaviour, |
| 697 /// use a constructor overload with a <c>leaveOpen</c> parameter. If thi
s instance does not |
| 698 /// have an underlying stream, this method does nothing. |
| 699 /// </para> |
| 700 /// <para> |
| 701 /// For the sake of efficiency, calling this method does not prevent fut
ure write calls - but |
| 702 /// if a later write ends up writing to a stream which has been disposed
, that is likely to |
| 703 /// fail. It is recommend that you not call any other methods after this
. |
| 704 /// </para> |
| 705 /// </remarks> |
| 706 public void Dispose() |
| 707 { |
| 708 Flush(); |
| 709 if (!leaveOpen) |
| 710 { |
| 711 output.Dispose(); |
| 712 } |
| 713 } |
| 714 |
| 715 /// <summary> |
663 /// Flushes any buffered data to the underlying stream (if there is one)
. | 716 /// Flushes any buffered data to the underlying stream (if there is one)
. |
664 /// </summary> | 717 /// </summary> |
665 public void Flush() | 718 public void Flush() |
666 { | 719 { |
667 if (output != null) | 720 if (output != null) |
668 { | 721 { |
669 RefreshBuffer(); | 722 RefreshBuffer(); |
670 } | 723 } |
671 } | 724 } |
672 | 725 |
(...skipping 25 matching lines...) Expand all Loading... |
698 } | 751 } |
699 else | 752 else |
700 { | 753 { |
701 throw new InvalidOperationException( | 754 throw new InvalidOperationException( |
702 "SpaceLeft can only be called on CodedOutputStreams that
are " + | 755 "SpaceLeft can only be called on CodedOutputStreams that
are " + |
703 "writing to a flat array."); | 756 "writing to a flat array."); |
704 } | 757 } |
705 } | 758 } |
706 } | 759 } |
707 } | 760 } |
708 } | 761 } |
OLD | NEW |