aboutsummaryrefslogtreecommitdiff
path: root/src/ProtocolBuffers
diff options
context:
space:
mode:
authorcsharptest <roger@csharptest.net>2010-11-09 20:49:12 -0600
committercsharptest <roger@csharptest.net>2010-11-09 20:49:12 -0600
commit272cb8aee775de65e08b4ab17c485cd678d08266 (patch)
tree3489244ff5bd901592b535ea5ad9352096d1521f /src/ProtocolBuffers
parente49547735834485dd22842e1a82bc5ae4139b8a8 (diff)
downloadprotobuf-272cb8aee775de65e08b4ab17c485cd678d08266.tar.gz
protobuf-272cb8aee775de65e08b4ab17c485cd678d08266.tar.bz2
protobuf-272cb8aee775de65e08b4ab17c485cd678d08266.zip
Lite feature complete.
Diffstat (limited to 'src/ProtocolBuffers')
-rw-r--r--src/ProtocolBuffers/AbstractMessage.cs4
-rw-r--r--src/ProtocolBuffers/AbstractMessageLite.cs2
-rw-r--r--src/ProtocolBuffers/EnumLite.cs12
-rw-r--r--src/ProtocolBuffers/ExtendableMessageLite.cs28
-rw-r--r--src/ProtocolBuffers/ExtensionInfo.cs4
-rw-r--r--src/ProtocolBuffers/FieldSet.cs1
-rw-r--r--src/ProtocolBuffers/GeneratedExtensionBase.cs8
-rw-r--r--src/ProtocolBuffers/GeneratedExtensionLite.cs16
-rw-r--r--src/ProtocolBuffers/GeneratedMessageLite.cs80
-rw-r--r--src/ProtocolBuffers/IMessageLite.cs5
-rw-r--r--src/ProtocolBuffers/TextFormat.cs16
-rw-r--r--src/ProtocolBuffers/UninitializedMessageException.cs14
-rw-r--r--src/ProtocolBuffers/UnknownFieldSet.cs12
13 files changed, 176 insertions, 26 deletions
diff --git a/src/ProtocolBuffers/AbstractMessage.cs b/src/ProtocolBuffers/AbstractMessage.cs
index e2cf3827..203b71a4 100644
--- a/src/ProtocolBuffers/AbstractMessage.cs
+++ b/src/ProtocolBuffers/AbstractMessage.cs
@@ -101,6 +101,10 @@ namespace Google.ProtocolBuffers {
return TextFormat.PrintToString(this);
}
+ public sealed override void PrintTo(TextWriter writer) {
+ TextFormat.Print(this, writer);
+ }
+
/// <summary>
/// Serializes the message and writes it to the given output stream.
/// This does not flush or close the stream.
diff --git a/src/ProtocolBuffers/AbstractMessageLite.cs b/src/ProtocolBuffers/AbstractMessageLite.cs
index 96884753..ee75f3dd 100644
--- a/src/ProtocolBuffers/AbstractMessageLite.cs
+++ b/src/ProtocolBuffers/AbstractMessageLite.cs
@@ -63,6 +63,8 @@ namespace Google.ProtocolBuffers {
//public override int GetHashCode() {
//}
+ public abstract void PrintTo(TextWriter writer);
+
#region IMessageLite<TMessage,TBuilder> Members
/// <summary>
diff --git a/src/ProtocolBuffers/EnumLite.cs b/src/ProtocolBuffers/EnumLite.cs
index ab13c9ab..12497d8e 100644
--- a/src/ProtocolBuffers/EnumLite.cs
+++ b/src/ProtocolBuffers/EnumLite.cs
@@ -46,6 +46,7 @@ namespace Google.ProtocolBuffers {
///</summary>
public interface IEnumLite {
int Number { get; }
+ string Name { get; }
}
///<summary>
@@ -69,12 +70,15 @@ namespace Google.ProtocolBuffers {
where TEnum : struct, IComparable, IFormattable {
struct EnumValue : IEnumLite {
- readonly int value;
- public EnumValue(int value) {
+ readonly TEnum value;
+ public EnumValue(TEnum value) {
this.value = value;
}
int IEnumLite.Number {
- get { return value; }
+ get { return Convert.ToInt32(value); }
+ }
+ string IEnumLite.Name {
+ get { return value.ToString(); }
}
}
@@ -83,7 +87,7 @@ namespace Google.ProtocolBuffers {
public EnumLiteMap() {
items = new SortedList<int, IEnumLite>();
foreach (TEnum evalue in Enum.GetValues(typeof(TEnum)))
- items.Add(Convert.ToInt32(evalue), new EnumValue(Convert.ToInt32(evalue)));
+ items.Add(Convert.ToInt32(evalue), new EnumValue(evalue));
}
IEnumLite IEnumLiteMap.FindValueByNumber(int number) {
diff --git a/src/ProtocolBuffers/ExtendableMessageLite.cs b/src/ProtocolBuffers/ExtendableMessageLite.cs
index fc2ccb6c..aed8545d 100644
--- a/src/ProtocolBuffers/ExtendableMessageLite.cs
+++ b/src/ProtocolBuffers/ExtendableMessageLite.cs
@@ -33,7 +33,10 @@
#endregion
using System;
+using System.Collections;
using System.Collections.Generic;
+using Google.ProtocolBuffers.Collections;
+
namespace Google.ProtocolBuffers {
public abstract class ExtendableMessageLite<TMessage, TBuilder> : GeneratedMessageLite<TMessage, TBuilder>
where TMessage : GeneratedMessageLite<TMessage, TBuilder>
@@ -49,6 +52,31 @@ namespace Google.ProtocolBuffers {
get { return extensions; }
}
+ public override bool Equals(object obj) {
+ ExtendableMessageLite<TMessage, TBuilder> other = obj as ExtendableMessageLite<TMessage, TBuilder>;
+ return !ReferenceEquals(null, other) &&
+ Dictionaries.Equals(extensions.AllFields, other.extensions.AllFields);
+ }
+
+ public override int GetHashCode() {
+ return Dictionaries.GetHashCode(extensions.AllFields);
+ }
+
+ /// <summary>
+ /// writes the extensions to the text stream
+ /// </summary>
+ public override void PrintTo(System.IO.TextWriter writer) {
+ foreach (KeyValuePair<IFieldDescriptorLite, object> entry in extensions.AllFields) {
+ string fn = string.Format("[{0}]", entry.Key.FullName);
+ if (entry.Key.IsRepeated) {
+ foreach (object o in ((IEnumerable)entry.Value))
+ PrintField(fn, true, o, writer);
+ } else {
+ PrintField(fn, true, entry.Value, writer);
+ }
+ }
+ }
+
/// <summary>
/// Checks if a singular extension is present.
/// </summary>
diff --git a/src/ProtocolBuffers/ExtensionInfo.cs b/src/ProtocolBuffers/ExtensionInfo.cs
index 482f006a..5d99b8ff 100644
--- a/src/ProtocolBuffers/ExtensionInfo.cs
+++ b/src/ProtocolBuffers/ExtensionInfo.cs
@@ -48,12 +48,12 @@ namespace Google.ProtocolBuffers
/// A default instance of the extensions's type, if it has a message type,
/// or null otherwise.
/// </summary>
- public IMessage DefaultInstance { get; private set; }
+ public IMessageLite DefaultInstance { get; private set; }
internal ExtensionInfo(FieldDescriptor descriptor) : this(descriptor, null) {
}
- internal ExtensionInfo(FieldDescriptor descriptor, IMessage defaultInstance) {
+ internal ExtensionInfo(FieldDescriptor descriptor, IMessageLite defaultInstance) {
Descriptor = descriptor;
DefaultInstance = defaultInstance;
}
diff --git a/src/ProtocolBuffers/FieldSet.cs b/src/ProtocolBuffers/FieldSet.cs
index 838d0568..c3e3d740 100644
--- a/src/ProtocolBuffers/FieldSet.cs
+++ b/src/ProtocolBuffers/FieldSet.cs
@@ -47,6 +47,7 @@ namespace Google.ProtocolBuffers {
bool IsExtension { get; }
bool MessageSetWireFormat { get; } //field.ContainingType.Options.MessageSetWireFormat
int FieldNumber { get; }
+ string FullName { get; }
IEnumLiteMap EnumType { get; }
FieldType FieldType { get; }
MappedType MappedType { get; }
diff --git a/src/ProtocolBuffers/GeneratedExtensionBase.cs b/src/ProtocolBuffers/GeneratedExtensionBase.cs
index 36da58e6..aacc0655 100644
--- a/src/ProtocolBuffers/GeneratedExtensionBase.cs
+++ b/src/ProtocolBuffers/GeneratedExtensionBase.cs
@@ -66,7 +66,7 @@ namespace Google.ProtocolBuffers {
public abstract class GeneratedExtensionBase<TExtension> {
private readonly FieldDescriptor descriptor;
- private readonly IMessage messageDefaultInstance;
+ private readonly IMessageLite messageDefaultInstance;
protected GeneratedExtensionBase(FieldDescriptor descriptor, Type singularExtensionType) {
if (!descriptor.IsExtension) {
@@ -80,8 +80,8 @@ namespace Google.ProtocolBuffers {
if (defaultInstanceProperty == null) {
throw new ArgumentException("No public static DefaultInstance property for type " + typeof(TExtension).Name);
}
-#warning ToDo - Invalid cast, could be IMessageLite
- messageDefaultInstance = (IMessage)defaultInstanceProperty.GetValue(null, null);
+
+ messageDefaultInstance = (IMessageLite)defaultInstanceProperty.GetValue(null, null);
}
}
@@ -96,7 +96,7 @@ namespace Google.ProtocolBuffers {
/// <summary>
/// Returns the default message instance for extensions which are message types.
/// </summary>
- public IMessage MessageDefaultInstance {
+ public IMessageLite MessageDefaultInstance {
get { return messageDefaultInstance; }
}
diff --git a/src/ProtocolBuffers/GeneratedExtensionLite.cs b/src/ProtocolBuffers/GeneratedExtensionLite.cs
index 81d8d41b..33969f4b 100644
--- a/src/ProtocolBuffers/GeneratedExtensionLite.cs
+++ b/src/ProtocolBuffers/GeneratedExtensionLite.cs
@@ -48,6 +48,7 @@ namespace Google.ProtocolBuffers {
}
public class ExtensionDescriptorLite : IFieldDescriptorLite {
+ private readonly string fullName;
private readonly IEnumLiteMap enumTypeMap;
private readonly int number;
private readonly FieldType type;
@@ -56,7 +57,8 @@ namespace Google.ProtocolBuffers {
private readonly MappedType mapType;
private readonly object defaultValue;
- public ExtensionDescriptorLite(IEnumLiteMap enumTypeMap, int number, FieldType type, object defaultValue, bool isRepeated, bool isPacked) {
+ public ExtensionDescriptorLite(string fullName, IEnumLiteMap enumTypeMap, int number, FieldType type, object defaultValue, bool isRepeated, bool isPacked) {
+ this.fullName = fullName;
this.enumTypeMap = enumTypeMap;
this.number = number;
this.type = type;
@@ -66,6 +68,8 @@ namespace Google.ProtocolBuffers {
this.defaultValue = defaultValue;
}
+ public string FullName { get { return fullName; } }
+
public bool IsRepeated {
get { return isRepeated; }
}
@@ -116,9 +120,9 @@ namespace Google.ProtocolBuffers {
public class GeneratedRepeatExtensionLite<TContainingType, TExtensionType> : GeneratedExtensionLite<TContainingType, IList<TExtensionType>>
where TContainingType : IMessageLite {
- public GeneratedRepeatExtensionLite(TContainingType containingTypeDefaultInstance,
+ public GeneratedRepeatExtensionLite(string fullName, TContainingType containingTypeDefaultInstance,
IMessageLite messageDefaultInstance, IEnumLiteMap enumTypeMap, int number, FieldType type, bool isPacked) :
- base(containingTypeDefaultInstance, new List<TExtensionType>(), messageDefaultInstance, enumTypeMap, number, type, isPacked) {
+ base(fullName, containingTypeDefaultInstance, new List<TExtensionType>(), messageDefaultInstance, enumTypeMap, number, type, isPacked) {
}
public override object ToReflectionType(object value) {
@@ -167,6 +171,7 @@ namespace Google.ProtocolBuffers {
/** For use by generated code only. */
public GeneratedExtensionLite(
+ string fullName,
TContainingType containingTypeDefaultInstance,
TExtensionType defaultValue,
IMessageLite messageDefaultInstance,
@@ -174,13 +179,14 @@ namespace Google.ProtocolBuffers {
int number,
FieldType type)
: this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
- new ExtensionDescriptorLite(enumTypeMap, number, type, defaultValue,
+ new ExtensionDescriptorLite(fullName, enumTypeMap, number, type, defaultValue,
false /* isRepeated */, false /* isPacked */)) {
}
private static readonly IList<object> Empty = new object[0];
/** Repeating fields: For use by generated code only. */
protected GeneratedExtensionLite(
+ string fullName,
TContainingType containingTypeDefaultInstance,
TExtensionType defaultValue,
IMessageLite messageDefaultInstance,
@@ -189,7 +195,7 @@ namespace Google.ProtocolBuffers {
FieldType type,
bool isPacked)
: this(containingTypeDefaultInstance, defaultValue, messageDefaultInstance,
- new ExtensionDescriptorLite(enumTypeMap, number, type, Empty,
+ new ExtensionDescriptorLite(fullName, enumTypeMap, number, type, Empty,
true /* isRepeated */, isPacked)) {
}
diff --git a/src/ProtocolBuffers/GeneratedMessageLite.cs b/src/ProtocolBuffers/GeneratedMessageLite.cs
index fd1c6216..b2a009c4 100644
--- a/src/ProtocolBuffers/GeneratedMessageLite.cs
+++ b/src/ProtocolBuffers/GeneratedMessageLite.cs
@@ -35,6 +35,8 @@
using System;
using System.Collections.Generic;
using System.Collections;
+using System.Globalization;
+using Google.ProtocolBuffers.Descriptors;
namespace Google.ProtocolBuffers {
@@ -48,5 +50,83 @@ namespace Google.ProtocolBuffers {
where TBuilder : GeneratedBuilderLite<TMessage, TBuilder> {
protected abstract TMessage ThisMessage { get; }
+
+ public sealed override string ToString() {
+ using (System.IO.StringWriter wtr = new System.IO.StringWriter()) {
+ PrintTo(wtr);
+ return wtr.ToString();
+ }
+ }
+
+ /// <summary>
+ /// PrintTo() helper methods for Lite Runtime
+ /// </summary>
+ protected static void PrintField<T>(string name, IList<T> value, System.IO.TextWriter writer) {
+ foreach (T item in value)
+ PrintField(name, true, (object)item, writer);
+ }
+ /// <summary>
+ /// PrintTo() helper methods for Lite Runtime
+ /// </summary>
+ protected static void PrintField(string name, bool hasValue, object value, System.IO.TextWriter writer) {
+ if (!hasValue) return;
+ if (value is IMessageLite) {
+ writer.WriteLine("{0} {{", name);
+ ((IMessageLite)value).PrintTo(writer);
+ writer.WriteLine("}");
+ } else if (value is ByteString || value is String) {
+ writer.Write("{0}: \"", name);
+ if(value is String)
+ EscapeBytes( System.Text.Encoding.UTF8.GetBytes((string)value), writer);
+ else
+ EscapeBytes(((ByteString)value), writer);
+ writer.WriteLine("\"");
+ } else if (value is bool) {
+ writer.WriteLine("{0}: {1}", name, (bool)value ? "true" : "false");
+ } else if (value is IEnumLite) {
+ writer.WriteLine("{0}: {1}", name, ((IEnumLite)value).Name);
+ }
+ else {
+ writer.WriteLine("{0}: {1}", name, ((IConvertible)value).ToString(CultureInfo.InvariantCulture));
+ }
+ }
+
+ /// <summary>
+ /// COPIED from TextFormat
+ /// Escapes bytes in the format used in protocol buffer text format, which
+ /// is the same as the format used for C string literals. All bytes
+ /// that are not printable 7-bit ASCII characters are escaped, as well as
+ /// backslash, single-quote, and double-quote characters. Characters for
+ /// which no defined short-hand escape sequence is defined will be escaped
+ /// using 3-digit octal sequences.
+ /// The returned value is guaranteed to be entirely ASCII.
+ /// </summary>
+ private static void EscapeBytes(IEnumerable<byte> input, System.IO.TextWriter writer) {
+ foreach (byte b in input) {
+ switch (b) {
+ // C# does not use \a or \v
+ case 0x07: writer.Write("\\a"); break;
+ case (byte)'\b': writer.Write("\\b"); break;
+ case (byte)'\f': writer.Write("\\f"); break;
+ case (byte)'\n': writer.Write("\\n"); break;
+ case (byte)'\r': writer.Write("\\r"); break;
+ case (byte)'\t': writer.Write("\\t"); break;
+ case 0x0b: writer.Write("\\v"); break;
+ case (byte)'\\': writer.Write("\\\\"); break;
+ case (byte)'\'': writer.Write("\\\'"); break;
+ case (byte)'"': writer.Write("\\\""); break;
+ default:
+ if (b >= 0x20 && b < 128) {
+ writer.Write((char)b);
+ } else {
+ writer.Write('\\');
+ writer.Write((char)('0' + ((b >> 6) & 3)));
+ writer.Write((char)('0' + ((b >> 3) & 7)));
+ writer.Write((char)('0' + (b & 7)));
+ }
+ break;
+ }
+ }
+ }
}
}
diff --git a/src/ProtocolBuffers/IMessageLite.cs b/src/ProtocolBuffers/IMessageLite.cs
index cb64e021..48660882 100644
--- a/src/ProtocolBuffers/IMessageLite.cs
+++ b/src/ProtocolBuffers/IMessageLite.cs
@@ -104,6 +104,11 @@ namespace Google.ProtocolBuffers {
string ToString();
/// <summary>
+ /// Converts the message to a string.
+ /// </summary>
+ void PrintTo(TextWriter writer);
+
+ /// <summary>
/// Serializes the message to a ByteString. This is a trivial wrapper
/// around WriteTo(CodedOutputStream).
/// </summary>
diff --git a/src/ProtocolBuffers/TextFormat.cs b/src/ProtocolBuffers/TextFormat.cs
index 81033087..81b3447c 100644
--- a/src/ProtocolBuffers/TextFormat.cs
+++ b/src/ProtocolBuffers/TextFormat.cs
@@ -170,17 +170,19 @@ namespace Google.ProtocolBuffers {
}
case FieldType.Enum: {
- generator.Print(((EnumValueDescriptor) value).Name);
+ if (value is IEnumLite && !(value is EnumValueDescriptor)) {
+ throw new NotSupportedException("Lite enumerations are not supported.");
+ }
+ generator.Print(((EnumValueDescriptor)value).Name);
break;
}
case FieldType.Message:
case FieldType.Group:
- if (value is IMessage) {
- Print((IMessage)value, generator);
- } else {
-#warning ToDo - What do we print for IMessageLite?
+ if (value is IMessageLite && !(value is IMessage)) {
+ throw new NotSupportedException("Lite messages are not supported.");
}
+ Print((IMessage)value, generator);
break;
}
}
@@ -580,7 +582,9 @@ namespace Google.ProtocolBuffers {
if (extension == null) {
subBuilder = builder.CreateBuilderForField(field);
} else {
- subBuilder = extension.DefaultInstance.WeakCreateBuilderForType();
+ subBuilder = extension.DefaultInstance.WeakCreateBuilderForType() as IBuilder;
+ if (subBuilder == null)
+ throw new NotSupportedException("Lite messages are not supported.");
}
while (!tokenizer.TryConsume(endToken)) {
diff --git a/src/ProtocolBuffers/UninitializedMessageException.cs b/src/ProtocolBuffers/UninitializedMessageException.cs
index c5bcd822..d7f58197 100644
--- a/src/ProtocolBuffers/UninitializedMessageException.cs
+++ b/src/ProtocolBuffers/UninitializedMessageException.cs
@@ -124,16 +124,24 @@ namespace Google.ProtocolBuffers {
foreach (KeyValuePair<FieldDescriptor, object> entry in message.AllFields) {
FieldDescriptor field = entry.Key;
object value = entry.Value;
-#warning ToDo - bad assumption, could be IMessageLite
+
if (field.MappedType == MappedType.Message) {
if (field.IsRepeated) {
int i = 0;
foreach (object element in (IEnumerable) value) {
- FindMissingFields((IMessage) element, SubMessagePrefix(prefix, field, i++), results);
+ if (element is IMessage) {
+ FindMissingFields((IMessage)element, SubMessagePrefix(prefix, field, i++), results);
+ } else {
+ results.Add(prefix + field.Name);
+ }
}
} else {
if (message.HasField(field)) {
- FindMissingFields((IMessage) value, SubMessagePrefix(prefix, field, -1), results);
+ if (value is IMessage) {
+ FindMissingFields((IMessage)value, SubMessagePrefix(prefix, field, -1), results);
+ } else {
+ results.Add(prefix + field.Name);
+ }
}
}
}
diff --git a/src/ProtocolBuffers/UnknownFieldSet.cs b/src/ProtocolBuffers/UnknownFieldSet.cs
index 515637cc..594ae8bd 100644
--- a/src/ProtocolBuffers/UnknownFieldSet.cs
+++ b/src/ProtocolBuffers/UnknownFieldSet.cs
@@ -139,6 +139,14 @@ namespace Google.ProtocolBuffers {
}
/// <summary>
+ /// Converts the set to a string in protocol buffer text format. This
+ /// is just a trivial wrapper around TextFormat.PrintToString.
+ /// </summary>
+ public void PrintTo(TextWriter writer) {
+ TextFormat.Print(this, writer);
+ }
+
+ /// <summary>
/// Serializes the message to a ByteString and returns it. This is
/// just a trivial wrapper around WriteTo(CodedOutputStream).
/// </summary>
@@ -533,7 +541,7 @@ namespace Google.ProtocolBuffers {
int fieldNumber = WireFormat.GetTagFieldNumber(tag);
FieldDescriptor field;
- IMessage defaultFieldInstance = null;
+ IMessageLite defaultFieldInstance = null;
if (type.IsExtensionNumber(fieldNumber)) {
ExtensionInfo extension = extensionRegistry[type, fieldNumber];
@@ -644,7 +652,7 @@ namespace Google.ProtocolBuffers {
int typeId = 0;
ByteString rawBytes = null; // If we encounter "message" before "typeId"
- IBuilder subBuilder = null;
+ IBuilderLite subBuilder = null;
FieldDescriptor field = null;
while (true) {