Commit 2e6dc12f authored by Jon Skeet's avatar Jon Skeet

Write/Read delimited messages

parent 43da7ae3
...@@ -174,6 +174,12 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { ...@@ -174,6 +174,12 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
public static PhoneNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static PhoneNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static PhoneNumber ParseFrom(pb::CodedInputStream input) { public static PhoneNumber ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -217,6 +223,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { ...@@ -217,6 +223,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
} }
public override PhoneNumber BuildPartial() { public override PhoneNumber BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
PhoneNumber returnMe = result; PhoneNumber returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -446,6 +455,12 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { ...@@ -446,6 +455,12 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
public static Person ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static Person ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static Person ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static Person ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static Person ParseFrom(pb::CodedInputStream input) { public static Person ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -489,6 +504,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { ...@@ -489,6 +504,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
} }
public override Person BuildPartial() { public override Person BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
result.phone_.MakeReadOnly(); result.phone_.MakeReadOnly();
Person returnMe = result; Person returnMe = result;
result = null; result = null;
...@@ -753,6 +771,12 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { ...@@ -753,6 +771,12 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
public static AddressBook ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static AddressBook ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static AddressBook ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static AddressBook ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static AddressBook ParseFrom(pb::CodedInputStream input) { public static AddressBook ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -796,6 +820,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook { ...@@ -796,6 +820,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
} }
public override AddressBook BuildPartial() { public override AddressBook BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
result.person_.MakeReadOnly(); result.person_.MakeReadOnly();
AddressBook returnMe = result; AddressBook returnMe = result;
result = null; result = null;
......
...@@ -218,6 +218,12 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -218,6 +218,12 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine("public static {0} ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName); writer.WriteLine("public static {0} ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
writer.WriteLine(" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();"); writer.WriteLine(" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
writer.WriteLine("}"); writer.WriteLine("}");
writer.WriteLine("public static {0} ParseDelimitedFrom(global::System.IO.Stream input) {{", ClassName);
writer.WriteLine(" return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();");
writer.WriteLine("}");
writer.WriteLine("public static {0} ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{", ClassName);
writer.WriteLine(" return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();");
writer.WriteLine("}");
writer.WriteLine("public static {0} ParseFrom(pb::CodedInputStream input) {{", ClassName); writer.WriteLine("public static {0} ParseFrom(pb::CodedInputStream input) {{", ClassName);
writer.WriteLine(" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();"); writer.WriteLine(" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
writer.WriteLine("}"); writer.WriteLine("}");
...@@ -325,6 +331,9 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -325,6 +331,9 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine("public override {0} BuildPartial() {{", ClassName); writer.WriteLine("public override {0} BuildPartial() {{", ClassName);
writer.Indent(); writer.Indent();
writer.WriteLine("if (result == null) {");
writer.WriteLine(" throw new global::System.InvalidOperationException(\"build() has already been called on this Builder\");");
writer.WriteLine("}");
foreach (FieldDescriptor field in Descriptor.Fields) { foreach (FieldDescriptor field in Descriptor.Fields) {
SourceGenerators.CreateFieldGenerator(field).GenerateBuildingCode(writer); SourceGenerators.CreateFieldGenerator(field).GenerateBuildingCode(writer);
} }
......
...@@ -141,6 +141,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -141,6 +141,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestEmbedOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestEmbedOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestEmbedOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestEmbedOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestEmbedOptimizedForSize ParseFrom(pb::CodedInputStream input) { public static TestEmbedOptimizedForSize ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -184,6 +190,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -184,6 +190,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestEmbedOptimizedForSize BuildPartial() { public override TestEmbedOptimizedForSize BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
result.repeatedMessage_.MakeReadOnly(); result.repeatedMessage_.MakeReadOnly();
TestEmbedOptimizedForSize returnMe = result; TestEmbedOptimizedForSize returnMe = result;
result = null; result = null;
......
...@@ -123,6 +123,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -123,6 +123,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static ImportMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static ImportMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static ImportMessage ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static ImportMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static ImportMessage ParseFrom(pb::CodedInputStream input) { public static ImportMessage ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -166,6 +172,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -166,6 +172,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override ImportMessage BuildPartial() { public override ImportMessage BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
ImportMessage returnMe = result; ImportMessage returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
......
...@@ -136,6 +136,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -136,6 +136,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestMessageSet ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestMessageSet ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestMessageSet ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestMessageSet ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestMessageSet ParseFrom(pb::CodedInputStream input) { public static TestMessageSet ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -179,6 +185,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -179,6 +185,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestMessageSet BuildPartial() { public override TestMessageSet BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
TestMessageSet returnMe = result; TestMessageSet returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -314,6 +323,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -314,6 +323,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestMessageSetContainer ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestMessageSetContainer ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestMessageSetContainer ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestMessageSetContainer ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestMessageSetContainer ParseFrom(pb::CodedInputStream input) { public static TestMessageSetContainer ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -357,6 +372,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -357,6 +372,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestMessageSetContainer BuildPartial() { public override TestMessageSetContainer BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
TestMessageSetContainer returnMe = result; TestMessageSetContainer returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -542,6 +560,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -542,6 +560,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestMessageSetExtension1 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestMessageSetExtension1 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestMessageSetExtension1 ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestMessageSetExtension1 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestMessageSetExtension1 ParseFrom(pb::CodedInputStream input) { public static TestMessageSetExtension1 ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -585,6 +609,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -585,6 +609,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestMessageSetExtension1 BuildPartial() { public override TestMessageSetExtension1 BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
TestMessageSetExtension1 returnMe = result; TestMessageSetExtension1 returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -747,6 +774,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -747,6 +774,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestMessageSetExtension2 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestMessageSetExtension2 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestMessageSetExtension2 ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestMessageSetExtension2 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestMessageSetExtension2 ParseFrom(pb::CodedInputStream input) { public static TestMessageSetExtension2 ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -790,6 +823,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -790,6 +823,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestMessageSetExtension2 BuildPartial() { public override TestMessageSetExtension2 BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
TestMessageSetExtension2 returnMe = result; TestMessageSetExtension2 returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -992,6 +1028,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -992,6 +1028,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static Item ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static Item ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static Item ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static Item ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static Item ParseFrom(pb::CodedInputStream input) { public static Item ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -1035,6 +1077,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1035,6 +1077,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override Item BuildPartial() { public override Item BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
Item returnMe = result; Item returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -1203,6 +1248,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1203,6 +1248,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static RawMessageSet ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static RawMessageSet ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static RawMessageSet ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static RawMessageSet ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static RawMessageSet ParseFrom(pb::CodedInputStream input) { public static RawMessageSet ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -1246,6 +1297,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -1246,6 +1297,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override RawMessageSet BuildPartial() { public override RawMessageSet BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
result.item_.MakeReadOnly(); result.item_.MakeReadOnly();
RawMessageSet returnMe = result; RawMessageSet returnMe = result;
result = null; result = null;
......
...@@ -119,6 +119,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -119,6 +119,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestOptimizedForSize ParseFrom(pb::CodedInputStream input) { public static TestOptimizedForSize ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -162,6 +168,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -162,6 +168,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestOptimizedForSize BuildPartial() { public override TestOptimizedForSize BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
TestOptimizedForSize returnMe = result; TestOptimizedForSize returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -274,6 +283,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -274,6 +283,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestRequiredOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestRequiredOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestRequiredOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestRequiredOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestRequiredOptimizedForSize ParseFrom(pb::CodedInputStream input) { public static TestRequiredOptimizedForSize ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -317,6 +332,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -317,6 +332,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestRequiredOptimizedForSize BuildPartial() { public override TestRequiredOptimizedForSize BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
TestRequiredOptimizedForSize returnMe = result; TestRequiredOptimizedForSize returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -393,6 +411,12 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -393,6 +411,12 @@ namespace Google.ProtocolBuffers.TestProtos {
public static TestOptionalOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static TestOptionalOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static TestOptionalOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static TestOptionalOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static TestOptionalOptimizedForSize ParseFrom(pb::CodedInputStream input) { public static TestOptionalOptimizedForSize ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -436,6 +460,9 @@ namespace Google.ProtocolBuffers.TestProtos { ...@@ -436,6 +460,9 @@ namespace Google.ProtocolBuffers.TestProtos {
} }
public override TestOptionalOptimizedForSize BuildPartial() { public override TestOptionalOptimizedForSize BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
TestOptionalOptimizedForSize returnMe = result; TestOptionalOptimizedForSize returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System.IO;
using System.Reflection; using System.Reflection;
using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.Descriptors;
using Google.ProtocolBuffers.TestProtos; using Google.ProtocolBuffers.TestProtos;
...@@ -98,6 +99,23 @@ namespace Google.ProtocolBuffers { ...@@ -98,6 +99,23 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual(rawBytes, rawBytes2); Assert.AreEqual(rawBytes, rawBytes2);
} }
[Test]
public void SerializeDelimited() {
MemoryStream stream = new MemoryStream();
TestUtil.GetAllSet().WriteDelimitedTo(stream);
stream.WriteByte(12);
TestUtil.GetPackedSet().WriteDelimitedTo(stream);
stream.WriteByte(34);
stream.Position = 0;
TestUtil.AssertAllFieldsSet(TestAllTypes.ParseDelimitedFrom(stream));
Assert.AreEqual(12, stream.ReadByte());
TestUtil.AssertPackedFieldsSet(TestPackedTypes.ParseDelimitedFrom(stream));
Assert.AreEqual(34, stream.ReadByte());
Assert.AreEqual(-1, stream.ReadByte());
}
[Test] [Test]
public void ParseExtensions() { public void ParseExtensions() {
// TestAllTypes and TestAllExtensions should have compatible wire formats, // TestAllTypes and TestAllExtensions should have compatible wire formats,
...@@ -133,7 +151,7 @@ namespace Google.ProtocolBuffers { ...@@ -133,7 +151,7 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual(TestUtil.GetAllSet().SerializedSize, TestUtil.GetAllExtensionsSet().SerializedSize); Assert.AreEqual(TestUtil.GetAllSet().SerializedSize, TestUtil.GetAllExtensionsSet().SerializedSize);
} }
private void AssertFieldsInOrder(ByteString data) { private static void AssertFieldsInOrder(ByteString data) {
CodedInputStream input = data.CreateCodedInput(); CodedInputStream input = data.CreateCodedInput();
uint previousTag = 0; uint previousTag = 0;
......
...@@ -225,6 +225,16 @@ namespace Google.ProtocolBuffers { ...@@ -225,6 +225,16 @@ namespace Google.ProtocolBuffers {
return ThisBuilder; return ThisBuilder;
} }
public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry) {
int size = CodedInputStream.ReadRawVarint32(input);
Stream limitedStream = new LimitedInputStream(input, size);
return MergeFrom(limitedStream, extensionRegistry);
}
public TBuilder MergeDelimitedFrom(Stream input) {
return MergeDelimitedFrom(input, ExtensionRegistry.Empty);
}
public virtual IBuilder SetField(FieldDescriptor field, object value) { public virtual IBuilder SetField(FieldDescriptor field, object value) {
this[field] = value; this[field] = value;
return ThisBuilder; return ThisBuilder;
...@@ -234,5 +244,70 @@ namespace Google.ProtocolBuffers { ...@@ -234,5 +244,70 @@ namespace Google.ProtocolBuffers {
this[field, index] = value; this[field, index] = value;
return ThisBuilder; return ThisBuilder;
} }
/// <summary>
/// Stream implementation which proxies another stream, only allowing a certain amount
/// of data to be read. Note that this is only used to read delimited streams, so it
/// doesn't attempt to implement everything.
/// </summary>
private class LimitedInputStream : Stream {
private readonly Stream proxied;
private int bytesLeft;
internal LimitedInputStream(Stream proxied, int size) {
this.proxied = proxied;
bytesLeft = size;
}
public override bool CanRead {
get { return true; }
}
public override bool CanSeek {
get { return false; }
}
public override bool CanWrite {
get { return false; }
}
public override void Flush() {
}
public override long Length {
get { throw new NotImplementedException(); }
}
public override long Position {
get {
throw new NotImplementedException();
}
set {
throw new NotImplementedException();
}
}
public override int Read(byte[] buffer, int offset, int count) {
if (bytesLeft > 0) {
int bytesRead = proxied.Read(buffer, offset, Math.Min(bytesLeft, count));
bytesLeft -= bytesRead;
return bytesRead;
}
return 0;
}
public override long Seek(long offset, SeekOrigin origin) {
throw new NotImplementedException();
}
public override void SetLength(long value) {
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count) {
throw new NotImplementedException();
}
}
} }
} }
...@@ -205,6 +205,13 @@ namespace Google.ProtocolBuffers { ...@@ -205,6 +205,13 @@ namespace Google.ProtocolBuffers {
codedOutput.Flush(); codedOutput.Flush();
} }
public void WriteDelimitedTo(Stream output) {
CodedOutputStream codedOutput = CodedOutputStream.CreateInstance(output);
codedOutput.WriteRawVarint32((uint) SerializedSize);
WriteTo(codedOutput);
codedOutput.Flush();
}
public override bool Equals(object other) { public override bool Equals(object other) {
if (other == this) { if (other == this) {
return true; return true;
......
...@@ -141,7 +141,7 @@ namespace Google.ProtocolBuffers { ...@@ -141,7 +141,7 @@ namespace Google.ProtocolBuffers {
/// zero is not a valid tag number. /// zero is not a valid tag number.
/// </summary> /// </summary>
public uint ReadTag() { public uint ReadTag() {
if (bufferPos == bufferSize && !RefillBuffer(false)) { if (IsAtEnd) {
lastTag = 0; lastTag = 0;
return 0; return 0;
} }
...@@ -457,6 +457,41 @@ namespace Google.ProtocolBuffers { ...@@ -457,6 +457,41 @@ namespace Google.ProtocolBuffers {
return (uint)result; return (uint)result;
} }
/// <summary>
/// Reads a varint from the input one byte at a time, so that it does not
/// read any bytes after the end of the varint. If you simply wrapped the
/// stream in a CodedInputStream and used ReadRawVarint32(Stream)}
/// then you would probably end up reading past the end of the varint since
/// CodedInputStream buffers its input.
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
internal static int ReadRawVarint32(Stream input) {
int result = 0;
int offset = 0;
for (; offset < 32; offset += 7) {
int b = input.ReadByte();
if (b == -1) {
throw InvalidProtocolBufferException.TruncatedMessage();
}
result |= (b & 0x7f) << offset;
if ((b & 0x80) == 0) {
return result;
}
}
// Keep reading up to 64 bits.
for (; offset < 64; offset += 7) {
int b = input.ReadByte();
if (b == -1) {
throw InvalidProtocolBufferException.TruncatedMessage();
}
if ((b & 0x80) == 0) {
return result;
}
}
throw InvalidProtocolBufferException.MalformedVarint();
}
/// <summary> /// <summary>
/// Read a raw varint from the stream. /// Read a raw varint from the stream.
/// </summary> /// </summary>
...@@ -555,6 +590,9 @@ namespace Google.ProtocolBuffers { ...@@ -555,6 +590,9 @@ namespace Google.ProtocolBuffers {
/// as you can without harming your app's functionality. Note that /// as you can without harming your app's functionality. Note that
/// size limits only apply when reading from an InputStream, not /// size limits only apply when reading from an InputStream, not
/// when constructed around a raw byte array (nor with ByteString.NewCodedInput). /// when constructed around a raw byte array (nor with ByteString.NewCodedInput).
/// If you want to read several messages from a single CodedInputStream, you
/// can call ResetSizeCounter() after each message to avoid hitting the
/// size limit.
/// </remarks> /// </remarks>
public int SetSizeLimit(int limit) { public int SetSizeLimit(int limit) {
if (limit < 0) { if (limit < 0) {
...@@ -566,6 +604,13 @@ namespace Google.ProtocolBuffers { ...@@ -566,6 +604,13 @@ namespace Google.ProtocolBuffers {
} }
#region Internal reading and buffer management #region Internal reading and buffer management
/// <summary>
/// Resets the current size counter to zero (see SetSizeLimit).
/// </summary>
public void ResetSizeCounter() {
totalBytesRetired = 0;
}
/// <summary> /// <summary>
/// Sets currentLimit to (current position) + byteLimit. This is called /// Sets currentLimit to (current position) + byteLimit. This is called
/// when descending into a length-delimited embedded message. The previous /// when descending into a length-delimited embedded message. The previous
...@@ -622,6 +667,17 @@ namespace Google.ProtocolBuffers { ...@@ -622,6 +667,17 @@ namespace Google.ProtocolBuffers {
} }
} }
/// <summary>
/// Returns true if the stream has reached the end of the input. This is the
/// case if either the end of the underlying input source has been reached or
/// the stream has reached a limit created using PushLimit.
/// </summary>
public bool IsAtEnd {
get {
return bufferPos == bufferSize && !RefillBuffer(false);
}
}
/// <summary> /// <summary>
/// Called when buffer is empty to read more bytes from the /// Called when buffer is empty to read more bytes from the
/// input. If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that /// input. If <paramref name="mustSucceed"/> is true, RefillBuffer() gurantees that
...@@ -649,6 +705,9 @@ namespace Google.ProtocolBuffers { ...@@ -649,6 +705,9 @@ namespace Google.ProtocolBuffers {
bufferPos = 0; bufferPos = 0;
bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length); bufferSize = (input == null) ? 0 : input.Read(buffer, 0, buffer.Length);
if (bufferSize < 0) {
throw new InvalidOperationException("Stream.Read returned a negative count");
}
if (bufferSize == 0) { if (bufferSize == 0) {
if (mustSucceed) { if (mustSucceed) {
throw InvalidProtocolBufferException.TruncatedMessage(); throw InvalidProtocolBufferException.TruncatedMessage();
...@@ -847,7 +906,7 @@ namespace Google.ProtocolBuffers { ...@@ -847,7 +906,7 @@ namespace Google.ProtocolBuffers {
throw InvalidProtocolBufferException.TruncatedMessage(); throw InvalidProtocolBufferException.TruncatedMessage();
} }
if (size < bufferSize - bufferPos) { if (size <= bufferSize - bufferPos) {
// We have all the bytes we need already. // We have all the bytes we need already.
bufferPos += size; bufferPos += size;
} else { } else {
...@@ -863,8 +922,9 @@ namespace Google.ProtocolBuffers { ...@@ -863,8 +922,9 @@ namespace Google.ProtocolBuffers {
if (input == null) { if (input == null) {
throw InvalidProtocolBufferException.TruncatedMessage(); throw InvalidProtocolBufferException.TruncatedMessage();
} }
input.Seek(size - pos, SeekOrigin.Current); long previousPosition = input.Position;
if (input.Position > input.Length) { input.Position += size - pos;
if (input.Position != previousPosition + size - pos) {
throw InvalidProtocolBufferException.TruncatedMessage(); throw InvalidProtocolBufferException.TruncatedMessage();
} }
totalBytesRetired += size - pos; totalBytesRetired += size - pos;
......
...@@ -143,6 +143,12 @@ namespace Google.ProtocolBuffers.DescriptorProtos { ...@@ -143,6 +143,12 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
public static CSharpFileOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static CSharpFileOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static CSharpFileOptions ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static CSharpFileOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static CSharpFileOptions ParseFrom(pb::CodedInputStream input) { public static CSharpFileOptions ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -186,6 +192,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos { ...@@ -186,6 +192,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
} }
public override CSharpFileOptions BuildPartial() { public override CSharpFileOptions BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
CSharpFileOptions returnMe = result; CSharpFileOptions returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
...@@ -336,6 +345,12 @@ namespace Google.ProtocolBuffers.DescriptorProtos { ...@@ -336,6 +345,12 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
public static CSharpFieldOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { public static CSharpFieldOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
} }
public static CSharpFieldOptions ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static CSharpFieldOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static CSharpFieldOptions ParseFrom(pb::CodedInputStream input) { public static CSharpFieldOptions ParseFrom(pb::CodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
} }
...@@ -379,6 +394,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos { ...@@ -379,6 +394,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
} }
public override CSharpFieldOptions BuildPartial() { public override CSharpFieldOptions BuildPartial() {
if (result == null) {
throw new global::System.InvalidOperationException("build() has already been called on this Builder");
}
CSharpFieldOptions returnMe = result; CSharpFieldOptions returnMe = result;
result = null; result = null;
return returnMe; return returnMe;
......
...@@ -248,6 +248,20 @@ namespace Google.ProtocolBuffers { ...@@ -248,6 +248,20 @@ namespace Google.ProtocolBuffers {
/// </summary> /// </summary>
TBuilder MergeUnknownFields(UnknownFieldSet unknownFields); TBuilder MergeUnknownFields(UnknownFieldSet unknownFields);
/// <summary>
/// Like MergeFrom(Stream), but does not read until the end of the file.
/// Instead, the size of the message (encoded as a varint) is read first,
/// then the message data. Use Message.WriteDelimitedTo(Stream) to
/// write messages in this format.
/// </summary>
/// <param name="input"></param>
TBuilder MergeDelimitedFrom(Stream input);
/// <summary>
/// Like MergeDelimitedFrom(Stream) but supporting extensions.
/// </summary>
TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry);
#region Convenience methods #region Convenience methods
/// <summary> /// <summary>
/// Parse <paramref name="data"/> as a message of this type and merge /// Parse <paramref name="data"/> as a message of this type and merge
...@@ -283,8 +297,9 @@ namespace Google.ProtocolBuffers { ...@@ -283,8 +297,9 @@ namespace Google.ProtocolBuffers {
/// MergeFrom(CodedInputStream). Note that this method always reads /// MergeFrom(CodedInputStream). Note that this method always reads
/// the entire input (unless it throws an exception). If you want it to /// the entire input (unless it throws an exception). If you want it to
/// stop earlier, you will need to wrap the input in a wrapper /// stop earlier, you will need to wrap the input in a wrapper
/// stream which limits reading. Despite usually reading the entire /// stream which limits reading. Or, use IMessage.WriteDelimitedTo(Stream)
/// stream, this method never closes the stream. /// to write your message and MmergeDelimitedFrom(Stream) to read it.
/// Despite usually reading the entire stream, this method never closes the stream.
/// </summary> /// </summary>
TBuilder MergeFrom(Stream input); TBuilder MergeFrom(Stream input);
......
...@@ -113,9 +113,26 @@ namespace Google.ProtocolBuffers { ...@@ -113,9 +113,26 @@ namespace Google.ProtocolBuffers {
/// Serializes the message and writes it to the given output stream. /// Serializes the message and writes it to the given output stream.
/// This does not flush or close the stream. /// This does not flush or close the stream.
/// </summary> /// </summary>
/// <param name="output"></param> /// <remarks>
/// Protocol Buffers are not self-delimiting. Therefore, if you write
/// any more data to the stream after the message, you must somehow ensure
/// that the parser on the receiving end does not interpret this as being
/// part of the protocol message. One way of doing this is by writing the size
/// of the message before the data, then making sure you limit the input to
/// that size when receiving the data. Alternatively, use WriteDelimitedTo(Stream).
/// </remarks>
void WriteTo(CodedOutputStream output); void WriteTo(CodedOutputStream output);
/// <summary>
/// Like WriteTo(Stream) but writes the size of the message as a varint before
/// writing the data. This allows more data to be written to the stream after the
/// message without the need to delimit the message data yourself. Use
/// IBuilder.MergeDelimitedFrom(Stream) or the static method
/// YourMessageType.ParseDelimitedFrom(Stream) to parse messages written by this method.
/// </summary>
/// <param name="output"></param>
void WriteDelimitedTo(Stream output);
/// <summary> /// <summary>
/// Returns the number of bytes required to encode this message. /// Returns the number of bytes required to encode this message.
/// The result is only computed on the first call and memoized after that. /// The result is only computed on the first call and memoized after that.
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Collections; using System.Collections;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
......
using System;
using System.Collections.Generic;
using System.Text;
using System.IO; using System.IO;
namespace Google.ProtocolBuffers { namespace Google.ProtocolBuffers {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment