diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs
index 1f9711555..df9b4e7ee 100644
--- a/crypto/src/util/Arrays.cs
+++ b/crypto/src/util/Arrays.cs
@@ -591,6 +591,35 @@ namespace Org.BouncyCastle.Utilities
return rv;
}
+ public static byte[] ConcatenateAll(params byte[][] vs)
+ {
+ byte[][] nonNull = new byte[vs.Length][];
+ int count = 0;
+ int totalLength = 0;
+
+ for (int i = 0; i < vs.Length; ++i)
+ {
+ byte[] v = vs[i];
+ if (v != null)
+ {
+ nonNull[count++] = v;
+ totalLength += v.Length;
+ }
+ }
+
+ byte[] result = new byte[totalLength];
+ int pos = 0;
+
+ for (int j = 0; j < count; ++j)
+ {
+ byte[] v = nonNull[j];
+ Array.Copy(v, 0, result, pos, v.Length);
+ pos += v.Length;
+ }
+
+ return result;
+ }
+
public static int[] Concatenate(int[] a, int[] b)
{
if (a == null)
diff --git a/crypto/src/util/Enums.cs b/crypto/src/util/Enums.cs
index 25b218667..9e908c4c0 100644
--- a/crypto/src/util/Enums.cs
+++ b/crypto/src/util/Enums.cs
@@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Utilities
{
internal static Enum GetEnumValue(System.Type enumType, string s)
{
- if (!enumType.IsEnum)
+ if (!IsEnumType(enumType))
throw new ArgumentException("Not an enumeration type", "enumType");
// We only want to parse single named constants
@@ -39,10 +39,10 @@ namespace Org.BouncyCastle.Utilities
internal static Array GetEnumValues(System.Type enumType)
{
- if (!enumType.IsEnum)
+ if (!IsEnumType(enumType))
throw new ArgumentException("Not an enumeration type", "enumType");
-#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT || PORTABLE
+#if NETCF_1_0 || NETCF_2_0 || SILVERLIGHT
IList result = Platform.CreateArrayList();
FieldInfo[] fields = enumType.GetFields(BindingFlags.Static | BindingFlags.Public);
foreach (FieldInfo field in fields)
@@ -65,5 +65,14 @@ namespace Org.BouncyCastle.Utilities
int pos = (int)(DateTimeUtilities.CurrentUnixMs() & int.MaxValue) % values.Length;
return (Enum)values.GetValue(pos);
}
+
+ internal static bool IsEnumType(System.Type t)
+ {
+#if NEW_REFLECTION
+ return t.GetTypeInfo().IsEnum;
+#else
+ return t.IsEnum;
+#endif
+ }
}
}
diff --git a/crypto/src/util/Platform.cs b/crypto/src/util/Platform.cs
index bfed0950a..86484854d 100644
--- a/crypto/src/util/Platform.cs
+++ b/crypto/src/util/Platform.cs
@@ -13,13 +13,15 @@ namespace Org.BouncyCastle.Utilities
{
internal abstract class Platform
{
+ private static readonly CompareInfo InvariantCompareInfo = CultureInfo.InvariantCulture.CompareInfo;
+
#if NETCF_1_0 || NETCF_2_0
private static string GetNewLine()
{
MemoryStream buf = new MemoryStream();
StreamWriter w = new StreamWriter(buf, Encoding.UTF8);
w.WriteLine();
- w.Close();
+ Dispose(w);
byte[] bs = buf.ToArray();
return Encoding.UTF8.GetString(bs, 0, bs.Length);
}
@@ -30,14 +32,12 @@ namespace Org.BouncyCastle.Utilities
}
#endif
- internal static int CompareIgnoreCase(string a, string b)
+ internal static bool EqualsIgnoreCase(string a, string b)
{
-#if SILVERLIGHT
- return String.Compare(a, b, StringComparison.InvariantCultureIgnoreCase);
-#elif PORTABLE
- return String.Compare(a, b, CultureInfo.InvariantCulture, CompareOptions.IgnoreCase);
+#if PORTABLE
+ return String.Equals(a, b, StringComparison.OrdinalIgnoreCase);
#else
- return String.Compare(a, b, true);
+ return ToUpperInvariant(a) == ToUpperInvariant(b);
#endif
}
@@ -184,5 +184,46 @@ namespace Org.BouncyCastle.Utilities
}
internal static readonly string NewLine = GetNewLine();
+
+#if PORTABLE
+ internal static void Dispose(IDisposable d)
+ {
+ d.Dispose();
+ }
+#else
+ internal static void Dispose(Stream s)
+ {
+ s.Close();
+ }
+ internal static void Dispose(TextWriter t)
+ {
+ t.Close();
+ }
+#endif
+
+ internal static int IndexOf(string source, string value)
+ {
+ return InvariantCompareInfo.IndexOf(source, value, CompareOptions.Ordinal);
+ }
+
+ internal static int LastIndexOf(string source, string value)
+ {
+ return InvariantCompareInfo.LastIndexOf(source, value, CompareOptions.Ordinal);
+ }
+
+ internal static bool StartsWith(string source, string prefix)
+ {
+ return InvariantCompareInfo.IsPrefix(source, prefix, CompareOptions.Ordinal);
+ }
+
+ internal static bool EndsWith(string source, string suffix)
+ {
+ return InvariantCompareInfo.IsSuffix(source, suffix, CompareOptions.Ordinal);
+ }
+
+ internal static string GetTypeName(object obj)
+ {
+ return obj.GetType().FullName;
+ }
}
}
diff --git a/crypto/src/util/TypeExtensions.cs b/crypto/src/util/TypeExtensions.cs
new file mode 100644
index 000000000..e2aeae4dc
--- /dev/null
+++ b/crypto/src/util/TypeExtensions.cs
@@ -0,0 +1,17 @@
+#if NEW_REFLECTION
+
+using System;
+using System.Reflection;
+
+namespace Org.BouncyCastle
+{
+ internal static class TypeExtensions
+ {
+ public static bool IsInstanceOfType(this Type type, object instance)
+ {
+ return instance != null && type.GetTypeInfo().IsAssignableFrom(instance.GetType().GetTypeInfo());
+ }
+ }
+}
+
+#endif
diff --git a/crypto/src/util/io/BaseInputStream.cs b/crypto/src/util/io/BaseInputStream.cs
index 3ff4a1957..a5613d801 100644
--- a/crypto/src/util/io/BaseInputStream.cs
+++ b/crypto/src/util/io/BaseInputStream.cs
@@ -11,8 +11,25 @@ namespace Org.BouncyCastle.Utilities.IO
public sealed override bool CanRead { get { return !closed; } }
public sealed override bool CanSeek { get { return false; } }
public sealed override bool CanWrite { get { return false; } }
- public override void Close() { closed = true; }
- public sealed override void Flush() {}
+
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ closed = true;
+ }
+ base.Dispose(disposing);
+ }
+#else
+ public override void Close()
+ {
+ closed = true;
+ base.Close();
+ }
+#endif
+
+ public sealed override void Flush() {}
public sealed override long Length { get { throw new NotSupportedException(); } }
public sealed override long Position
{
diff --git a/crypto/src/util/io/BaseOutputStream.cs b/crypto/src/util/io/BaseOutputStream.cs
index 6e6c6d346..a0608d111 100644
--- a/crypto/src/util/io/BaseOutputStream.cs
+++ b/crypto/src/util/io/BaseOutputStream.cs
@@ -11,8 +11,25 @@ namespace Org.BouncyCastle.Utilities.IO
public sealed override bool CanRead { get { return false; } }
public sealed override bool CanSeek { get { return false; } }
public sealed override bool CanWrite { get { return !closed; } }
- public override void Close() { closed = true; }
- public override void Flush() {}
+
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ closed = true;
+ }
+ base.Dispose(disposing);
+ }
+#else
+ public override void Close()
+ {
+ closed = true;
+ base.Close();
+ }
+#endif
+
+ public override void Flush() { }
public sealed override long Length { get { throw new NotSupportedException(); } }
public sealed override long Position
{
diff --git a/crypto/src/util/io/FilterStream.cs b/crypto/src/util/io/FilterStream.cs
index 260ce1789..a92dee3e5 100644
--- a/crypto/src/util/io/FilterStream.cs
+++ b/crypto/src/util/io/FilterStream.cs
@@ -29,10 +29,22 @@ namespace Org.BouncyCastle.Utilities.IO
get { return s.Position; }
set { s.Position = value; }
}
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Platform.Dispose(s);
+ }
+ base.Dispose(disposing);
+ }
+#else
public override void Close()
{
- s.Close();
+ Platform.Dispose(s);
+ base.Close();
}
+#endif
public override void Flush()
{
s.Flush();
diff --git a/crypto/src/util/io/TeeInputStream.cs b/crypto/src/util/io/TeeInputStream.cs
index 373df4502..6996f3fbb 100644
--- a/crypto/src/util/io/TeeInputStream.cs
+++ b/crypto/src/util/io/TeeInputStream.cs
@@ -18,13 +18,26 @@ namespace Org.BouncyCastle.Utilities.IO
this.tee = tee;
}
- public override void Close()
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Platform.Dispose(input);
+ Platform.Dispose(tee);
+ }
+ base.Dispose(disposing);
+ }
+#else
+ public override void Close()
{
- input.Close();
- tee.Close();
+ Platform.Dispose(input);
+ Platform.Dispose(tee);
+ base.Close();
}
+#endif
- public override int Read(byte[] buf, int off, int len)
+ public override int Read(byte[] buf, int off, int len)
{
int i = input.Read(buf, off, len);
diff --git a/crypto/src/util/io/TeeOutputStream.cs b/crypto/src/util/io/TeeOutputStream.cs
index fe3a7586a..a6c7fd5b5 100644
--- a/crypto/src/util/io/TeeOutputStream.cs
+++ b/crypto/src/util/io/TeeOutputStream.cs
@@ -18,13 +18,26 @@ namespace Org.BouncyCastle.Utilities.IO
this.tee = tee;
}
- public override void Close()
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Platform.Dispose(output);
+ Platform.Dispose(tee);
+ }
+ base.Dispose(disposing);
+ }
+#else
+ public override void Close()
{
- output.Close();
- tee.Close();
+ Platform.Dispose(output);
+ Platform.Dispose(tee);
+ base.Close();
}
+#endif
- public override void Write(byte[] buffer, int offset, int count)
+ public override void Write(byte[] buffer, int offset, int count)
{
output.Write(buffer, offset, count);
tee.Write(buffer, offset, count);
diff --git a/crypto/src/util/io/pem/PemReader.cs b/crypto/src/util/io/pem/PemReader.cs
index b3284705d..bf712b6de 100644
--- a/crypto/src/util/io/pem/PemReader.cs
+++ b/crypto/src/util/io/pem/PemReader.cs
@@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
{
string line = reader.ReadLine();
- if (line != null && line.StartsWith(BeginString))
+ if (line != null && Platform.StartsWith(line, BeginString))
{
line = line.Substring(BeginString.Length);
int index = line.IndexOf('-');
@@ -56,7 +56,7 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
string line;
while ((line = reader.ReadLine()) != null
- && line.IndexOf(endMarker) == -1)
+ && Platform.IndexOf(line, endMarker) == -1)
{
int colonPos = line.IndexOf(':');
@@ -69,8 +69,10 @@ namespace Org.BouncyCastle.Utilities.IO.Pem
// Process field
string fieldName = line.Substring(0, colonPos).Trim();
- if (fieldName.StartsWith("X-"))
- fieldName = fieldName.Substring(2);
+ if (Platform.StartsWith(fieldName, "X-"))
+ {
+ fieldName = fieldName.Substring(2);
+ }
string fieldValue = line.Substring(colonPos + 1).Trim();
diff --git a/crypto/src/util/net/IPAddress.cs b/crypto/src/util/net/IPAddress.cs
index 2a30a15f0..38c124590 100644
--- a/crypto/src/util/net/IPAddress.cs
+++ b/crypto/src/util/net/IPAddress.cs
@@ -85,7 +85,7 @@ namespace Org.BouncyCastle.Utilities.Net
public static bool IsValidIPv4WithNetmask(
string address)
{
- int index = address.IndexOf("/");
+ int index = address.IndexOf('/');
string mask = address.Substring(index + 1);
return (index > 0) && IsValidIPv4(address.Substring(0, index))
@@ -95,7 +95,7 @@ namespace Org.BouncyCastle.Utilities.Net
public static bool IsValidIPv6WithNetmask(
string address)
{
- int index = address.IndexOf("/");
+ int index = address.IndexOf('/');
string mask = address.Substring(index + 1);
return (index > 0) && (IsValidIPv6(address.Substring(0, index))
diff --git a/crypto/src/util/zlib/ZDeflaterOutputStream.cs b/crypto/src/util/zlib/ZDeflaterOutputStream.cs
index 1d88847bd..d0f0bcb8d 100644
--- a/crypto/src/util/zlib/ZDeflaterOutputStream.cs
+++ b/crypto/src/util/zlib/ZDeflaterOutputStream.cs
@@ -136,6 +136,24 @@ namespace Org.BouncyCastle.Utilities.Zlib {
z=null;
}
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ try{
+ try{Finish();}
+ catch (IOException) {}
+ }
+ finally{
+ End();
+ Platform.Dispose(outp);
+ outp=null;
+ }
+ }
+ base.Dispose(disposing);
+ }
+#else
public override void Close() {
try{
try{Finish();}
@@ -143,9 +161,11 @@ namespace Org.BouncyCastle.Utilities.Zlib {
}
finally{
End();
- outp.Close();
+ Platform.Dispose(outp);
outp=null;
}
+ base.Close();
}
+#endif
}
}
diff --git a/crypto/src/util/zlib/ZInflaterInputStream.cs b/crypto/src/util/zlib/ZInflaterInputStream.cs
index 5a3ff5aa6..ef742bb00 100644
--- a/crypto/src/util/zlib/ZInflaterInputStream.cs
+++ b/crypto/src/util/zlib/ZInflaterInputStream.cs
@@ -114,10 +114,23 @@ namespace Org.BouncyCastle.Utilities.Zlib {
public override void WriteByte(byte b) {
}
- public override void Close() {
- inp.Close();
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Platform.Dispose(inp);
+ }
+ base.Dispose(disposing);
}
-
+#else
+ public override void Close()
+ {
+ Platform.Dispose(inp);
+ base.Close();
+ }
+#endif
+
public override int ReadByte() {
if(Read(buf1, 0, 1)<=0)
return -1;
diff --git a/crypto/src/util/zlib/ZInputStream.cs b/crypto/src/util/zlib/ZInputStream.cs
index d1e1ba160..4b7351555 100644
--- a/crypto/src/util/zlib/ZInputStream.cs
+++ b/crypto/src/util/zlib/ZInputStream.cs
@@ -93,14 +93,30 @@ namespace Org.BouncyCastle.Utilities.Zlib
public sealed override bool CanSeek { get { return false; } }
public sealed override bool CanWrite { get { return false; } }
- public override void Close()
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (closed)
+ return;
+
+ closed = true;
+ Platform.Dispose(input);
+ }
+ base.Dispose(disposing);
+ }
+#else
+ public override void Close()
{
- if (!closed)
- {
- closed = true;
- input.Close();
- }
+ if (closed)
+ return;
+
+ closed = true;
+ Platform.Dispose(input);
+ base.Close();
}
+#endif
public sealed override void Flush() {}
diff --git a/crypto/src/util/zlib/ZOutputStream.cs b/crypto/src/util/zlib/ZOutputStream.cs
index 1d2ead7b3..d9f005f69 100644
--- a/crypto/src/util/zlib/ZOutputStream.cs
+++ b/crypto/src/util/zlib/ZOutputStream.cs
@@ -95,32 +95,52 @@ namespace Org.BouncyCastle.Utilities.Zlib
public sealed override bool CanSeek { get { return false; } }
public sealed override bool CanWrite { get { return !closed; } }
+#if PORTABLE
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (closed)
+ return;
+
+ DoClose();
+ }
+ base.Dispose(disposing);
+ }
+#else
public override void Close()
{
- if (this.closed)
+ if (closed)
return;
- try
- {
- try
- {
- Finish();
- }
- catch (IOException)
- {
- // Ignore
- }
- }
- finally
- {
- this.closed = true;
- End();
- output.Close();
- output = null;
- }
+ DoClose();
+ base.Close();
}
+#endif
+
+ private void DoClose()
+ {
+ try
+ {
+ try
+ {
+ Finish();
+ }
+ catch (IOException)
+ {
+ // Ignore
+ }
+ }
+ finally
+ {
+ this.closed = true;
+ End();
+ Platform.Dispose(output);
+ output = null;
+ }
+ }
- public virtual void End()
+ public virtual void End()
{
if (z == null)
return;
|