parent
62ce3a625e
commit
d965c666ec
25 changed files with 6794 additions and 6794 deletions
@ -1,71 +1,71 @@ |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// Grab-bag of utility functions useful when dealing with RPCs. |
||||
/// </summary> |
||||
public static class RpcUtil { |
||||
|
||||
/// <summary> |
||||
/// Converts an Action[IMessage] to an Action[T]. |
||||
/// </summary> |
||||
public static Action<T> SpecializeCallback<T>(Action<IMessage> action) |
||||
where T : IMessage<T> { |
||||
return message => action(message); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Converts an Action[T] to an Action[IMessage]. |
||||
/// The generalized action will accept any message object which has |
||||
/// the same descriptor, and will convert it to the correct class |
||||
/// before calling the original action. However, if the generalized |
||||
/// callback is given a message with a different descriptor, an |
||||
/// exception will be thrown. |
||||
/// </summary> |
||||
public static Action<IMessage> GeneralizeCallback<TMessage, TBuilder>(Action<TMessage> action, TMessage defaultInstance) |
||||
where TMessage : class, IMessage<TMessage, TBuilder> |
||||
where TBuilder : IBuilder<TMessage, TBuilder> { |
||||
return message => { |
||||
TMessage castMessage = message as TMessage; |
||||
if (castMessage == null) { |
||||
castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build(); |
||||
} |
||||
action(castMessage); |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// Grab-bag of utility functions useful when dealing with RPCs. |
||||
/// </summary> |
||||
public static class RpcUtil { |
||||
|
||||
/// <summary> |
||||
/// Converts an Action[IMessage] to an Action[T]. |
||||
/// </summary> |
||||
public static Action<T> SpecializeCallback<T>(Action<IMessage> action) |
||||
where T : IMessage<T> { |
||||
return message => action(message); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Converts an Action[T] to an Action[IMessage]. |
||||
/// The generalized action will accept any message object which has |
||||
/// the same descriptor, and will convert it to the correct class |
||||
/// before calling the original action. However, if the generalized |
||||
/// callback is given a message with a different descriptor, an |
||||
/// exception will be thrown. |
||||
/// </summary> |
||||
public static Action<IMessage> GeneralizeCallback<TMessage, TBuilder>(Action<TMessage> action, TMessage defaultInstance) |
||||
where TMessage : class, IMessage<TMessage, TBuilder> |
||||
where TBuilder : IBuilder<TMessage, TBuilder> { |
||||
return message => { |
||||
TMessage castMessage = message as TMessage; |
||||
if (castMessage == null) { |
||||
castMessage = defaultInstance.CreateBuilderForType().MergeFrom(message).Build(); |
||||
} |
||||
action(castMessage); |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,143 +1,143 @@ |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
|
||||
/// <summary> |
||||
/// Helper class to control indentation. Used for TextFormat and by ProtoGen. |
||||
/// </summary> |
||||
public sealed class TextGenerator { |
||||
|
||||
/// <summary> |
||||
/// The string to use at the end of each line. We assume that "Print" is only called using \n |
||||
/// to indicate a line break; that's what we use to detect when we need to indent etc, and |
||||
/// *just* the \n is replaced with the contents of lineBreak. |
||||
/// </summary> |
||||
private readonly string lineBreak; |
||||
|
||||
/// <summary> |
||||
/// Writer to write formatted text to. |
||||
/// </summary> |
||||
private readonly TextWriter writer; |
||||
|
||||
/// <summary> |
||||
/// Keeps track of whether the next piece of text should be indented |
||||
/// </summary> |
||||
bool atStartOfLine = true; |
||||
|
||||
/// <summary> |
||||
/// Keeps track of the current level of indentation |
||||
/// </summary> |
||||
readonly StringBuilder indent = new StringBuilder(); |
||||
|
||||
/// <summary> |
||||
/// Creates a generator writing to the given writer. The writer |
||||
/// is not closed by this class. |
||||
/// </summary> |
||||
public TextGenerator(TextWriter writer, string lineBreak) { |
||||
this.writer = writer; |
||||
this.lineBreak = lineBreak; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Indents text by two spaces. After calling Indent(), two spaces |
||||
/// will be inserted at the beginning of each line of text. Indent() may |
||||
/// be called multiple times to produce deeper indents. |
||||
/// </summary> |
||||
public void Indent() { |
||||
indent.Append(" "); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Reduces the current indent level by two spaces. |
||||
/// </summary> |
||||
public void Outdent() { |
||||
if (indent.Length == 0) { |
||||
throw new InvalidOperationException("Too many calls to Outdent()"); |
||||
} |
||||
indent.Length -= 2; |
||||
} |
||||
|
||||
public void WriteLine(string text) { |
||||
Print(text); |
||||
Print("\n"); |
||||
} |
||||
|
||||
public void WriteLine(string format, params object[] args) { |
||||
WriteLine(string.Format(format, args)); |
||||
} |
||||
|
||||
public void WriteLine() { |
||||
WriteLine(""); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Prints the given text to the output stream, indenting at line boundaries. |
||||
/// </summary> |
||||
/// <param name="text"></param> |
||||
public void Print(string text) { |
||||
int pos = 0; |
||||
|
||||
for (int i = 0; i < text.Length; i++) { |
||||
if (text[i] == '\n') { |
||||
// Strip off the \n from what we write |
||||
Write(text.Substring(pos, i - pos)); |
||||
Write(lineBreak); |
||||
pos = i + 1; |
||||
atStartOfLine = true; |
||||
} |
||||
} |
||||
Write(text.Substring(pos)); |
||||
} |
||||
|
||||
public void Write(string format, params object[] args) { |
||||
Write(string.Format(format, args)); |
||||
} |
||||
|
||||
private void Write(string data) { |
||||
if (data.Length == 0) { |
||||
return; |
||||
} |
||||
if (atStartOfLine) { |
||||
atStartOfLine = false; |
||||
writer.Write(indent); |
||||
} |
||||
writer.Write(data); |
||||
} |
||||
} |
||||
} |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
|
||||
/// <summary> |
||||
/// Helper class to control indentation. Used for TextFormat and by ProtoGen. |
||||
/// </summary> |
||||
public sealed class TextGenerator { |
||||
|
||||
/// <summary> |
||||
/// The string to use at the end of each line. We assume that "Print" is only called using \n |
||||
/// to indicate a line break; that's what we use to detect when we need to indent etc, and |
||||
/// *just* the \n is replaced with the contents of lineBreak. |
||||
/// </summary> |
||||
private readonly string lineBreak; |
||||
|
||||
/// <summary> |
||||
/// Writer to write formatted text to. |
||||
/// </summary> |
||||
private readonly TextWriter writer; |
||||
|
||||
/// <summary> |
||||
/// Keeps track of whether the next piece of text should be indented |
||||
/// </summary> |
||||
bool atStartOfLine = true; |
||||
|
||||
/// <summary> |
||||
/// Keeps track of the current level of indentation |
||||
/// </summary> |
||||
readonly StringBuilder indent = new StringBuilder(); |
||||
|
||||
/// <summary> |
||||
/// Creates a generator writing to the given writer. The writer |
||||
/// is not closed by this class. |
||||
/// </summary> |
||||
public TextGenerator(TextWriter writer, string lineBreak) { |
||||
this.writer = writer; |
||||
this.lineBreak = lineBreak; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Indents text by two spaces. After calling Indent(), two spaces |
||||
/// will be inserted at the beginning of each line of text. Indent() may |
||||
/// be called multiple times to produce deeper indents. |
||||
/// </summary> |
||||
public void Indent() { |
||||
indent.Append(" "); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Reduces the current indent level by two spaces. |
||||
/// </summary> |
||||
public void Outdent() { |
||||
if (indent.Length == 0) { |
||||
throw new InvalidOperationException("Too many calls to Outdent()"); |
||||
} |
||||
indent.Length -= 2; |
||||
} |
||||
|
||||
public void WriteLine(string text) { |
||||
Print(text); |
||||
Print("\n"); |
||||
} |
||||
|
||||
public void WriteLine(string format, params object[] args) { |
||||
WriteLine(string.Format(format, args)); |
||||
} |
||||
|
||||
public void WriteLine() { |
||||
WriteLine(""); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Prints the given text to the output stream, indenting at line boundaries. |
||||
/// </summary> |
||||
/// <param name="text"></param> |
||||
public void Print(string text) { |
||||
int pos = 0; |
||||
|
||||
for (int i = 0; i < text.Length; i++) { |
||||
if (text[i] == '\n') { |
||||
// Strip off the \n from what we write |
||||
Write(text.Substring(pos, i - pos)); |
||||
Write(lineBreak); |
||||
pos = i + 1; |
||||
atStartOfLine = true; |
||||
} |
||||
} |
||||
Write(text.Substring(pos)); |
||||
} |
||||
|
||||
public void Write(string format, params object[] args) { |
||||
Write(string.Format(format, args)); |
||||
} |
||||
|
||||
private void Write(string data) { |
||||
if (data.Length == 0) { |
||||
return; |
||||
} |
||||
if (atStartOfLine) { |
||||
atStartOfLine = false; |
||||
writer.Write(indent); |
||||
} |
||||
writer.Write(data); |
||||
} |
||||
} |
||||
} |
||||
|
@ -1,412 +1,412 @@ |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Globalization; |
||||
using System.Text.RegularExpressions; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// Represents a stream of tokens parsed from a string. |
||||
/// </summary> |
||||
internal sealed class TextTokenizer { |
||||
private readonly string text; |
||||
private string currentToken; |
||||
|
||||
/// <summary> |
||||
/// The character index within the text to perform the next regex match at. |
||||
/// </summary> |
||||
private int matchPos = 0; |
||||
|
||||
/// <summary> |
||||
/// The character index within the text at which the current token begins. |
||||
/// </summary> |
||||
private int pos = 0; |
||||
|
||||
/// <summary> |
||||
/// The line number of the current token. |
||||
/// </summary> |
||||
private int line = 0; |
||||
/// <summary> |
||||
/// The column number of the current token. |
||||
/// </summary> |
||||
private int column = 0; |
||||
|
||||
/// <summary> |
||||
/// The line number of the previous token. |
||||
/// </summary> |
||||
private int previousLine = 0; |
||||
/// <summary> |
||||
/// The column number of the previous token. |
||||
/// </summary> |
||||
private int previousColumn = 0; |
||||
|
||||
// Note: atomic groups used to mimic possessive quantifiers in Java in both of these regexes |
||||
internal static readonly Regex WhitespaceAndCommentPattern = new Regex("\\G(?>(\\s|(#.*$))+)", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline); |
||||
private static readonly Regex TokenPattern = new Regex( |
||||
"\\G[a-zA-Z_](?>[0-9a-zA-Z_+-]*)|" + // an identifier |
||||
"\\G[0-9+-](?>[0-9a-zA-Z_.+-]*)|" + // a number |
||||
"\\G\"(?>([^\"\\\n\\\\]|\\\\.)*)(\"|\\\\?$)|" + // a double-quoted string |
||||
"\\G\'(?>([^\"\\\n\\\\]|\\\\.)*)(\'|\\\\?$)", // a single-quoted string |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline); |
||||
|
||||
private static readonly Regex DoubleInfinity = new Regex("^-?inf(inity)?$", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); |
||||
private static readonly Regex FloatInfinity = new Regex("^-?inf(inity)?f?$", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); |
||||
private static readonly Regex FloatNan = new Regex("^nanf?$", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); |
||||
|
||||
/** Construct a tokenizer that parses tokens from the given text. */ |
||||
public TextTokenizer(string text) { |
||||
this.text = text; |
||||
SkipWhitespace(); |
||||
NextToken(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Are we at the end of the input? |
||||
/// </summary> |
||||
public bool AtEnd { |
||||
get { return currentToken.Length == 0; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Advances to the next token. |
||||
/// </summary> |
||||
public void NextToken() { |
||||
previousLine = line; |
||||
previousColumn = column; |
||||
|
||||
// Advance the line counter to the current position. |
||||
while (pos < matchPos) { |
||||
if (text[pos] == '\n') { |
||||
++line; |
||||
column = 0; |
||||
} else { |
||||
++column; |
||||
} |
||||
++pos; |
||||
} |
||||
|
||||
// Match the next token. |
||||
if (matchPos == text.Length) { |
||||
// EOF |
||||
currentToken = ""; |
||||
} else { |
||||
Match match = TokenPattern.Match(text, matchPos); |
||||
if (match.Success) { |
||||
currentToken = match.Value; |
||||
matchPos += match.Length; |
||||
} else { |
||||
// Take one character. |
||||
currentToken = text[matchPos].ToString(); |
||||
matchPos++; |
||||
} |
||||
|
||||
SkipWhitespace(); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Skip over any whitespace so that matchPos starts at the next token. |
||||
/// </summary> |
||||
private void SkipWhitespace() { |
||||
Match match = WhitespaceAndCommentPattern.Match(text, matchPos); |
||||
if (match.Success) { |
||||
matchPos += match.Length; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token exactly matches the given token, consume it and return |
||||
/// true. Otherwise, return false without doing anything. |
||||
/// </summary> |
||||
public bool TryConsume(string token) { |
||||
if (currentToken == token) { |
||||
NextToken(); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/* |
||||
* If the next token exactly matches {@code token}, consume it. Otherwise, |
||||
* throw a {@link ParseException}. |
||||
*/ |
||||
/// <summary> |
||||
/// If the next token exactly matches the specified one, consume it. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
/// <param name="token"></param> |
||||
public void Consume(string token) { |
||||
if (!TryConsume(token)) { |
||||
throw CreateFormatException("Expected \"" + token + "\"."); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns true if the next token is an integer, but does not consume it. |
||||
/// </summary> |
||||
public bool LookingAtInteger() { |
||||
if (currentToken.Length == 0) { |
||||
return false; |
||||
} |
||||
|
||||
char c = currentToken[0]; |
||||
return ('0' <= c && c <= '9') || c == '-' || c == '+'; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is an identifier, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public string ConsumeIdentifier() { |
||||
foreach (char c in currentToken) { |
||||
if (('a' <= c && c <= 'z') || |
||||
('A' <= c && c <= 'Z') || |
||||
('0' <= c && c <= '9') || |
||||
(c == '_') || (c == '.')) { |
||||
// OK |
||||
} else { |
||||
throw CreateFormatException("Expected identifier."); |
||||
} |
||||
} |
||||
|
||||
string result = currentToken; |
||||
NextToken(); |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 32-bit signed integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public int ConsumeInt32() { |
||||
try { |
||||
int result = TextFormat.ParseInt32(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 32-bit unsigned integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public uint ConsumeUInt32() { |
||||
try { |
||||
uint result = TextFormat.ParseUInt32(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 64-bit signed integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public long ConsumeInt64() { |
||||
try { |
||||
long result = TextFormat.ParseInt64(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 64-bit unsigned integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public ulong ConsumeUInt64() { |
||||
try { |
||||
ulong result = TextFormat.ParseUInt64(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a double, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public double ConsumeDouble() { |
||||
// We need to parse infinity and nan separately because |
||||
// double.Parse() does not accept "inf", "infinity", or "nan". |
||||
if (DoubleInfinity.IsMatch(currentToken)) { |
||||
bool negative = currentToken.StartsWith("-"); |
||||
NextToken(); |
||||
return negative ? double.NegativeInfinity : double.PositiveInfinity; |
||||
} |
||||
if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase)) { |
||||
NextToken(); |
||||
return Double.NaN; |
||||
} |
||||
|
||||
try { |
||||
double result = double.Parse(currentToken, CultureInfo.InvariantCulture); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateFloatParseException(e); |
||||
} catch (OverflowException e) { |
||||
throw CreateFloatParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a float, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public float ConsumeFloat() { |
||||
// We need to parse infinity and nan separately because |
||||
// Float.parseFloat() does not accept "inf", "infinity", or "nan". |
||||
if (FloatInfinity.IsMatch(currentToken)) { |
||||
bool negative = currentToken.StartsWith("-"); |
||||
NextToken(); |
||||
return negative ? float.NegativeInfinity : float.PositiveInfinity; |
||||
} |
||||
if (FloatNan.IsMatch(currentToken)) { |
||||
NextToken(); |
||||
return float.NaN; |
||||
} |
||||
|
||||
if (currentToken.EndsWith("f")) { |
||||
currentToken = currentToken.TrimEnd('f'); |
||||
} |
||||
|
||||
try { |
||||
float result = float.Parse(currentToken, CultureInfo.InvariantCulture); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateFloatParseException(e); |
||||
} catch (OverflowException e) { |
||||
throw CreateFloatParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a Boolean, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public bool ConsumeBoolean() { |
||||
if (currentToken == "true") { |
||||
NextToken(); |
||||
return true; |
||||
} |
||||
if (currentToken == "false") { |
||||
NextToken(); |
||||
return false; |
||||
} |
||||
throw CreateFormatException("Expected \"true\" or \"false\"."); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a string, consume it and return its (unescaped) value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public string ConsumeString() { |
||||
return ConsumeByteString().ToStringUtf8(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a string, consume it, unescape it as a |
||||
/// ByteString and return it. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public ByteString ConsumeByteString() { |
||||
char quote = currentToken.Length > 0 ? currentToken[0] : '\0'; |
||||
if (quote != '\"' && quote != '\'') { |
||||
throw CreateFormatException("Expected string."); |
||||
} |
||||
|
||||
if (currentToken.Length < 2 || |
||||
currentToken[currentToken.Length-1] != quote) { |
||||
throw CreateFormatException("String missing ending quote."); |
||||
} |
||||
|
||||
try { |
||||
string escaped = currentToken.Substring(1, currentToken.Length - 2); |
||||
ByteString result = TextFormat.UnescapeBytes(escaped); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateFormatException(e.Message); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a format exception with the current line and column numbers |
||||
/// in the description, suitable for throwing. |
||||
/// </summary> |
||||
public FormatException CreateFormatException(string description) { |
||||
// Note: People generally prefer one-based line and column numbers. |
||||
return new FormatException((line + 1) + ":" + (column + 1) + ": " + description); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a format exception with the line and column numbers of the |
||||
/// previous token in the description, suitable for throwing. |
||||
/// </summary> |
||||
public FormatException CreateFormatExceptionPreviousToken(string description) { |
||||
// Note: People generally prefer one-based line and column numbers. |
||||
return new FormatException((previousLine + 1) + ":" + (previousColumn + 1) + ": " + description); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs an appropriate FormatException for the given existing exception |
||||
/// when trying to parse an integer. |
||||
/// </summary> |
||||
private FormatException CreateIntegerParseException(FormatException e) { |
||||
return CreateFormatException("Couldn't parse integer: " + e.Message); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs an appropriate FormatException for the given existing exception |
||||
/// when trying to parse a float or double. |
||||
/// </summary> |
||||
private FormatException CreateFloatParseException(Exception e) { |
||||
return CreateFormatException("Couldn't parse number: " + e.Message); |
||||
} |
||||
} |
||||
} |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Globalization; |
||||
using System.Text.RegularExpressions; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// Represents a stream of tokens parsed from a string. |
||||
/// </summary> |
||||
internal sealed class TextTokenizer { |
||||
private readonly string text; |
||||
private string currentToken; |
||||
|
||||
/// <summary> |
||||
/// The character index within the text to perform the next regex match at. |
||||
/// </summary> |
||||
private int matchPos = 0; |
||||
|
||||
/// <summary> |
||||
/// The character index within the text at which the current token begins. |
||||
/// </summary> |
||||
private int pos = 0; |
||||
|
||||
/// <summary> |
||||
/// The line number of the current token. |
||||
/// </summary> |
||||
private int line = 0; |
||||
/// <summary> |
||||
/// The column number of the current token. |
||||
/// </summary> |
||||
private int column = 0; |
||||
|
||||
/// <summary> |
||||
/// The line number of the previous token. |
||||
/// </summary> |
||||
private int previousLine = 0; |
||||
/// <summary> |
||||
/// The column number of the previous token. |
||||
/// </summary> |
||||
private int previousColumn = 0; |
||||
|
||||
// Note: atomic groups used to mimic possessive quantifiers in Java in both of these regexes |
||||
internal static readonly Regex WhitespaceAndCommentPattern = new Regex("\\G(?>(\\s|(#.*$))+)", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline); |
||||
private static readonly Regex TokenPattern = new Regex( |
||||
"\\G[a-zA-Z_](?>[0-9a-zA-Z_+-]*)|" + // an identifier |
||||
"\\G[0-9+-](?>[0-9a-zA-Z_.+-]*)|" + // a number |
||||
"\\G\"(?>([^\"\\\n\\\\]|\\\\.)*)(\"|\\\\?$)|" + // a double-quoted string |
||||
"\\G\'(?>([^\"\\\n\\\\]|\\\\.)*)(\'|\\\\?$)", // a single-quoted string |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.Multiline); |
||||
|
||||
private static readonly Regex DoubleInfinity = new Regex("^-?inf(inity)?$", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); |
||||
private static readonly Regex FloatInfinity = new Regex("^-?inf(inity)?f?$", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); |
||||
private static readonly Regex FloatNan = new Regex("^nanf?$", |
||||
SilverlightCompatibility.CompiledRegexWhereAvailable | RegexOptions.IgnoreCase); |
||||
|
||||
/** Construct a tokenizer that parses tokens from the given text. */ |
||||
public TextTokenizer(string text) { |
||||
this.text = text; |
||||
SkipWhitespace(); |
||||
NextToken(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Are we at the end of the input? |
||||
/// </summary> |
||||
public bool AtEnd { |
||||
get { return currentToken.Length == 0; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Advances to the next token. |
||||
/// </summary> |
||||
public void NextToken() { |
||||
previousLine = line; |
||||
previousColumn = column; |
||||
|
||||
// Advance the line counter to the current position. |
||||
while (pos < matchPos) { |
||||
if (text[pos] == '\n') { |
||||
++line; |
||||
column = 0; |
||||
} else { |
||||
++column; |
||||
} |
||||
++pos; |
||||
} |
||||
|
||||
// Match the next token. |
||||
if (matchPos == text.Length) { |
||||
// EOF |
||||
currentToken = ""; |
||||
} else { |
||||
Match match = TokenPattern.Match(text, matchPos); |
||||
if (match.Success) { |
||||
currentToken = match.Value; |
||||
matchPos += match.Length; |
||||
} else { |
||||
// Take one character. |
||||
currentToken = text[matchPos].ToString(); |
||||
matchPos++; |
||||
} |
||||
|
||||
SkipWhitespace(); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Skip over any whitespace so that matchPos starts at the next token. |
||||
/// </summary> |
||||
private void SkipWhitespace() { |
||||
Match match = WhitespaceAndCommentPattern.Match(text, matchPos); |
||||
if (match.Success) { |
||||
matchPos += match.Length; |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token exactly matches the given token, consume it and return |
||||
/// true. Otherwise, return false without doing anything. |
||||
/// </summary> |
||||
public bool TryConsume(string token) { |
||||
if (currentToken == token) { |
||||
NextToken(); |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/* |
||||
* If the next token exactly matches {@code token}, consume it. Otherwise, |
||||
* throw a {@link ParseException}. |
||||
*/ |
||||
/// <summary> |
||||
/// If the next token exactly matches the specified one, consume it. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
/// <param name="token"></param> |
||||
public void Consume(string token) { |
||||
if (!TryConsume(token)) { |
||||
throw CreateFormatException("Expected \"" + token + "\"."); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns true if the next token is an integer, but does not consume it. |
||||
/// </summary> |
||||
public bool LookingAtInteger() { |
||||
if (currentToken.Length == 0) { |
||||
return false; |
||||
} |
||||
|
||||
char c = currentToken[0]; |
||||
return ('0' <= c && c <= '9') || c == '-' || c == '+'; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is an identifier, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public string ConsumeIdentifier() { |
||||
foreach (char c in currentToken) { |
||||
if (('a' <= c && c <= 'z') || |
||||
('A' <= c && c <= 'Z') || |
||||
('0' <= c && c <= '9') || |
||||
(c == '_') || (c == '.')) { |
||||
// OK |
||||
} else { |
||||
throw CreateFormatException("Expected identifier."); |
||||
} |
||||
} |
||||
|
||||
string result = currentToken; |
||||
NextToken(); |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 32-bit signed integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public int ConsumeInt32() { |
||||
try { |
||||
int result = TextFormat.ParseInt32(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 32-bit unsigned integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public uint ConsumeUInt32() { |
||||
try { |
||||
uint result = TextFormat.ParseUInt32(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 64-bit signed integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public long ConsumeInt64() { |
||||
try { |
||||
long result = TextFormat.ParseInt64(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a 64-bit unsigned integer, consume it and return its |
||||
/// value. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public ulong ConsumeUInt64() { |
||||
try { |
||||
ulong result = TextFormat.ParseUInt64(currentToken); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateIntegerParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a double, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public double ConsumeDouble() { |
||||
// We need to parse infinity and nan separately because |
||||
// double.Parse() does not accept "inf", "infinity", or "nan". |
||||
if (DoubleInfinity.IsMatch(currentToken)) { |
||||
bool negative = currentToken.StartsWith("-"); |
||||
NextToken(); |
||||
return negative ? double.NegativeInfinity : double.PositiveInfinity; |
||||
} |
||||
if (currentToken.Equals("nan", StringComparison.InvariantCultureIgnoreCase)) { |
||||
NextToken(); |
||||
return Double.NaN; |
||||
} |
||||
|
||||
try { |
||||
double result = double.Parse(currentToken, CultureInfo.InvariantCulture); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateFloatParseException(e); |
||||
} catch (OverflowException e) { |
||||
throw CreateFloatParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a float, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public float ConsumeFloat() { |
||||
// We need to parse infinity and nan separately because |
||||
// Float.parseFloat() does not accept "inf", "infinity", or "nan". |
||||
if (FloatInfinity.IsMatch(currentToken)) { |
||||
bool negative = currentToken.StartsWith("-"); |
||||
NextToken(); |
||||
return negative ? float.NegativeInfinity : float.PositiveInfinity; |
||||
} |
||||
if (FloatNan.IsMatch(currentToken)) { |
||||
NextToken(); |
||||
return float.NaN; |
||||
} |
||||
|
||||
if (currentToken.EndsWith("f")) { |
||||
currentToken = currentToken.TrimEnd('f'); |
||||
} |
||||
|
||||
try { |
||||
float result = float.Parse(currentToken, CultureInfo.InvariantCulture); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateFloatParseException(e); |
||||
} catch (OverflowException e) { |
||||
throw CreateFloatParseException(e); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a Boolean, consume it and return its value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public bool ConsumeBoolean() { |
||||
if (currentToken == "true") { |
||||
NextToken(); |
||||
return true; |
||||
} |
||||
if (currentToken == "false") { |
||||
NextToken(); |
||||
return false; |
||||
} |
||||
throw CreateFormatException("Expected \"true\" or \"false\"."); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a string, consume it and return its (unescaped) value. |
||||
/// Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public string ConsumeString() { |
||||
return ConsumeByteString().ToStringUtf8(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// If the next token is a string, consume it, unescape it as a |
||||
/// ByteString and return it. Otherwise, throw a FormatException. |
||||
/// </summary> |
||||
public ByteString ConsumeByteString() { |
||||
char quote = currentToken.Length > 0 ? currentToken[0] : '\0'; |
||||
if (quote != '\"' && quote != '\'') { |
||||
throw CreateFormatException("Expected string."); |
||||
} |
||||
|
||||
if (currentToken.Length < 2 || |
||||
currentToken[currentToken.Length-1] != quote) { |
||||
throw CreateFormatException("String missing ending quote."); |
||||
} |
||||
|
||||
try { |
||||
string escaped = currentToken.Substring(1, currentToken.Length - 2); |
||||
ByteString result = TextFormat.UnescapeBytes(escaped); |
||||
NextToken(); |
||||
return result; |
||||
} catch (FormatException e) { |
||||
throw CreateFormatException(e.Message); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a format exception with the current line and column numbers |
||||
/// in the description, suitable for throwing. |
||||
/// </summary> |
||||
public FormatException CreateFormatException(string description) { |
||||
// Note: People generally prefer one-based line and column numbers. |
||||
return new FormatException((line + 1) + ":" + (column + 1) + ": " + description); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a format exception with the line and column numbers of the |
||||
/// previous token in the description, suitable for throwing. |
||||
/// </summary> |
||||
public FormatException CreateFormatExceptionPreviousToken(string description) { |
||||
// Note: People generally prefer one-based line and column numbers. |
||||
return new FormatException((previousLine + 1) + ":" + (previousColumn + 1) + ": " + description); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs an appropriate FormatException for the given existing exception |
||||
/// when trying to parse an integer. |
||||
/// </summary> |
||||
private FormatException CreateIntegerParseException(FormatException e) { |
||||
return CreateFormatException("Couldn't parse integer: " + e.Message); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs an appropriate FormatException for the given existing exception |
||||
/// when trying to parse a float or double. |
||||
/// </summary> |
||||
private FormatException CreateFloatParseException(Exception e) { |
||||
return CreateFormatException("Couldn't parse number: " + e.Message); |
||||
} |
||||
} |
||||
} |
||||
|
@ -1,170 +1,170 @@ |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
#if !LITE |
||||
using Google.ProtocolBuffers.Collections; |
||||
using Google.ProtocolBuffers.Descriptors; |
||||
#endif |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// TODO(jonskeet): Write summary text. |
||||
/// </summary> |
||||
public sealed class UninitializedMessageException : Exception { |
||||
|
||||
private readonly IList<string> missingFields; |
||||
|
||||
private UninitializedMessageException(IList<string> missingFields) |
||||
: base(BuildDescription(missingFields)) { |
||||
this.missingFields = new List<string>(missingFields); |
||||
} |
||||
/// <summary> |
||||
/// Returns a read-only list of human-readable names of |
||||
/// required fields missing from this message. Each name |
||||
/// is a full path to a field, e.g. "foo.bar[5].baz" |
||||
/// </summary> |
||||
public IList<string> MissingFields { |
||||
get { return missingFields; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Converts this exception into an InvalidProtocolBufferException. |
||||
/// When a parsed message is missing required fields, this should be thrown |
||||
/// instead of UninitializedMessageException. |
||||
/// </summary> |
||||
public InvalidProtocolBufferException AsInvalidProtocolBufferException() { |
||||
return new InvalidProtocolBufferException(Message); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs the description string for a given list of missing fields. |
||||
/// </summary> |
||||
private static string BuildDescription(IEnumerable<string> missingFields) { |
||||
StringBuilder description = new StringBuilder("Message missing required fields: "); |
||||
bool first = true; |
||||
foreach(string field in missingFields) { |
||||
if (first) { |
||||
first = false; |
||||
} else { |
||||
description.Append(", "); |
||||
} |
||||
description.Append(field); |
||||
} |
||||
return description.ToString(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// For Lite exceptions that do not known how to enumerate missing fields |
||||
/// </summary> |
||||
public UninitializedMessageException(IMessageLite message) |
||||
: base(String.Format("Message {0} is missing required fields", message.GetType())) { |
||||
missingFields = new List<string>(); |
||||
} |
||||
|
||||
#if !LITE |
||||
public UninitializedMessageException(IMessage message) |
||||
: this(FindMissingFields(message)) { |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a list of the full "paths" of missing required |
||||
/// fields in the specified message. |
||||
/// </summary> |
||||
private static IList<String> FindMissingFields(IMessage message) { |
||||
List<String> results = new List<String>(); |
||||
FindMissingFields(message, "", results); |
||||
return results; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Recursive helper implementing FindMissingFields. |
||||
/// </summary> |
||||
private static void FindMissingFields(IMessage message, String prefix, List<String> results) { |
||||
foreach (FieldDescriptor field in message.DescriptorForType.Fields) { |
||||
if (field.IsRequired && !message.HasField(field)) { |
||||
results.Add(prefix + field.Name); |
||||
} |
||||
} |
||||
|
||||
foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) { |
||||
FieldDescriptor field = entry.Key; |
||||
object value = entry.Value; |
||||
|
||||
if (field.MappedType == MappedType.Message) { |
||||
if (field.IsRepeated) { |
||||
int i = 0; |
||||
foreach (object element in (IEnumerable) value) { |
||||
if (element is IMessage) { |
||||
FindMissingFields((IMessage)element, SubMessagePrefix(prefix, field, i++), results); |
||||
} else { |
||||
results.Add(prefix + field.Name); |
||||
} |
||||
} |
||||
} else { |
||||
if (message.HasField(field)) { |
||||
if (value is IMessage) { |
||||
FindMissingFields((IMessage)value, SubMessagePrefix(prefix, field, -1), results); |
||||
} else { |
||||
results.Add(prefix + field.Name); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index) { |
||||
StringBuilder result = new StringBuilder(prefix); |
||||
if (field.IsExtension) { |
||||
result.Append('(') |
||||
.Append(field.FullName) |
||||
.Append(')'); |
||||
} else { |
||||
result.Append(field.Name); |
||||
} |
||||
if (index != -1) { |
||||
result.Append('[') |
||||
.Append(index) |
||||
.Append(']'); |
||||
} |
||||
result.Append('.'); |
||||
return result.ToString(); |
||||
} |
||||
#endif |
||||
} |
||||
} |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Text; |
||||
#if !LITE |
||||
using Google.ProtocolBuffers.Collections; |
||||
using Google.ProtocolBuffers.Descriptors; |
||||
#endif |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// TODO(jonskeet): Write summary text. |
||||
/// </summary> |
||||
public sealed class UninitializedMessageException : Exception { |
||||
|
||||
private readonly IList<string> missingFields; |
||||
|
||||
private UninitializedMessageException(IList<string> missingFields) |
||||
: base(BuildDescription(missingFields)) { |
||||
this.missingFields = new List<string>(missingFields); |
||||
} |
||||
/// <summary> |
||||
/// Returns a read-only list of human-readable names of |
||||
/// required fields missing from this message. Each name |
||||
/// is a full path to a field, e.g. "foo.bar[5].baz" |
||||
/// </summary> |
||||
public IList<string> MissingFields { |
||||
get { return missingFields; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Converts this exception into an InvalidProtocolBufferException. |
||||
/// When a parsed message is missing required fields, this should be thrown |
||||
/// instead of UninitializedMessageException. |
||||
/// </summary> |
||||
public InvalidProtocolBufferException AsInvalidProtocolBufferException() { |
||||
return new InvalidProtocolBufferException(Message); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs the description string for a given list of missing fields. |
||||
/// </summary> |
||||
private static string BuildDescription(IEnumerable<string> missingFields) { |
||||
StringBuilder description = new StringBuilder("Message missing required fields: "); |
||||
bool first = true; |
||||
foreach(string field in missingFields) { |
||||
if (first) { |
||||
first = false; |
||||
} else { |
||||
description.Append(", "); |
||||
} |
||||
description.Append(field); |
||||
} |
||||
return description.ToString(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// For Lite exceptions that do not known how to enumerate missing fields |
||||
/// </summary> |
||||
public UninitializedMessageException(IMessageLite message) |
||||
: base(String.Format("Message {0} is missing required fields", message.GetType())) { |
||||
missingFields = new List<string>(); |
||||
} |
||||
|
||||
#if !LITE |
||||
public UninitializedMessageException(IMessage message) |
||||
: this(FindMissingFields(message)) { |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a list of the full "paths" of missing required |
||||
/// fields in the specified message. |
||||
/// </summary> |
||||
private static IList<String> FindMissingFields(IMessage message) { |
||||
List<String> results = new List<String>(); |
||||
FindMissingFields(message, "", results); |
||||
return results; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Recursive helper implementing FindMissingFields. |
||||
/// </summary> |
||||
private static void FindMissingFields(IMessage message, String prefix, List<String> results) { |
||||
foreach (FieldDescriptor field in message.DescriptorForType.Fields) { |
||||
if (field.IsRequired && !message.HasField(field)) { |
||||
results.Add(prefix + field.Name); |
||||
} |
||||
} |
||||
|
||||
foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) { |
||||
FieldDescriptor field = entry.Key; |
||||
object value = entry.Value; |
||||
|
||||
if (field.MappedType == MappedType.Message) { |
||||
if (field.IsRepeated) { |
||||
int i = 0; |
||||
foreach (object element in (IEnumerable) value) { |
||||
if (element is IMessage) { |
||||
FindMissingFields((IMessage)element, SubMessagePrefix(prefix, field, i++), results); |
||||
} else { |
||||
results.Add(prefix + field.Name); |
||||
} |
||||
} |
||||
} else { |
||||
if (message.HasField(field)) { |
||||
if (value is IMessage) { |
||||
FindMissingFields((IMessage)value, SubMessagePrefix(prefix, field, -1), results); |
||||
} else { |
||||
results.Add(prefix + field.Name); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static String SubMessagePrefix(String prefix, FieldDescriptor field, int index) { |
||||
StringBuilder result = new StringBuilder(prefix); |
||||
if (field.IsExtension) { |
||||
result.Append('(') |
||||
.Append(field.FullName) |
||||
.Append(')'); |
||||
} else { |
||||
result.Append(field.Name); |
||||
} |
||||
if (index != -1) { |
||||
result.Append('[') |
||||
.Append(index) |
||||
.Append(']'); |
||||
} |
||||
result.Append('.'); |
||||
return result.ToString(); |
||||
} |
||||
#endif |
||||
} |
||||
} |
||||
|
@ -1,371 +1,371 @@ |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using Google.ProtocolBuffers.Collections; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// Represents a single field in an UnknownFieldSet. |
||||
/// |
||||
/// An UnknownField consists of five lists of values. The lists correspond |
||||
/// to the five "wire types" used in the protocol buffer binary format. |
||||
/// The wire type of each field can be determined from the encoded form alone, |
||||
/// without knowing the field's declared type. So, we are able to parse |
||||
/// unknown values at least this far and separate them. Normally, only one |
||||
/// of the five lists will contain any values, since it is impossible to |
||||
/// define a valid message type that declares two different types for the |
||||
/// same field number. However, the code is designed to allow for the case |
||||
/// where the same unknown field number is encountered using multiple different |
||||
/// wire types. |
||||
/// |
||||
/// UnknownField is an immutable class. To construct one, you must use an |
||||
/// UnknownField.Builder. |
||||
/// </summary> |
||||
public sealed class UnknownField { |
||||
|
||||
private static readonly UnknownField defaultInstance = CreateBuilder().Build(); |
||||
private readonly ReadOnlyCollection<ulong> varintList; |
||||
private readonly ReadOnlyCollection<uint> fixed32List; |
||||
private readonly ReadOnlyCollection<ulong> fixed64List; |
||||
private readonly ReadOnlyCollection<ByteString> lengthDelimitedList; |
||||
private readonly ReadOnlyCollection<UnknownFieldSet> groupList; |
||||
|
||||
private UnknownField(ReadOnlyCollection<ulong> varintList, |
||||
ReadOnlyCollection<uint> fixed32List, |
||||
ReadOnlyCollection<ulong> fixed64List, |
||||
ReadOnlyCollection<ByteString> lengthDelimitedList, |
||||
ReadOnlyCollection<UnknownFieldSet> groupList) { |
||||
this.varintList = varintList; |
||||
this.fixed32List = fixed32List; |
||||
this.fixed64List = fixed64List; |
||||
this.lengthDelimitedList = lengthDelimitedList; |
||||
this.groupList = groupList; |
||||
} |
||||
|
||||
public static UnknownField DefaultInstance { |
||||
get { return defaultInstance; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of varint values for this field. |
||||
/// </summary> |
||||
public IList<ulong> VarintList { |
||||
get { return varintList; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of fixed32 values for this field. |
||||
/// </summary> |
||||
public IList<uint> Fixed32List { |
||||
get { return fixed32List; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of fixed64 values for this field. |
||||
/// </summary> |
||||
public IList<ulong> Fixed64List { |
||||
get { return fixed64List; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of length-delimited values for this field. |
||||
/// </summary> |
||||
public IList<ByteString> LengthDelimitedList { |
||||
get { return lengthDelimitedList; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of embedded group values for this field. These |
||||
/// are represented using UnknownFieldSets rather than Messages |
||||
/// since the group's type is presumably unknown. |
||||
/// </summary> |
||||
public IList<UnknownFieldSet> GroupList { |
||||
get { return groupList; } |
||||
} |
||||
|
||||
public override bool Equals(object other) { |
||||
if (ReferenceEquals(this, other)) { |
||||
return true; |
||||
} |
||||
UnknownField otherField = other as UnknownField; |
||||
return otherField != null |
||||
&& Lists.Equals(varintList, otherField.varintList) |
||||
&& Lists.Equals(fixed32List, otherField.fixed32List) |
||||
&& Lists.Equals(fixed64List, otherField.fixed64List) |
||||
&& Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList) |
||||
&& Lists.Equals(groupList, otherField.groupList); |
||||
} |
||||
|
||||
public override int GetHashCode() { |
||||
int hash = 43; |
||||
hash = hash * 47 + Lists.GetHashCode(varintList); |
||||
hash = hash * 47 + Lists.GetHashCode(fixed32List); |
||||
hash = hash * 47 + Lists.GetHashCode(fixed64List); |
||||
hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList); |
||||
hash = hash * 47 + Lists.GetHashCode(groupList); |
||||
return hash; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs a new Builder. |
||||
/// </summary> |
||||
public static Builder CreateBuilder() { |
||||
return new Builder(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs a new Builder and initializes it to a copy of <paramref name="copyFrom"/>. |
||||
/// </summary> |
||||
public static Builder CreateBuilder(UnknownField copyFrom) { |
||||
return new Builder().MergeFrom(copyFrom); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Serializes the field, including the field number, and writes it to |
||||
/// <paramref name="output"/>. |
||||
/// </summary> |
||||
public void WriteTo(int fieldNumber, CodedOutputStream output) { |
||||
foreach (ulong value in varintList) { |
||||
output.WriteUInt64(fieldNumber, value); |
||||
} |
||||
foreach (uint value in fixed32List) { |
||||
output.WriteFixed32(fieldNumber, value); |
||||
} |
||||
foreach (ulong value in fixed64List) { |
||||
output.WriteFixed64(fieldNumber, value); |
||||
} |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
output.WriteBytes(fieldNumber, value); |
||||
} |
||||
foreach (UnknownFieldSet value in groupList) { |
||||
#pragma warning disable 0612 |
||||
output.WriteUnknownGroup(fieldNumber, value); |
||||
#pragma warning restore 0612 |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Computes the number of bytes required to encode this field, including field |
||||
/// number. |
||||
/// </summary> |
||||
public int GetSerializedSize(int fieldNumber) { |
||||
int result = 0; |
||||
foreach (ulong value in varintList) { |
||||
result += CodedOutputStream.ComputeUInt64Size(fieldNumber, value); |
||||
} |
||||
foreach (uint value in fixed32List) { |
||||
result += CodedOutputStream.ComputeFixed32Size(fieldNumber, value); |
||||
} |
||||
foreach (ulong value in fixed64List) { |
||||
result += CodedOutputStream.ComputeFixed64Size(fieldNumber, value); |
||||
} |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
result += CodedOutputStream.ComputeBytesSize(fieldNumber, value); |
||||
} |
||||
foreach (UnknownFieldSet value in groupList) { |
||||
#pragma warning disable 0612 |
||||
result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value); |
||||
#pragma warning restore 0612 |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Serializes the length-delimited values of the field, including field |
||||
/// number, and writes them to <paramref name="output"/> using the MessageSet wire format. |
||||
/// </summary> |
||||
/// <param name="fieldNumber"></param> |
||||
/// <param name="output"></param> |
||||
public void WriteAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) { |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
output.WriteRawMessageSetExtension(fieldNumber, value); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Get the number of bytes required to encode this field, incuding field number, |
||||
/// using the MessageSet wire format. |
||||
/// </summary> |
||||
public int GetSerializedSizeAsMessageSetExtension(int fieldNumber) { |
||||
int result = 0; |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
result += CodedOutputStream.ComputeRawMessageSetExtensionSize(fieldNumber, value); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Used to build instances of UnknownField. |
||||
/// </summary> |
||||
public sealed class Builder { |
||||
|
||||
private List<ulong> varintList; |
||||
private List<uint> fixed32List; |
||||
private List<ulong> fixed64List; |
||||
private List<ByteString> lengthDelimitedList; |
||||
private List<UnknownFieldSet> groupList; |
||||
|
||||
/// <summary> |
||||
/// Builds the field. After building, the builder is reset to an empty |
||||
/// state. (This is actually easier than making it unusable.) |
||||
/// </summary> |
||||
public UnknownField Build() { |
||||
return new UnknownField(MakeReadOnly(ref varintList), |
||||
MakeReadOnly(ref fixed32List), |
||||
MakeReadOnly(ref fixed64List), |
||||
MakeReadOnly(ref lengthDelimitedList), |
||||
MakeReadOnly(ref groupList)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Merge the values in <paramref name="other" /> into this field. For each list |
||||
/// of values, <paramref name="other"/>'s values are append to the ones in this |
||||
/// field. |
||||
/// </summary> |
||||
public Builder MergeFrom(UnknownField other) { |
||||
varintList = AddAll(varintList, other.VarintList); |
||||
fixed32List = AddAll(fixed32List, other.Fixed32List); |
||||
fixed64List = AddAll(fixed64List, other.Fixed64List); |
||||
lengthDelimitedList = AddAll(lengthDelimitedList, other.LengthDelimitedList); |
||||
groupList = AddAll(groupList, other.GroupList); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a new list containing all of the given specified values from |
||||
/// both the <paramref name="current"/> and <paramref name="extras"/> lists. |
||||
/// If <paramref name="current" /> is null and <paramref name="extras"/> is empty, |
||||
/// null is returned. Otherwise, either a new list is created (if <paramref name="current" /> |
||||
/// is null) or the elements of <paramref name="extras"/> are added to <paramref name="current" />. |
||||
/// </summary> |
||||
private static List<T> AddAll<T>(List<T> current, IList<T> extras) |
||||
{ |
||||
if (extras.Count == 0) { |
||||
return current; |
||||
} |
||||
if (current == null) { |
||||
current = new List<T>(extras); |
||||
} else { |
||||
current.AddRange(extras); |
||||
} |
||||
return current; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Clears the contents of this builder. |
||||
/// </summary> |
||||
public Builder Clear() { |
||||
varintList = null; |
||||
fixed32List = null; |
||||
fixed64List = null; |
||||
lengthDelimitedList = null; |
||||
groupList = null; |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a varint value. |
||||
/// </summary> |
||||
[CLSCompliant(false)] |
||||
public Builder AddVarint(ulong value) { |
||||
varintList = Add(varintList, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a fixed32 value. |
||||
/// </summary> |
||||
[CLSCompliant(false)] |
||||
public Builder AddFixed32(uint value) { |
||||
fixed32List = Add(fixed32List, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a fixed64 value. |
||||
/// </summary> |
||||
[CLSCompliant(false)] |
||||
public Builder AddFixed64(ulong value) { |
||||
fixed64List = Add(fixed64List, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a length-delimited value. |
||||
/// </summary> |
||||
public Builder AddLengthDelimited(ByteString value) { |
||||
lengthDelimitedList = Add(lengthDelimitedList, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds an embedded group. |
||||
/// </summary> |
||||
/// <param name="value"></param> |
||||
/// <returns></returns> |
||||
public Builder AddGroup(UnknownFieldSet value) { |
||||
groupList = Add(groupList, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds <paramref name="value"/> to the <paramref name="list"/>, creating |
||||
/// a new list if <paramref name="list"/> is null. The list is returned - either |
||||
/// the original reference or the new list. |
||||
/// </summary> |
||||
private static List<T> Add<T>(List<T> list, T value) { |
||||
if (list == null) { |
||||
list = new List<T>(); |
||||
} |
||||
list.Add(value); |
||||
return list; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a read-only version of the given IList, and clears |
||||
/// the field used for <paramref name="list"/>. If the value |
||||
/// is null, an empty list is produced using Lists.Empty. |
||||
/// </summary> |
||||
/// <returns></returns> |
||||
private static ReadOnlyCollection<T> MakeReadOnly<T>(ref List<T> list) { |
||||
ReadOnlyCollection<T> ret = list == null ? Lists<T>.Empty : new ReadOnlyCollection<T>(list); |
||||
list = null; |
||||
return ret; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
#region Copyright notice and license |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2008 Google Inc. All rights reserved. |
||||
// http://github.com/jskeet/dotnet-protobufs/ |
||||
// Original C++/Java/Python code: |
||||
// http://code.google.com/p/protobuf/ |
||||
// |
||||
// Redistribution and use in source and binary forms, with or without |
||||
// modification, are permitted provided that the following conditions are |
||||
// met: |
||||
// |
||||
// * Redistributions of source code must retain the above copyright |
||||
// notice, this list of conditions and the following disclaimer. |
||||
// * Redistributions in binary form must reproduce the above |
||||
// copyright notice, this list of conditions and the following disclaimer |
||||
// in the documentation and/or other materials provided with the |
||||
// distribution. |
||||
// * Neither the name of Google Inc. nor the names of its |
||||
// contributors may be used to endorse or promote products derived from |
||||
// this software without specific prior written permission. |
||||
// |
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
#endregion |
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Collections.ObjectModel; |
||||
using Google.ProtocolBuffers.Collections; |
||||
|
||||
namespace Google.ProtocolBuffers { |
||||
/// <summary> |
||||
/// Represents a single field in an UnknownFieldSet. |
||||
/// |
||||
/// An UnknownField consists of five lists of values. The lists correspond |
||||
/// to the five "wire types" used in the protocol buffer binary format. |
||||
/// The wire type of each field can be determined from the encoded form alone, |
||||
/// without knowing the field's declared type. So, we are able to parse |
||||
/// unknown values at least this far and separate them. Normally, only one |
||||
/// of the five lists will contain any values, since it is impossible to |
||||
/// define a valid message type that declares two different types for the |
||||
/// same field number. However, the code is designed to allow for the case |
||||
/// where the same unknown field number is encountered using multiple different |
||||
/// wire types. |
||||
/// |
||||
/// UnknownField is an immutable class. To construct one, you must use an |
||||
/// UnknownField.Builder. |
||||
/// </summary> |
||||
public sealed class UnknownField { |
||||
|
||||
private static readonly UnknownField defaultInstance = CreateBuilder().Build(); |
||||
private readonly ReadOnlyCollection<ulong> varintList; |
||||
private readonly ReadOnlyCollection<uint> fixed32List; |
||||
private readonly ReadOnlyCollection<ulong> fixed64List; |
||||
private readonly ReadOnlyCollection<ByteString> lengthDelimitedList; |
||||
private readonly ReadOnlyCollection<UnknownFieldSet> groupList; |
||||
|
||||
private UnknownField(ReadOnlyCollection<ulong> varintList, |
||||
ReadOnlyCollection<uint> fixed32List, |
||||
ReadOnlyCollection<ulong> fixed64List, |
||||
ReadOnlyCollection<ByteString> lengthDelimitedList, |
||||
ReadOnlyCollection<UnknownFieldSet> groupList) { |
||||
this.varintList = varintList; |
||||
this.fixed32List = fixed32List; |
||||
this.fixed64List = fixed64List; |
||||
this.lengthDelimitedList = lengthDelimitedList; |
||||
this.groupList = groupList; |
||||
} |
||||
|
||||
public static UnknownField DefaultInstance { |
||||
get { return defaultInstance; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of varint values for this field. |
||||
/// </summary> |
||||
public IList<ulong> VarintList { |
||||
get { return varintList; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of fixed32 values for this field. |
||||
/// </summary> |
||||
public IList<uint> Fixed32List { |
||||
get { return fixed32List; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of fixed64 values for this field. |
||||
/// </summary> |
||||
public IList<ulong> Fixed64List { |
||||
get { return fixed64List; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of length-delimited values for this field. |
||||
/// </summary> |
||||
public IList<ByteString> LengthDelimitedList { |
||||
get { return lengthDelimitedList; } |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The list of embedded group values for this field. These |
||||
/// are represented using UnknownFieldSets rather than Messages |
||||
/// since the group's type is presumably unknown. |
||||
/// </summary> |
||||
public IList<UnknownFieldSet> GroupList { |
||||
get { return groupList; } |
||||
} |
||||
|
||||
public override bool Equals(object other) { |
||||
if (ReferenceEquals(this, other)) { |
||||
return true; |
||||
} |
||||
UnknownField otherField = other as UnknownField; |
||||
return otherField != null |
||||
&& Lists.Equals(varintList, otherField.varintList) |
||||
&& Lists.Equals(fixed32List, otherField.fixed32List) |
||||
&& Lists.Equals(fixed64List, otherField.fixed64List) |
||||
&& Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList) |
||||
&& Lists.Equals(groupList, otherField.groupList); |
||||
} |
||||
|
||||
public override int GetHashCode() { |
||||
int hash = 43; |
||||
hash = hash * 47 + Lists.GetHashCode(varintList); |
||||
hash = hash * 47 + Lists.GetHashCode(fixed32List); |
||||
hash = hash * 47 + Lists.GetHashCode(fixed64List); |
||||
hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList); |
||||
hash = hash * 47 + Lists.GetHashCode(groupList); |
||||
return hash; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs a new Builder. |
||||
/// </summary> |
||||
public static Builder CreateBuilder() { |
||||
return new Builder(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Constructs a new Builder and initializes it to a copy of <paramref name="copyFrom"/>. |
||||
/// </summary> |
||||
public static Builder CreateBuilder(UnknownField copyFrom) { |
||||
return new Builder().MergeFrom(copyFrom); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Serializes the field, including the field number, and writes it to |
||||
/// <paramref name="output"/>. |
||||
/// </summary> |
||||
public void WriteTo(int fieldNumber, CodedOutputStream output) { |
||||
foreach (ulong value in varintList) { |
||||
output.WriteUInt64(fieldNumber, value); |
||||
} |
||||
foreach (uint value in fixed32List) { |
||||
output.WriteFixed32(fieldNumber, value); |
||||
} |
||||
foreach (ulong value in fixed64List) { |
||||
output.WriteFixed64(fieldNumber, value); |
||||
} |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
output.WriteBytes(fieldNumber, value); |
||||
} |
||||
foreach (UnknownFieldSet value in groupList) { |
||||
#pragma warning disable 0612 |
||||
output.WriteUnknownGroup(fieldNumber, value); |
||||
#pragma warning restore 0612 |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Computes the number of bytes required to encode this field, including field |
||||
/// number. |
||||
/// </summary> |
||||
public int GetSerializedSize(int fieldNumber) { |
||||
int result = 0; |
||||
foreach (ulong value in varintList) { |
||||
result += CodedOutputStream.ComputeUInt64Size(fieldNumber, value); |
||||
} |
||||
foreach (uint value in fixed32List) { |
||||
result += CodedOutputStream.ComputeFixed32Size(fieldNumber, value); |
||||
} |
||||
foreach (ulong value in fixed64List) { |
||||
result += CodedOutputStream.ComputeFixed64Size(fieldNumber, value); |
||||
} |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
result += CodedOutputStream.ComputeBytesSize(fieldNumber, value); |
||||
} |
||||
foreach (UnknownFieldSet value in groupList) { |
||||
#pragma warning disable 0612 |
||||
result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value); |
||||
#pragma warning restore 0612 |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Serializes the length-delimited values of the field, including field |
||||
/// number, and writes them to <paramref name="output"/> using the MessageSet wire format. |
||||
/// </summary> |
||||
/// <param name="fieldNumber"></param> |
||||
/// <param name="output"></param> |
||||
public void WriteAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) { |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
output.WriteRawMessageSetExtension(fieldNumber, value); |
||||
} |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Get the number of bytes required to encode this field, incuding field number, |
||||
/// using the MessageSet wire format. |
||||
/// </summary> |
||||
public int GetSerializedSizeAsMessageSetExtension(int fieldNumber) { |
||||
int result = 0; |
||||
foreach (ByteString value in lengthDelimitedList) { |
||||
result += CodedOutputStream.ComputeRawMessageSetExtensionSize(fieldNumber, value); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Used to build instances of UnknownField. |
||||
/// </summary> |
||||
public sealed class Builder { |
||||
|
||||
private List<ulong> varintList; |
||||
private List<uint> fixed32List; |
||||
private List<ulong> fixed64List; |
||||
private List<ByteString> lengthDelimitedList; |
||||
private List<UnknownFieldSet> groupList; |
||||
|
||||
/// <summary> |
||||
/// Builds the field. After building, the builder is reset to an empty |
||||
/// state. (This is actually easier than making it unusable.) |
||||
/// </summary> |
||||
public UnknownField Build() { |
||||
return new UnknownField(MakeReadOnly(ref varintList), |
||||
MakeReadOnly(ref fixed32List), |
||||
MakeReadOnly(ref fixed64List), |
||||
MakeReadOnly(ref lengthDelimitedList), |
||||
MakeReadOnly(ref groupList)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Merge the values in <paramref name="other" /> into this field. For each list |
||||
/// of values, <paramref name="other"/>'s values are append to the ones in this |
||||
/// field. |
||||
/// </summary> |
||||
public Builder MergeFrom(UnknownField other) { |
||||
varintList = AddAll(varintList, other.VarintList); |
||||
fixed32List = AddAll(fixed32List, other.Fixed32List); |
||||
fixed64List = AddAll(fixed64List, other.Fixed64List); |
||||
lengthDelimitedList = AddAll(lengthDelimitedList, other.LengthDelimitedList); |
||||
groupList = AddAll(groupList, other.GroupList); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a new list containing all of the given specified values from |
||||
/// both the <paramref name="current"/> and <paramref name="extras"/> lists. |
||||
/// If <paramref name="current" /> is null and <paramref name="extras"/> is empty, |
||||
/// null is returned. Otherwise, either a new list is created (if <paramref name="current" /> |
||||
/// is null) or the elements of <paramref name="extras"/> are added to <paramref name="current" />. |
||||
/// </summary> |
||||
private static List<T> AddAll<T>(List<T> current, IList<T> extras) |
||||
{ |
||||
if (extras.Count == 0) { |
||||
return current; |
||||
} |
||||
if (current == null) { |
||||
current = new List<T>(extras); |
||||
} else { |
||||
current.AddRange(extras); |
||||
} |
||||
return current; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Clears the contents of this builder. |
||||
/// </summary> |
||||
public Builder Clear() { |
||||
varintList = null; |
||||
fixed32List = null; |
||||
fixed64List = null; |
||||
lengthDelimitedList = null; |
||||
groupList = null; |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a varint value. |
||||
/// </summary> |
||||
[CLSCompliant(false)] |
||||
public Builder AddVarint(ulong value) { |
||||
varintList = Add(varintList, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a fixed32 value. |
||||
/// </summary> |
||||
[CLSCompliant(false)] |
||||
public Builder AddFixed32(uint value) { |
||||
fixed32List = Add(fixed32List, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a fixed64 value. |
||||
/// </summary> |
||||
[CLSCompliant(false)] |
||||
public Builder AddFixed64(ulong value) { |
||||
fixed64List = Add(fixed64List, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds a length-delimited value. |
||||
/// </summary> |
||||
public Builder AddLengthDelimited(ByteString value) { |
||||
lengthDelimitedList = Add(lengthDelimitedList, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds an embedded group. |
||||
/// </summary> |
||||
/// <param name="value"></param> |
||||
/// <returns></returns> |
||||
public Builder AddGroup(UnknownFieldSet value) { |
||||
groupList = Add(groupList, value); |
||||
return this; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Adds <paramref name="value"/> to the <paramref name="list"/>, creating |
||||
/// a new list if <paramref name="list"/> is null. The list is returned - either |
||||
/// the original reference or the new list. |
||||
/// </summary> |
||||
private static List<T> Add<T>(List<T> list, T value) { |
||||
if (list == null) { |
||||
list = new List<T>(); |
||||
} |
||||
list.Add(value); |
||||
return list; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Returns a read-only version of the given IList, and clears |
||||
/// the field used for <paramref name="list"/>. If the value |
||||
/// is null, an empty list is produced using Lists.Empty. |
||||
/// </summary> |
||||
/// <returns></returns> |
||||
private static ReadOnlyCollection<T> MakeReadOnly<T>(ref List<T> list) { |
||||
ReadOnlyCollection<T> ret = list == null ? Lists<T>.Empty : new ReadOnlyCollection<T>(list); |
||||
list = null; |
||||
return ret; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,116 +1,116 @@ |
||||
optional_int32: 101 |
||||
optional_int64: 102 |
||||
optional_uint32: 103 |
||||
optional_uint64: 104 |
||||
optional_sint32: 105 |
||||
optional_sint64: 106 |
||||
optional_fixed32: 107 |
||||
optional_fixed64: 108 |
||||
optional_sfixed32: 109 |
||||
optional_sfixed64: 110 |
||||
optional_float: 111 |
||||
optional_double: 112 |
||||
optional_bool: true |
||||
optional_string: "115" |
||||
optional_bytes: "116" |
||||
OptionalGroup { |
||||
a: 117 |
||||
} |
||||
optional_nested_message { |
||||
bb: 118 |
||||
} |
||||
optional_foreign_message { |
||||
c: 119 |
||||
} |
||||
optional_import_message { |
||||
d: 120 |
||||
} |
||||
optional_nested_enum: BAZ |
||||
optional_foreign_enum: FOREIGN_BAZ |
||||
optional_import_enum: IMPORT_BAZ |
||||
optional_string_piece: "124" |
||||
optional_cord: "125" |
||||
repeated_int32: 201 |
||||
repeated_int32: 301 |
||||
repeated_int64: 202 |
||||
repeated_int64: 302 |
||||
repeated_uint32: 203 |
||||
repeated_uint32: 303 |
||||
repeated_uint64: 204 |
||||
repeated_uint64: 304 |
||||
repeated_sint32: 205 |
||||
repeated_sint32: 305 |
||||
repeated_sint64: 206 |
||||
repeated_sint64: 306 |
||||
repeated_fixed32: 207 |
||||
repeated_fixed32: 307 |
||||
repeated_fixed64: 208 |
||||
repeated_fixed64: 308 |
||||
repeated_sfixed32: 209 |
||||
repeated_sfixed32: 309 |
||||
repeated_sfixed64: 210 |
||||
repeated_sfixed64: 310 |
||||
repeated_float: 211 |
||||
repeated_float: 311 |
||||
repeated_double: 212 |
||||
repeated_double: 312 |
||||
repeated_bool: true |
||||
repeated_bool: false |
||||
repeated_string: "215" |
||||
repeated_string: "315" |
||||
repeated_bytes: "216" |
||||
repeated_bytes: "316" |
||||
RepeatedGroup { |
||||
a: 217 |
||||
} |
||||
RepeatedGroup { |
||||
a: 317 |
||||
} |
||||
repeated_nested_message { |
||||
bb: 218 |
||||
} |
||||
repeated_nested_message { |
||||
bb: 318 |
||||
} |
||||
repeated_foreign_message { |
||||
c: 219 |
||||
} |
||||
repeated_foreign_message { |
||||
c: 319 |
||||
} |
||||
repeated_import_message { |
||||
d: 220 |
||||
} |
||||
repeated_import_message { |
||||
d: 320 |
||||
} |
||||
repeated_nested_enum: BAR |
||||
repeated_nested_enum: BAZ |
||||
repeated_foreign_enum: FOREIGN_BAR |
||||
repeated_foreign_enum: FOREIGN_BAZ |
||||
repeated_import_enum: IMPORT_BAR |
||||
repeated_import_enum: IMPORT_BAZ |
||||
repeated_string_piece: "224" |
||||
repeated_string_piece: "324" |
||||
repeated_cord: "225" |
||||
repeated_cord: "325" |
||||
default_int32: 401 |
||||
default_int64: 402 |
||||
default_uint32: 403 |
||||
default_uint64: 404 |
||||
default_sint32: 405 |
||||
default_sint64: 406 |
||||
default_fixed32: 407 |
||||
default_fixed64: 408 |
||||
default_sfixed32: 409 |
||||
default_sfixed64: 410 |
||||
default_float: 411 |
||||
default_double: 412 |
||||
default_bool: false |
||||
default_string: "415" |
||||
default_bytes: "416" |
||||
default_nested_enum: FOO |
||||
default_foreign_enum: FOREIGN_FOO |
||||
default_import_enum: IMPORT_FOO |
||||
default_string_piece: "424" |
||||
default_cord: "425" |
||||
optional_int32: 101 |
||||
optional_int64: 102 |
||||
optional_uint32: 103 |
||||
optional_uint64: 104 |
||||
optional_sint32: 105 |
||||
optional_sint64: 106 |
||||
optional_fixed32: 107 |
||||
optional_fixed64: 108 |
||||
optional_sfixed32: 109 |
||||
optional_sfixed64: 110 |
||||
optional_float: 111 |
||||
optional_double: 112 |
||||
optional_bool: true |
||||
optional_string: "115" |
||||
optional_bytes: "116" |
||||
OptionalGroup { |
||||
a: 117 |
||||
} |
||||
optional_nested_message { |
||||
bb: 118 |
||||
} |
||||
optional_foreign_message { |
||||
c: 119 |
||||
} |
||||
optional_import_message { |
||||
d: 120 |
||||
} |
||||
optional_nested_enum: BAZ |
||||
optional_foreign_enum: FOREIGN_BAZ |
||||
optional_import_enum: IMPORT_BAZ |
||||
optional_string_piece: "124" |
||||
optional_cord: "125" |
||||
repeated_int32: 201 |
||||
repeated_int32: 301 |
||||
repeated_int64: 202 |
||||
repeated_int64: 302 |
||||
repeated_uint32: 203 |
||||
repeated_uint32: 303 |
||||
repeated_uint64: 204 |
||||
repeated_uint64: 304 |
||||
repeated_sint32: 205 |
||||
repeated_sint32: 305 |
||||
repeated_sint64: 206 |
||||
repeated_sint64: 306 |
||||
repeated_fixed32: 207 |
||||
repeated_fixed32: 307 |
||||
repeated_fixed64: 208 |
||||
repeated_fixed64: 308 |
||||
repeated_sfixed32: 209 |
||||
repeated_sfixed32: 309 |
||||
repeated_sfixed64: 210 |
||||
repeated_sfixed64: 310 |
||||
repeated_float: 211 |
||||
repeated_float: 311 |
||||
repeated_double: 212 |
||||
repeated_double: 312 |
||||
repeated_bool: true |
||||
repeated_bool: false |
||||
repeated_string: "215" |
||||
repeated_string: "315" |
||||
repeated_bytes: "216" |
||||
repeated_bytes: "316" |
||||
RepeatedGroup { |
||||
a: 217 |
||||
} |
||||
RepeatedGroup { |
||||
a: 317 |
||||
} |
||||
repeated_nested_message { |
||||
bb: 218 |
||||
} |
||||
repeated_nested_message { |
||||
bb: 318 |
||||
} |
||||
repeated_foreign_message { |
||||
c: 219 |
||||
} |
||||
repeated_foreign_message { |
||||
c: 319 |
||||
} |
||||
repeated_import_message { |
||||
d: 220 |
||||
} |
||||
repeated_import_message { |
||||
d: 320 |
||||
} |
||||
repeated_nested_enum: BAR |
||||
repeated_nested_enum: BAZ |
||||
repeated_foreign_enum: FOREIGN_BAR |
||||
repeated_foreign_enum: FOREIGN_BAZ |
||||
repeated_import_enum: IMPORT_BAR |
||||
repeated_import_enum: IMPORT_BAZ |
||||
repeated_string_piece: "224" |
||||
repeated_string_piece: "324" |
||||
repeated_cord: "225" |
||||
repeated_cord: "325" |
||||
default_int32: 401 |
||||
default_int64: 402 |
||||
default_uint32: 403 |
||||
default_uint64: 404 |
||||
default_sint32: 405 |
||||
default_sint64: 406 |
||||
default_fixed32: 407 |
||||
default_fixed64: 408 |
||||
default_sfixed32: 409 |
||||
default_sfixed64: 410 |
||||
default_float: 411 |
||||
default_double: 412 |
||||
default_bool: false |
||||
default_string: "415" |
||||
default_bytes: "416" |
||||
default_nested_enum: FOO |
||||
default_foreign_enum: FOREIGN_FOO |
||||
default_import_enum: IMPORT_FOO |
||||
default_string_piece: "424" |
||||
default_cord: "425" |
||||
|
@ -1,116 +1,116 @@ |
||||
[protobuf_unittest.optional_int32_extension]: 101 |
||||
[protobuf_unittest.optional_int64_extension]: 102 |
||||
[protobuf_unittest.optional_uint32_extension]: 103 |
||||
[protobuf_unittest.optional_uint64_extension]: 104 |
||||
[protobuf_unittest.optional_sint32_extension]: 105 |
||||
[protobuf_unittest.optional_sint64_extension]: 106 |
||||
[protobuf_unittest.optional_fixed32_extension]: 107 |
||||
[protobuf_unittest.optional_fixed64_extension]: 108 |
||||
[protobuf_unittest.optional_sfixed32_extension]: 109 |
||||
[protobuf_unittest.optional_sfixed64_extension]: 110 |
||||
[protobuf_unittest.optional_float_extension]: 111 |
||||
[protobuf_unittest.optional_double_extension]: 112 |
||||
[protobuf_unittest.optional_bool_extension]: true |
||||
[protobuf_unittest.optional_string_extension]: "115" |
||||
[protobuf_unittest.optional_bytes_extension]: "116" |
||||
[protobuf_unittest.optionalgroup_extension] { |
||||
a: 117 |
||||
} |
||||
[protobuf_unittest.optional_nested_message_extension] { |
||||
bb: 118 |
||||
} |
||||
[protobuf_unittest.optional_foreign_message_extension] { |
||||
c: 119 |
||||
} |
||||
[protobuf_unittest.optional_import_message_extension] { |
||||
d: 120 |
||||
} |
||||
[protobuf_unittest.optional_nested_enum_extension]: BAZ |
||||
[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ |
||||
[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ |
||||
[protobuf_unittest.optional_string_piece_extension]: "124" |
||||
[protobuf_unittest.optional_cord_extension]: "125" |
||||
[protobuf_unittest.repeated_int32_extension]: 201 |
||||
[protobuf_unittest.repeated_int32_extension]: 301 |
||||
[protobuf_unittest.repeated_int64_extension]: 202 |
||||
[protobuf_unittest.repeated_int64_extension]: 302 |
||||
[protobuf_unittest.repeated_uint32_extension]: 203 |
||||
[protobuf_unittest.repeated_uint32_extension]: 303 |
||||
[protobuf_unittest.repeated_uint64_extension]: 204 |
||||
[protobuf_unittest.repeated_uint64_extension]: 304 |
||||
[protobuf_unittest.repeated_sint32_extension]: 205 |
||||
[protobuf_unittest.repeated_sint32_extension]: 305 |
||||
[protobuf_unittest.repeated_sint64_extension]: 206 |
||||
[protobuf_unittest.repeated_sint64_extension]: 306 |
||||
[protobuf_unittest.repeated_fixed32_extension]: 207 |
||||
[protobuf_unittest.repeated_fixed32_extension]: 307 |
||||
[protobuf_unittest.repeated_fixed64_extension]: 208 |
||||
[protobuf_unittest.repeated_fixed64_extension]: 308 |
||||
[protobuf_unittest.repeated_sfixed32_extension]: 209 |
||||
[protobuf_unittest.repeated_sfixed32_extension]: 309 |
||||
[protobuf_unittest.repeated_sfixed64_extension]: 210 |
||||
[protobuf_unittest.repeated_sfixed64_extension]: 310 |
||||
[protobuf_unittest.repeated_float_extension]: 211 |
||||
[protobuf_unittest.repeated_float_extension]: 311 |
||||
[protobuf_unittest.repeated_double_extension]: 212 |
||||
[protobuf_unittest.repeated_double_extension]: 312 |
||||
[protobuf_unittest.repeated_bool_extension]: true |
||||
[protobuf_unittest.repeated_bool_extension]: false |
||||
[protobuf_unittest.repeated_string_extension]: "215" |
||||
[protobuf_unittest.repeated_string_extension]: "315" |
||||
[protobuf_unittest.repeated_bytes_extension]: "216" |
||||
[protobuf_unittest.repeated_bytes_extension]: "316" |
||||
[protobuf_unittest.repeatedgroup_extension] { |
||||
a: 217 |
||||
} |
||||
[protobuf_unittest.repeatedgroup_extension] { |
||||
a: 317 |
||||
} |
||||
[protobuf_unittest.repeated_nested_message_extension] { |
||||
bb: 218 |
||||
} |
||||
[protobuf_unittest.repeated_nested_message_extension] { |
||||
bb: 318 |
||||
} |
||||
[protobuf_unittest.repeated_foreign_message_extension] { |
||||
c: 219 |
||||
} |
||||
[protobuf_unittest.repeated_foreign_message_extension] { |
||||
c: 319 |
||||
} |
||||
[protobuf_unittest.repeated_import_message_extension] { |
||||
d: 220 |
||||
} |
||||
[protobuf_unittest.repeated_import_message_extension] { |
||||
d: 320 |
||||
} |
||||
[protobuf_unittest.repeated_nested_enum_extension]: BAR |
||||
[protobuf_unittest.repeated_nested_enum_extension]: BAZ |
||||
[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR |
||||
[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ |
||||
[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR |
||||
[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ |
||||
[protobuf_unittest.repeated_string_piece_extension]: "224" |
||||
[protobuf_unittest.repeated_string_piece_extension]: "324" |
||||
[protobuf_unittest.repeated_cord_extension]: "225" |
||||
[protobuf_unittest.repeated_cord_extension]: "325" |
||||
[protobuf_unittest.default_int32_extension]: 401 |
||||
[protobuf_unittest.default_int64_extension]: 402 |
||||
[protobuf_unittest.default_uint32_extension]: 403 |
||||
[protobuf_unittest.default_uint64_extension]: 404 |
||||
[protobuf_unittest.default_sint32_extension]: 405 |
||||
[protobuf_unittest.default_sint64_extension]: 406 |
||||
[protobuf_unittest.default_fixed32_extension]: 407 |
||||
[protobuf_unittest.default_fixed64_extension]: 408 |
||||
[protobuf_unittest.default_sfixed32_extension]: 409 |
||||
[protobuf_unittest.default_sfixed64_extension]: 410 |
||||
[protobuf_unittest.default_float_extension]: 411 |
||||
[protobuf_unittest.default_double_extension]: 412 |
||||
[protobuf_unittest.default_bool_extension]: false |
||||
[protobuf_unittest.default_string_extension]: "415" |
||||
[protobuf_unittest.default_bytes_extension]: "416" |
||||
[protobuf_unittest.default_nested_enum_extension]: FOO |
||||
[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO |
||||
[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO |
||||
[protobuf_unittest.default_string_piece_extension]: "424" |
||||
[protobuf_unittest.default_cord_extension]: "425" |
||||
[protobuf_unittest.optional_int32_extension]: 101 |
||||
[protobuf_unittest.optional_int64_extension]: 102 |
||||
[protobuf_unittest.optional_uint32_extension]: 103 |
||||
[protobuf_unittest.optional_uint64_extension]: 104 |
||||
[protobuf_unittest.optional_sint32_extension]: 105 |
||||
[protobuf_unittest.optional_sint64_extension]: 106 |
||||
[protobuf_unittest.optional_fixed32_extension]: 107 |
||||
[protobuf_unittest.optional_fixed64_extension]: 108 |
||||
[protobuf_unittest.optional_sfixed32_extension]: 109 |
||||
[protobuf_unittest.optional_sfixed64_extension]: 110 |
||||
[protobuf_unittest.optional_float_extension]: 111 |
||||
[protobuf_unittest.optional_double_extension]: 112 |
||||
[protobuf_unittest.optional_bool_extension]: true |
||||
[protobuf_unittest.optional_string_extension]: "115" |
||||
[protobuf_unittest.optional_bytes_extension]: "116" |
||||
[protobuf_unittest.optionalgroup_extension] { |
||||
a: 117 |
||||
} |
||||
[protobuf_unittest.optional_nested_message_extension] { |
||||
bb: 118 |
||||
} |
||||
[protobuf_unittest.optional_foreign_message_extension] { |
||||
c: 119 |
||||
} |
||||
[protobuf_unittest.optional_import_message_extension] { |
||||
d: 120 |
||||
} |
||||
[protobuf_unittest.optional_nested_enum_extension]: BAZ |
||||
[protobuf_unittest.optional_foreign_enum_extension]: FOREIGN_BAZ |
||||
[protobuf_unittest.optional_import_enum_extension]: IMPORT_BAZ |
||||
[protobuf_unittest.optional_string_piece_extension]: "124" |
||||
[protobuf_unittest.optional_cord_extension]: "125" |
||||
[protobuf_unittest.repeated_int32_extension]: 201 |
||||
[protobuf_unittest.repeated_int32_extension]: 301 |
||||
[protobuf_unittest.repeated_int64_extension]: 202 |
||||
[protobuf_unittest.repeated_int64_extension]: 302 |
||||
[protobuf_unittest.repeated_uint32_extension]: 203 |
||||
[protobuf_unittest.repeated_uint32_extension]: 303 |
||||
[protobuf_unittest.repeated_uint64_extension]: 204 |
||||
[protobuf_unittest.repeated_uint64_extension]: 304 |
||||
[protobuf_unittest.repeated_sint32_extension]: 205 |
||||
[protobuf_unittest.repeated_sint32_extension]: 305 |
||||
[protobuf_unittest.repeated_sint64_extension]: 206 |
||||
[protobuf_unittest.repeated_sint64_extension]: 306 |
||||
[protobuf_unittest.repeated_fixed32_extension]: 207 |
||||
[protobuf_unittest.repeated_fixed32_extension]: 307 |
||||
[protobuf_unittest.repeated_fixed64_extension]: 208 |
||||
[protobuf_unittest.repeated_fixed64_extension]: 308 |
||||
[protobuf_unittest.repeated_sfixed32_extension]: 209 |
||||
[protobuf_unittest.repeated_sfixed32_extension]: 309 |
||||
[protobuf_unittest.repeated_sfixed64_extension]: 210 |
||||
[protobuf_unittest.repeated_sfixed64_extension]: 310 |
||||
[protobuf_unittest.repeated_float_extension]: 211 |
||||
[protobuf_unittest.repeated_float_extension]: 311 |
||||
[protobuf_unittest.repeated_double_extension]: 212 |
||||
[protobuf_unittest.repeated_double_extension]: 312 |
||||
[protobuf_unittest.repeated_bool_extension]: true |
||||
[protobuf_unittest.repeated_bool_extension]: false |
||||
[protobuf_unittest.repeated_string_extension]: "215" |
||||
[protobuf_unittest.repeated_string_extension]: "315" |
||||
[protobuf_unittest.repeated_bytes_extension]: "216" |
||||
[protobuf_unittest.repeated_bytes_extension]: "316" |
||||
[protobuf_unittest.repeatedgroup_extension] { |
||||
a: 217 |
||||
} |
||||
[protobuf_unittest.repeatedgroup_extension] { |
||||
a: 317 |
||||
} |
||||
[protobuf_unittest.repeated_nested_message_extension] { |
||||
bb: 218 |
||||
} |
||||
[protobuf_unittest.repeated_nested_message_extension] { |
||||
bb: 318 |
||||
} |
||||
[protobuf_unittest.repeated_foreign_message_extension] { |
||||
c: 219 |
||||
} |
||||
[protobuf_unittest.repeated_foreign_message_extension] { |
||||
c: 319 |
||||
} |
||||
[protobuf_unittest.repeated_import_message_extension] { |
||||
d: 220 |
||||
} |
||||
[protobuf_unittest.repeated_import_message_extension] { |
||||
d: 320 |
||||
} |
||||
[protobuf_unittest.repeated_nested_enum_extension]: BAR |
||||
[protobuf_unittest.repeated_nested_enum_extension]: BAZ |
||||
[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAR |
||||
[protobuf_unittest.repeated_foreign_enum_extension]: FOREIGN_BAZ |
||||
[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAR |
||||
[protobuf_unittest.repeated_import_enum_extension]: IMPORT_BAZ |
||||
[protobuf_unittest.repeated_string_piece_extension]: "224" |
||||
[protobuf_unittest.repeated_string_piece_extension]: "324" |
||||
[protobuf_unittest.repeated_cord_extension]: "225" |
||||
[protobuf_unittest.repeated_cord_extension]: "325" |
||||
[protobuf_unittest.default_int32_extension]: 401 |
||||
[protobuf_unittest.default_int64_extension]: 402 |
||||
[protobuf_unittest.default_uint32_extension]: 403 |
||||
[protobuf_unittest.default_uint64_extension]: 404 |
||||
[protobuf_unittest.default_sint32_extension]: 405 |
||||
[protobuf_unittest.default_sint64_extension]: 406 |
||||
[protobuf_unittest.default_fixed32_extension]: 407 |
||||
[protobuf_unittest.default_fixed64_extension]: 408 |
||||
[protobuf_unittest.default_sfixed32_extension]: 409 |
||||
[protobuf_unittest.default_sfixed64_extension]: 410 |
||||
[protobuf_unittest.default_float_extension]: 411 |
||||
[protobuf_unittest.default_double_extension]: 412 |
||||
[protobuf_unittest.default_bool_extension]: false |
||||
[protobuf_unittest.default_string_extension]: "415" |
||||
[protobuf_unittest.default_bytes_extension]: "416" |
||||
[protobuf_unittest.default_nested_enum_extension]: FOO |
||||
[protobuf_unittest.default_foreign_enum_extension]: FOREIGN_FOO |
||||
[protobuf_unittest.default_import_enum_extension]: IMPORT_FOO |
||||
[protobuf_unittest.default_string_piece_extension]: "424" |
||||
[protobuf_unittest.default_cord_extension]: "425" |
||||
|
@ -1,16 +1,16 @@ |
||||
Current task list (not in order) |
||||
|
||||
- Remove multifile support |
||||
- Docs |
||||
- Clean up protogen code |
||||
- Avoid using reflection for messages which don't need it (is this |
||||
possible?) |
||||
- Bring service generation into line with Java |
||||
- Build protoc as a dll and use directly from protogen |
||||
- Check copyright is everywhere |
||||
- Work out how to unit test Silverlight code |
||||
- Reformat code |
||||
- Change generated format |
||||
- Add regions to copyright |
||||
- Build and publish binaries |
||||
- Work out why the Compact Framework 3.5 build fails under VS2010 |
||||
Current task list (not in order) |
||||
|
||||
- Remove multifile support |
||||
- Docs |
||||
- Clean up protogen code |
||||
- Avoid using reflection for messages which don't need it (is this |
||||
possible?) |
||||
- Bring service generation into line with Java |
||||
- Build protoc as a dll and use directly from protogen |
||||
- Check copyright is everywhere |
||||
- Work out how to unit test Silverlight code |
||||
- Reformat code |
||||
- Change generated format |
||||
- Add regions to copyright |
||||
- Build and publish binaries |
||||
- Work out why the Compact Framework 3.5 build fails under VS2010 |
||||
|
Loading…
Reference in new issue