summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/CCI/FastFileIO.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tools/Sandcastle/Source/CCI/FastFileIO.cs')
-rw-r--r--tools/Sandcastle/Source/CCI/FastFileIO.cs606
1 files changed, 606 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/CCI/FastFileIO.cs b/tools/Sandcastle/Source/CCI/FastFileIO.cs
new file mode 100644
index 0000000..865932c
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/FastFileIO.cs
@@ -0,0 +1,606 @@
+// Copyright © Microsoft Corporation.
+// This source file is subject to the Microsoft Permissive License.
+// See http://www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
+// All other rights reserved.
+
+using System;
+using System.Diagnostics;
+#if CCINamespace
+using Microsoft.Cci.Metadata;
+#else
+using System.Compiler.Metadata;
+#endif
+using System.Globalization;
+using System.Text;
+
+#if CCINamespace
+namespace Microsoft.Cci{
+#else
+namespace System.Compiler
+{
+#endif
+#if !(FxCop || NoWriter)
+ /// <summary>
+ /// High performance replacement for System.IO.BinaryWriter.
+ /// </summary>
+ public sealed class BinaryWriter
+ {
+ public MemoryStream/*!*/ BaseStream;
+ private bool UTF8 = true;
+ public BinaryWriter(MemoryStream/*!*/ output)
+ {
+ this.BaseStream = output;
+ //^ base();
+ }
+ public BinaryWriter(MemoryStream/*!*/ output, Encoding/*!*/ encoding)
+ {
+ Debug.Assert(encoding == Encoding.Unicode);
+ this.BaseStream = output;
+ this.UTF8 = false;
+ //^ base();
+ }
+ public void Write(bool value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 1;
+ m.Buffer[i] = (byte)(value ? 1 : 0);
+ }
+ public void Write(byte value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 1;
+ m.Buffer[i] = value;
+ }
+ public void Write(sbyte value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 1;
+ m.Buffer[i] = (byte)value;
+ }
+ public void Write(byte[] buffer)
+ {
+ if (buffer == null) return;
+ this.BaseStream.Write(buffer, 0, buffer.Length);
+ }
+ public void Write(char ch)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ if (this.UTF8)
+ {
+ if (ch < 0x80)
+ {
+ m.Position = i + 1;
+ m.Buffer[i] = (byte)ch;
+ }
+ else
+ this.Write(new char[] { ch });
+ }
+ else
+ {
+ m.Position = i + 2;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)ch;
+ buffer[i] = (byte)(ch >> 8);
+ }
+ }
+ public void Write(char[] chars)
+ {
+ if (chars == null) return;
+ MemoryStream m = this.BaseStream;
+ int n = chars.Length;
+ int i = m.Position;
+ if (this.UTF8)
+ {
+ m.Position = i + n;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = chars[j];
+ if ((ch & 0x80) != 0) goto writeUTF8;
+ buffer[i++] = (byte)ch;
+ }
+ return;
+ writeUTF8:
+ int ch32 = 0;
+ for (int j = n - (m.Position - i); j < n; j++)
+ {
+ char ch = chars[j];
+ if (ch < 0x80)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)ch;
+ }
+ else if (ch < 0x800)
+ {
+ m.Position = i + 2;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 6) & 0x1F) | 0xC0);
+ buffer[i] = (byte)((ch & 0x3F) | 0x80);
+ }
+ else if (0xD800 <= ch && ch <= 0xDBFF)
+ {
+ ch32 = (ch & 0x3FF) << 10;
+ }
+ else if (0xDC00 <= ch && ch <= 0xDFFF)
+ {
+ ch32 |= ch & 0x3FF;
+ m.Position = i + 4;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch32 >> 18) & 0x7) | 0xF0);
+ buffer[i++] = (byte)(((ch32 >> 12) & 0x3F) | 0x80);
+ buffer[i++] = (byte)(((ch32 >> 6) & 0x3F) | 0x80);
+ buffer[i] = (byte)((ch32 & 0x3F) | 0x80);
+ }
+ else
+ {
+ m.Position = i + 3;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 12) & 0xF) | 0xE0);
+ buffer[i++] = (byte)(((ch >> 6) & 0x3F) | 0x80);
+ buffer[i] = (byte)((ch & 0x3F) | 0x80);
+ }
+ }
+ }
+ else
+ {
+ m.Position = i + n * 2;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = chars[j];
+ buffer[i++] = (byte)ch;
+ buffer[i++] = (byte)(ch >> 8);
+ }
+ }
+ }
+ public unsafe void Write(double value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 8;
+ fixed (byte* b = m.Buffer)
+ *((double*)(b + i)) = value;
+ }
+ public void Write(short value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 2;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i] = (byte)(value >> 8);
+ }
+ public unsafe void Write(ushort value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 2;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i] = (byte)(value >> 8);
+ }
+ public void Write(int value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 4;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i++] = (byte)(value >> 8);
+ buffer[i++] = (byte)(value >> 16);
+ buffer[i] = (byte)(value >> 24);
+ }
+ public void Write(uint value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 4;
+ byte[] buffer = m.Buffer;
+ buffer[i++] = (byte)value;
+ buffer[i++] = (byte)(value >> 8);
+ buffer[i++] = (byte)(value >> 16);
+ buffer[i] = (byte)(value >> 24);
+ }
+ public void Write(long value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 8;
+ byte[] buffer = m.Buffer;
+ uint lo = (uint)value;
+ uint hi = (uint)(value >> 32);
+ buffer[i++] = (byte)lo;
+ buffer[i++] = (byte)(lo >> 8);
+ buffer[i++] = (byte)(lo >> 16);
+ buffer[i++] = (byte)(lo >> 24);
+ buffer[i++] = (byte)hi;
+ buffer[i++] = (byte)(hi >> 8);
+ buffer[i++] = (byte)(hi >> 16);
+ buffer[i] = (byte)(hi >> 24);
+ }
+ public unsafe void Write(ulong value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 8;
+ byte[] buffer = m.Buffer;
+ uint lo = (uint)value;
+ uint hi = (uint)(value >> 32);
+ buffer[i++] = (byte)lo;
+ buffer[i++] = (byte)(lo >> 8);
+ buffer[i++] = (byte)(lo >> 16);
+ buffer[i++] = (byte)(lo >> 24);
+ buffer[i++] = (byte)hi;
+ buffer[i++] = (byte)(hi >> 8);
+ buffer[i++] = (byte)(hi >> 16);
+ buffer[i] = (byte)(hi >> 24);
+ }
+ public unsafe void Write(float value)
+ {
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ m.Position = i + 4;
+ fixed (byte* b = m.Buffer)
+ *((float*)(b + i)) = value;
+ }
+ public void Write(string str)
+ {
+ this.Write(str, false);
+ }
+ public void Write(string str, bool emitNullTerminator)
+ {
+ if (str == null)
+ {
+ Debug.Assert(!emitNullTerminator);
+ this.Write((byte)0xff);
+ return;
+ }
+ int n = str.Length;
+ if (!emitNullTerminator)
+ {
+ if (this.UTF8)
+ Ir2md.WriteCompressedInt(this, this.GetUTF8ByteCount(str));
+ else
+ Ir2md.WriteCompressedInt(this, n * 2);
+ }
+ MemoryStream m = this.BaseStream;
+ int i = m.Position;
+ if (this.UTF8)
+ {
+ m.Position = i + n;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = str[j];
+ if (ch >= 0x80) goto writeUTF8;
+ buffer[i++] = (byte)ch;
+ }
+ if (emitNullTerminator)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i] = 0;
+ }
+ return;
+ writeUTF8:
+ int ch32 = 0;
+ for (int j = n - (m.Position - i); j < n; j++)
+ {
+ char ch = str[j];
+ if (ch < 0x80)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)ch;
+ }
+ else if (ch < 0x800)
+ {
+ m.Position = i + 2;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 6) & 0x1F) | 0xC0);
+ buffer[i++] = (byte)((ch & 0x3F) | 0x80);
+ }
+ else if (0xD800 <= ch && ch <= 0xDBFF)
+ {
+ ch32 = (ch & 0x3FF) << 10;
+ }
+ else if (0xDC00 <= ch && ch <= 0xDFFF)
+ {
+ ch32 |= ch & 0x3FF;
+ m.Position = i + 4;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch32 >> 18) & 0x7) | 0xF0);
+ buffer[i++] = (byte)(((ch32 >> 12) & 0x3F) | 0x80);
+ buffer[i++] = (byte)(((ch32 >> 6) & 0x3F) | 0x80);
+ buffer[i++] = (byte)((ch32 & 0x3F) | 0x80);
+ }
+ else
+ {
+ m.Position = i + 3;
+ buffer = m.Buffer;
+ buffer[i++] = (byte)(((ch >> 12) & 0xF) | 0xE0);
+ buffer[i++] = (byte)(((ch >> 6) & 0x3F) | 0x80);
+ buffer[i++] = (byte)((ch & 0x3F) | 0x80);
+ }
+ }
+ if (emitNullTerminator)
+ {
+ m.Position = i + 1;
+ buffer = m.Buffer;
+ buffer[i] = 0;
+ }
+ }
+ else
+ {
+ m.Position = i + n * 2;
+ byte[] buffer = m.Buffer;
+ for (int j = 0; j < n; j++)
+ {
+ char ch = str[j];
+ buffer[i++] = (byte)ch;
+ buffer[i++] = (byte)(ch >> 8);
+ }
+ if (emitNullTerminator)
+ {
+ m.Position = i + 2;
+ buffer = m.Buffer;
+ buffer[i++] = 0;
+ buffer[i] = 0;
+ }
+ }
+ }
+ public int GetUTF8ByteCount(string str)
+ {
+ int count = 0;
+ for (int i = 0, n = str == null ? 0 : str.Length; i < n; i++)
+ {
+ //^ assume str != null;
+ char ch = str[i];
+ if (ch < 0x80)
+ {
+ count += 1;
+ }
+ else if (ch < 0x800)
+ {
+ count += 2;
+ }
+ else if (0xD800 <= ch && ch <= 0xDBFF)
+ {
+ count += 2;
+ }
+ else if (0xDC00 <= ch && ch <= 0xDFFF)
+ {
+ count += 2;
+ }
+ else
+ {
+ count += 3;
+ }
+ }
+ return count;
+ }
+ }
+ public sealed class MemoryStream
+ {
+ public byte[]/* ! */ Buffer;
+ public int Length;
+ public int position;
+ public int Position
+ {
+ get { return this.position; }
+ set
+ {
+ byte[] myBuffer = this.Buffer;
+ int n = myBuffer.Length;
+ if (value >= n) this.Grow(myBuffer, n, value);
+ if (value > this.Length) this.Length = value;
+ this.position = value;
+ }
+ }
+ public MemoryStream()
+ {
+ this.Buffer = new byte[64];
+ this.Length = 0;
+ this.position = 0;
+ //^ base();
+ }
+ public MemoryStream(byte[]/*!*/ bytes)
+ {
+ if (bytes == null) { Debug.Fail(""); }
+ this.Buffer = bytes;
+ this.Length = bytes.Length;
+ this.position = 0;
+ //^ base();
+ }
+ private void Grow(byte[]/*!*/ myBuffer, int n, int m)
+ {
+ if (myBuffer == null) { Debug.Fail(""); return; }
+ int n2 = n * 2;
+ while (m >= n2) n2 = n2 * 2;
+ byte[] newBuffer = this.Buffer = new byte[n2];
+ for (int i = 0; i < n; i++)
+ newBuffer[i] = myBuffer[i]; //TODO: optimize this
+ }
+ public void Seek(long offset, SeekOrigin loc)
+ {
+ Debug.Assert(loc == SeekOrigin.Begin);
+ Debug.Assert(offset <= int.MaxValue);
+ this.Position = (int)offset;
+ }
+ public byte[]/*!*/ ToArray()
+ {
+ int n = this.Length;
+ byte[] source = this.Buffer;
+ if (source.Length == n) return this.Buffer; //unlikely, but the check is cheap
+ byte[] result = new byte[n];
+ for (int i = 0; i < n; i++)
+ result[i] = source[i]; //TODO: optimize this
+ return result;
+ }
+ public void Write(byte[]/*!*/ buffer, int index, int count)
+ {
+ int p = this.position;
+ this.Position = p + count;
+ byte[] myBuffer = this.Buffer;
+ for (int i = 0, j = p, k = index; i < count; i++)
+ myBuffer[j++] = buffer[k++]; //TODO: optimize this
+ }
+ public void WriteTo(MemoryStream/*!*/ stream)
+ {
+ stream.Write(this.Buffer, 0, this.Length);
+ }
+ public void WriteTo(System.IO.Stream/*!*/ stream)
+ {
+ stream.Write(this.Buffer, 0, this.Length);
+ }
+ }
+ public enum SeekOrigin { Begin, Current, End }
+#endif
+ /// <summary>
+ /// A version of System.IO.Path that does not throw exceptions.
+ /// </summary>
+#if FxCop || NoWriter
+ internal sealed class BetterPath {
+#else
+ public sealed class BetterPath
+ {
+#endif
+ public static readonly char AltDirectorySeparatorChar = System.IO.Path.AltDirectorySeparatorChar;
+ public static readonly char DirectorySeparatorChar = System.IO.Path.DirectorySeparatorChar;
+ public static readonly char VolumeSeparatorChar = System.IO.Path.VolumeSeparatorChar;
+
+ public static string ChangeExtension(string path, string extension)
+ {
+ if (path == null) return null;
+ string text1 = path;
+ int num1 = path.Length;
+ while (--num1 >= 0)
+ {
+ char ch1 = path[num1];
+ if (ch1 == '.')
+ {
+ text1 = path.Substring(0, num1);
+ break;
+ }
+ if (((ch1 == BetterPath.DirectorySeparatorChar) || (ch1 == BetterPath.AltDirectorySeparatorChar)) || (ch1 == BetterPath.VolumeSeparatorChar))
+ break;
+ }
+ if (extension == null || path.Length == 0) return text1;
+ if (extension.Length == 0 || extension[0] != '.')
+ text1 = text1 + ".";
+ return text1 + extension;
+ }
+ public static string Combine(string path1, string path2)
+ {
+ if (path1 == null || path1.Length == 0) return path2;
+ if (path2 == null || path2.Length == 0) return path1;
+ char ch = path2[0];
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || (path2.Length >= 2 && path2[1] == BetterPath.VolumeSeparatorChar))
+ return path2;
+ ch = path1[path1.Length - 1];
+ if (ch != BetterPath.DirectorySeparatorChar && ch != BetterPath.AltDirectorySeparatorChar && ch != BetterPath.VolumeSeparatorChar)
+ return (path1 + BetterPath.DirectorySeparatorChar + path2);
+ return path1 + path2;
+ }
+ public static string GetExtension(string path)
+ {
+ if (path == null) return null;
+ int length = path.Length;
+ for (int i = length; --i >= 0; )
+ {
+ char ch = path[i];
+ if (ch == '.')
+ {
+ if (i != length - 1)
+ return path.Substring(i, length - i);
+ else
+ return String.Empty;
+ }
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || ch == BetterPath.VolumeSeparatorChar)
+ break;
+ }
+ return string.Empty;
+ }
+ public static String GetFileName(string path)
+ {
+ if (path == null) return null;
+ int length = path.Length;
+ for (int i = length; --i >= 0; )
+ {
+ char ch = path[i];
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || ch == BetterPath.VolumeSeparatorChar)
+ return path.Substring(i + 1);
+ }
+ return path;
+ }
+ public static string GetFileNameWithoutExtension(string path)
+ {
+ int num1;
+ path = BetterPath.GetFileName(path);
+ if (path == null) return null;
+ if ((num1 = path.LastIndexOf('.')) == -1) return path;
+ return path.Substring(0, num1);
+ }
+ public static String GetDirectoryName(string path)
+ {
+ if (path == null) return null;
+ int length = path.Length;
+ for (int i = length; --i >= 0; )
+ {
+ char ch = path[i];
+ if (ch == BetterPath.DirectorySeparatorChar || ch == BetterPath.AltDirectorySeparatorChar || ch == BetterPath.VolumeSeparatorChar)
+ return path.Substring(0, i);
+ }
+ return path;
+ }
+ public static char[] GetInvalidFileNameChars()
+ {
+#if WHIDBEY
+ return System.IO.Path.GetInvalidFileNameChars();
+#else
+ return System.IO.Path.InvalidPathChars;
+#endif
+ }
+ public static char[] GetInvalidPathChars()
+ {
+#if WHIDBEY
+ return System.IO.Path.GetInvalidPathChars();
+#else
+ return System.IO.Path.InvalidPathChars;
+#endif
+ }
+ public static string GetTempFileName()
+ {
+ return System.IO.Path.GetTempFileName();
+ }
+ public static bool HasExtension(string path)
+ {
+ if (path != null)
+ {
+ int num1 = path.Length;
+ while (--num1 >= 0)
+ {
+ char ch1 = path[num1];
+ if (ch1 == '.')
+ {
+ if (num1 != (path.Length - 1))
+ {
+ return true;
+ }
+ return false;
+ }
+ if (((ch1 == BetterPath.DirectorySeparatorChar) || (ch1 == BetterPath.AltDirectorySeparatorChar)) || (ch1 == BetterPath.VolumeSeparatorChar))
+ {
+ break;
+ }
+ }
+ }
+ return false;
+ }
+ }
+}