Commit feb9385b authored by Jon Skeet's avatar Jon Skeet

Lots of text formatting tests, but ignored the parsing ones for the moment.

parent ca4cbda9
...@@ -21,19 +21,6 @@ namespace Google.ProtocolBuffers { ...@@ -21,19 +21,6 @@ namespace Google.ProtocolBuffers {
[TestFixture] [TestFixture]
public class CodedOutputStreamTest { public class CodedOutputStreamTest {
/// <summary>
/// Helper to construct a byte array from a bunch of bytes. The inputs are
/// actually ints so that I can use hex notation and not get stupid errors
/// about precision.
/// </summary>
private static byte[] Bytes(params int[] bytesAsInts) {
byte[] bytes = new byte[bytesAsInts.Length];
for (int i = 0; i < bytesAsInts.Length; i++) {
bytes[i] = (byte) bytesAsInts[i];
}
return bytes;
}
private static void AssertEqualBytes(byte[] a, byte[] b) { private static void AssertEqualBytes(byte[] a, byte[] b) {
Assert.AreEqual(ByteString.CopyFrom(a), ByteString.CopyFrom(b)); Assert.AreEqual(ByteString.CopyFrom(a), ByteString.CopyFrom(b));
} }
...@@ -92,29 +79,29 @@ namespace Google.ProtocolBuffers { ...@@ -92,29 +79,29 @@ namespace Google.ProtocolBuffers {
/// </summary> /// </summary>
[Test] [Test]
public void WriteVarint() { public void WriteVarint() {
AssertWriteVarint(Bytes(0x00), 0); AssertWriteVarint(new byte[] {0x00}, 0);
AssertWriteVarint(Bytes(0x01), 1); AssertWriteVarint(new byte[] {0x01}, 1);
AssertWriteVarint(Bytes(0x7f), 127); AssertWriteVarint(new byte[] {0x7f}, 127);
// 14882 // 14882
AssertWriteVarint(Bytes(0xa2, 0x74), (0x22 << 0) | (0x74 << 7)); AssertWriteVarint(new byte[] {0xa2, 0x74}, (0x22 << 0) | (0x74 << 7));
// 2961488830 // 2961488830
AssertWriteVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x0b), AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x0b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x0bL << 28)); (0x0bL << 28));
// 64-bit // 64-bit
// 7256456126 // 7256456126
AssertWriteVarint(Bytes(0xbe, 0xf7, 0x92, 0x84, 0x1b), AssertWriteVarint(new byte[] {0xbe, 0xf7, 0x92, 0x84, 0x1b},
(0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) | (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
(0x1bL << 28)); (0x1bL << 28));
// 41256202580718336 // 41256202580718336
AssertWriteVarint( AssertWriteVarint(
Bytes(0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49), new byte[] {0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49},
(0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) | (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
(0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49)); (0x43UL << 28) | (0x49L << 35) | (0x24UL << 42) | (0x49UL << 49));
// 11964378330978735131 // 11964378330978735131
AssertWriteVarint( AssertWriteVarint(
Bytes(0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01), new byte[] {0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01},
unchecked((ulong) unchecked((ulong)
((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) | ((0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
(0x3bL << 28) | (0x56L << 35) | (0x00L << 42) | (0x3bL << 28) | (0x56L << 35) | (0x00L << 42) |
...@@ -168,14 +155,14 @@ namespace Google.ProtocolBuffers { ...@@ -168,14 +155,14 @@ namespace Google.ProtocolBuffers {
/// </summary> /// </summary>
[Test] [Test]
public void WriteLittleEndian() { public void WriteLittleEndian() {
AssertWriteLittleEndian32(Bytes(0x78, 0x56, 0x34, 0x12), 0x12345678); AssertWriteLittleEndian32(new byte[] {0x78, 0x56, 0x34, 0x12}, 0x12345678);
AssertWriteLittleEndian32(Bytes(0xf0, 0xde, 0xbc, 0x9a), 0x9abcdef0); AssertWriteLittleEndian32(new byte[] {0xf0, 0xde, 0xbc, 0x9a}, 0x9abcdef0);
AssertWriteLittleEndian64( AssertWriteLittleEndian64(
Bytes(0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12), new byte[]{0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12},
0x123456789abcdef0L); 0x123456789abcdef0L);
AssertWriteLittleEndian64( AssertWriteLittleEndian64(
Bytes(0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a), new byte[]{0x78, 0x56, 0x34, 0x12, 0xf0, 0xde, 0xbc, 0x9a},
0x9abcdef012345678UL); 0x9abcdef012345678UL);
} }
......
...@@ -129,6 +129,9 @@ namespace Google.ProtocolBuffers { ...@@ -129,6 +129,9 @@ namespace Google.ProtocolBuffers {
registry.Add(UnitTestProtoFile.DefaultCordExtension); registry.Add(UnitTestProtoFile.DefaultCordExtension);
} }
internal static string ReadTextFromFile(string filePath) {
return ReadBytesFromFile(filePath).ToStringUtf8();
}
internal static ByteString ReadBytesFromFile(String filename) { internal static ByteString ReadBytesFromFile(String filename) {
byte[] data = File.ReadAllBytes(Path.Combine(TestDataDirectory, filename)); byte[] data = File.ReadAllBytes(Path.Combine(TestDataDirectory, filename));
...@@ -1334,5 +1337,16 @@ namespace Google.ProtocolBuffers { ...@@ -1334,5 +1337,16 @@ namespace Google.ProtocolBuffers {
Assert.AreEqual("abc", message.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension)); Assert.AreEqual("abc", message.GetExtension(UnitTestProtoFile.DefaultStringPieceExtension));
Assert.AreEqual("123", message.GetExtension(UnitTestProtoFile.DefaultCordExtension)); Assert.AreEqual("123", message.GetExtension(UnitTestProtoFile.DefaultCordExtension));
} }
/// <summary>
/// Helper to construct a byte array from a bunch of bytes.
/// </summary>
internal static byte[] Bytes(params byte[] bytesAsInts) {
byte[] bytes = new byte[bytesAsInts.Length];
for (int i = 0; i < bytesAsInts.Length; i++) {
bytes[i] = (byte)bytesAsInts[i];
}
return bytes;
}
} }
} }
...@@ -187,19 +187,23 @@ namespace Google.ProtocolBuffers { ...@@ -187,19 +187,23 @@ namespace Google.ProtocolBuffers {
} }
} }
internal static ulong ParseUInt64(string text) { // TODO(jonskeet): InternalsVisibleTo
public static ulong ParseUInt64(string text) {
return (ulong) ParseInteger(text, false, true); return (ulong) ParseInteger(text, false, true);
} }
internal static long ParseInt64(string text) { // TODO(jonskeet): InternalsVisibleTo
public static long ParseInt64(string text) {
return ParseInteger(text, true, true); return ParseInteger(text, true, true);
} }
internal static uint ParseUInt32(string text) { // TODO(jonskeet): InternalsVisibleTo
public static uint ParseUInt32(string text) {
return (uint) ParseInteger(text, false, false); return (uint) ParseInteger(text, false, false);
} }
internal static int ParseInt32(string text) { // TODO(jonskeet): InternalsVisibleTo
public static int ParseInt32(string text) {
return (int) ParseInteger(text, true, false); return (int) ParseInteger(text, true, false);
} }
...@@ -224,10 +228,17 @@ namespace Google.ProtocolBuffers { ...@@ -224,10 +228,17 @@ namespace Google.ProtocolBuffers {
text = text.Substring(2); text = text.Substring(2);
} else if (text.StartsWith("0")) { } else if (text.StartsWith("0")) {
radix = 8; radix = 8;
text = text.Substring(1);
} }
ulong result = Convert.ToUInt64(text, radix); ulong result;
try {
// Workaround for https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=278448
// We should be able to use Convert.ToUInt64 for all cases.
result = radix == 10 ? ulong.Parse(text) : Convert.ToUInt64(text, radix);
} catch (OverflowException) {
// Convert OverflowException to FormatException so there's a single exception type this method can throw.
throw new FormatException("Number of out range: " + original);
}
if (negative) { if (negative) {
ulong max = isLong ? 0x8000000000000000UL : 0x80000000L; ulong max = isLong ? 0x8000000000000000UL : 0x80000000L;
...@@ -276,12 +287,22 @@ namespace Google.ProtocolBuffers { ...@@ -276,12 +287,22 @@ namespace Google.ProtocolBuffers {
} }
} }
/// <summary>
/// Unescapes a text string as escaped using <see cref="EscapeText(string)" />.
/// Two-digit hex escapes (starting with "\x" are also recognised.
/// TODO(jonskeet): InternalsVisibleTo
/// </summary>
public static string UnescapeText(string input) {
return UnescapeBytes(input).ToStringUtf8();
}
/// <summary> /// <summary>
/// Like <see cref="EscapeBytes" /> but escapes a text string. /// Like <see cref="EscapeBytes" /> but escapes a text string.
/// The string is first encoded as UTF-8, then each byte escaped individually. /// The string is first encoded as UTF-8, then each byte escaped individually.
/// The returned value is guaranteed to be entirely ASCII. /// The returned value is guaranteed to be entirely ASCII.
/// TODO(jonskeet): InternalsVisibleTo
/// </summary> /// </summary>
static String EscapeText(string input) { public static string EscapeText(string input) {
return EscapeBytes(ByteString.CopyFromUtf8(input)); return EscapeBytes(ByteString.CopyFromUtf8(input));
} }
/// <summary> /// <summary>
...@@ -292,8 +313,9 @@ namespace Google.ProtocolBuffers { ...@@ -292,8 +313,9 @@ namespace Google.ProtocolBuffers {
/// which no defined short-hand escape sequence is defined will be escaped /// which no defined short-hand escape sequence is defined will be escaped
/// using 3-digit octal sequences. /// using 3-digit octal sequences.
/// The returned value is guaranteed to be entirely ASCII. /// The returned value is guaranteed to be entirely ASCII.
/// TODO(jonskeet): InternalsVisibleTo
/// </summary> /// </summary>
private static String EscapeBytes(ByteString input) { public static String EscapeBytes(ByteString input) {
StringBuilder builder = new StringBuilder(input.Length); StringBuilder builder = new StringBuilder(input.Length);
foreach (byte b in input) { foreach (byte b in input) {
switch (b) { switch (b) {
...@@ -309,7 +331,7 @@ namespace Google.ProtocolBuffers { ...@@ -309,7 +331,7 @@ namespace Google.ProtocolBuffers {
case (byte)'\'': builder.Append("\\\'"); break; case (byte)'\'': builder.Append("\\\'"); break;
case (byte)'"' : builder.Append("\\\""); break; case (byte)'"' : builder.Append("\\\""); break;
default: default:
if (b >= 0x20) { if (b >= 0x20 && b < 128) {
builder.Append((char) b); builder.Append((char) b);
} else { } else {
builder.Append('\\'); builder.Append('\\');
...@@ -325,8 +347,9 @@ namespace Google.ProtocolBuffers { ...@@ -325,8 +347,9 @@ namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Performs string unescaping from C style (octal, hex, form feeds, tab etc) into a byte string. /// Performs string unescaping from C style (octal, hex, form feeds, tab etc) into a byte string.
/// TODO(jonskeet): Make this internal again, and use InternalsVisibleTo.
/// </summary> /// </summary>
internal static ByteString UnescapeBytes(string input) { public static ByteString UnescapeBytes(string input) {
byte[] result = new byte[input.Length]; byte[] result = new byte[input.Length];
int pos = 0; int pos = 0;
for (int i = 0; i < input.Length; i++) { for (int i = 0; i < input.Length; i++) {
...@@ -393,5 +416,21 @@ namespace Google.ProtocolBuffers { ...@@ -393,5 +416,21 @@ namespace Google.ProtocolBuffers {
return ByteString.CopyFrom(result, 0, pos); return ByteString.CopyFrom(result, 0, pos);
} }
public static void Merge(string text, IBuilder builder) {
throw new NotImplementedException();
}
public static void Merge(TextReader reader, IBuilder builder) {
throw new NotImplementedException();
}
public static void Merge(string text, ExtensionRegistry registry, IBuilder builder) {
throw new NotImplementedException();
}
public static void Merge(TextReader reader, ExtensionRegistry registry, IBuilder builder) {
throw new NotImplementedException();
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment