summaryrefslogtreecommitdiffstats
path: root/tools/Sandcastle/Source/CCI/MemoryMappedFile.cs
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-09-20 21:18:59 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2009-09-21 08:06:22 -0700
commitbbe3f9cc9c8a1e5909273c1a162a63ea7a66afd8 (patch)
treec91f66e642c4d26fca266e226b3f2765f546d700 /tools/Sandcastle/Source/CCI/MemoryMappedFile.cs
parent627014f0bbc3fd576277375e70f8391d150b0a67 (diff)
downloadDotNetOpenAuth-bbe3f9cc9c8a1e5909273c1a162a63ea7a66afd8.zip
DotNetOpenAuth-bbe3f9cc9c8a1e5909273c1a162a63ea7a66afd8.tar.gz
DotNetOpenAuth-bbe3f9cc9c8a1e5909273c1a162a63ea7a66afd8.tar.bz2
Switched out the Sandcastle binaries for the source code.
Diffstat (limited to 'tools/Sandcastle/Source/CCI/MemoryMappedFile.cs')
-rw-r--r--tools/Sandcastle/Source/CCI/MemoryMappedFile.cs459
1 files changed, 459 insertions, 0 deletions
diff --git a/tools/Sandcastle/Source/CCI/MemoryMappedFile.cs b/tools/Sandcastle/Source/CCI/MemoryMappedFile.cs
new file mode 100644
index 0000000..ac9558c
--- /dev/null
+++ b/tools/Sandcastle/Source/CCI/MemoryMappedFile.cs
@@ -0,0 +1,459 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+using System;
+#if CCINamespace
+using Microsoft.Cci;
+#else
+using System.Compiler;
+#endif
+using System.Diagnostics;
+using System.IO;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if CCINamespace
+namespace Microsoft.Cci.Metadata{
+#else
+namespace System.Compiler.Metadata
+{
+#endif
+ unsafe internal sealed class MemoryCursor
+ {
+ private byte* buffer, pb;
+ readonly internal int Length;
+
+#if !ROTOR
+ internal MemoryCursor(MemoryMappedFile/*!*/ memoryMap)
+ : this(memoryMap.Buffer, memoryMap.Length)
+ {
+ }
+#endif
+ internal MemoryCursor(byte* buffer, int length, int position)
+ {
+ this.buffer = buffer;
+ this.pb = buffer + position;
+ this.Length = length;
+ }
+ internal MemoryCursor(byte* buffer, int length)
+ : this(buffer, length, 0)
+ {
+ }
+ internal MemoryCursor(MemoryCursor/*!*/ c)
+ {
+ this.buffer = c.buffer;
+ this.pb = c.pb;
+ this.Length = c.Length;
+ }
+
+ internal byte* GetBuffer()
+ {
+ return this.buffer;
+ }
+
+ internal int Position
+ {
+ get { return (int)(this.pb - this.buffer); }
+ set { this.pb = this.buffer + value; }
+ }
+ internal void Align(int size)
+ {
+ Debug.Assert(size == 2 || size == 4 || size == 8 || size == 16 || size == 32 || size == 64);
+ int remainder = Position & (size - 1);
+ if (remainder != 0)
+ pb += size - remainder;
+ }
+
+ //internal System.Char Char(int i){ return *(System.Char*)(this.pb+i*sizeof(System.Char)); }
+ //internal System.SByte SByte(int i){ return *(System.SByte*)(this.pb+i*sizeof(System.SByte)); }
+ internal System.Int16 Int16(int i) { return *(System.Int16*)(this.pb + i * sizeof(System.Int16)); }
+ internal System.Int32 Int32(int i) { return *(System.Int32*)(this.pb + i * sizeof(System.Int32)); }
+ //internal System.Int64 Int64(int i){ return *(System.Int64*)(this.pb+i*sizeof(System.Int64)); }
+ internal System.Byte Byte(int i) { return *(System.Byte*)(this.pb + i * sizeof(System.Byte)); }
+ internal System.UInt16 UInt16(int i) { return *(System.UInt16*)(this.pb + i * sizeof(System.UInt16)); }
+ //internal System.UInt32 UInt32(int i){ return *(System.UInt32*)(this.pb+i*sizeof(System.UInt32)); }
+ //internal System.UInt64 UInt64(int i){ return *(System.UInt64*)(this.pb+i*sizeof(System.UInt64)); }
+ //internal System.Boolean Boolean(int i){ return *(System.Boolean*)(this.pb+i*sizeof(System.Boolean)); }
+ //internal System.Single Single(int i){ return *(System.Single*)(this.pb+i*sizeof(System.Single)); }
+ //internal System.Double Double(int i){ return *(System.Double*)(this.pb+i*sizeof(System.Double)); }
+
+ //internal void SkipChar(int c){ this.pb += c*sizeof(System.Char); }
+ //internal void SkipSByte(int c){ this.pb += c*sizeof(System.SByte); }
+ internal void SkipInt16(int c) { this.pb += c * sizeof(System.Int16); }
+ internal void SkipInt32(int c) { this.pb += c * sizeof(System.Int32); }
+ //internal void SkipInt64(int c){ this.pb += c*sizeof(System.Int64); }
+ internal void SkipByte(int c) { this.pb += c * sizeof(System.Byte); }
+ internal void SkipUInt16(int c) { this.pb += c * sizeof(System.UInt16); }
+ //internal void SkipUInt32(int c){ this.pb += c*sizeof(System.UInt32); }
+ //internal void SkipUInt64(int c){ this.pb += c*sizeof(System.UInt64); }
+ //internal void SkipBoolean(int c){ this.pb += c*sizeof(System.Boolean); }
+ //internal void SkipSingle(int c){ this.pb += c*sizeof(System.Single); }
+ //internal void SkipDouble(int c){ this.pb += c*sizeof(System.Double); }
+
+ internal System.Char ReadChar() { byte* pb = this.pb; System.Char v = *(System.Char*)pb; this.pb = pb + sizeof(System.Char); return v; }
+ internal System.SByte ReadSByte() { byte* pb = this.pb; System.SByte v = *(System.SByte*)pb; this.pb = pb + sizeof(System.SByte); return v; }
+ internal System.Int16 ReadInt16() { byte* pb = this.pb; System.Int16 v = *(System.Int16*)pb; this.pb = pb + sizeof(System.Int16); return v; }
+ internal System.Int32 ReadInt32() { byte* pb = this.pb; System.Int32 v = *(System.Int32*)pb; this.pb = pb + sizeof(System.Int32); return v; }
+ internal System.Int64 ReadInt64() { byte* pb = this.pb; System.Int64 v = *(System.Int64*)pb; this.pb = pb + sizeof(System.Int64); return v; }
+ internal System.Byte ReadByte() { byte* pb = this.pb; System.Byte v = *(System.Byte*)pb; this.pb = pb + sizeof(System.Byte); return v; }
+ internal System.UInt16 ReadUInt16() { byte* pb = this.pb; System.UInt16 v = *(System.UInt16*)pb; this.pb = pb + sizeof(System.UInt16); return v; }
+ internal System.UInt32 ReadUInt32() { byte* pb = this.pb; System.UInt32 v = *(System.UInt32*)pb; this.pb = pb + sizeof(System.UInt32); return v; }
+ internal System.UInt64 ReadUInt64() { byte* pb = this.pb; System.UInt64 v = *(System.UInt64*)pb; this.pb = pb + sizeof(System.UInt64); return v; }
+ internal System.Boolean ReadBoolean() { byte* pb = this.pb; System.Boolean v = *(System.Boolean*)pb; this.pb = pb + sizeof(System.Boolean); return v; }
+ internal System.Single ReadSingle() { byte* pb = this.pb; System.Single v = *(System.Single*)pb; this.pb = pb + sizeof(System.Single); return v; }
+ internal System.Double ReadDouble() { byte* pb = this.pb; System.Double v = *(System.Double*)pb; this.pb = pb + sizeof(System.Double); return v; }
+
+ internal System.Int32 ReadReference(int refSize)
+ {
+ if (refSize == 2) return ReadUInt16();
+ return ReadInt32();
+ }
+
+ internal int ReadCompressedInt()
+ {
+ byte headerByte = ReadByte();
+ int result;
+ if ((headerByte & 0x80) == 0x00)
+ result = headerByte;
+ else if ((headerByte & 0x40) == 0x00)
+ result = ((headerByte & 0x3f) << 8) | ReadByte();
+ else if (headerByte == 0xFF)
+ result = -1;
+ else
+ result = ((headerByte & 0x3f) << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte();
+ return result;
+ }
+
+ internal byte[]/*!*/ ReadBytes(int c)
+ {
+ byte[] result = new byte[c];
+ byte* pb = this.pb;
+ for (int i = 0; i < c; i++)
+ result[i] = *pb++;
+ this.pb = pb;
+ return result;
+ }
+
+ internal unsafe Identifier/*!*/ ReadIdentifierFromSerString()
+ {
+ byte* pb = this.pb;
+ byte headerByte = *pb++;
+ uint length = 0;
+ if ((headerByte & 0x80) == 0x00)
+ length = headerByte;
+ else if ((headerByte & 0x40) == 0x00)
+ length = (uint)((headerByte & 0x3f) << 8) | *pb++;
+ else
+ length = (uint)((headerByte & 0x3f) << 24) | (uint)(*pb++ << 16) | (uint)(*pb++ << 8) | (*pb++);
+ this.pb = pb + length;
+ return Identifier.For(pb, length/*, this.KeepAlive*/);
+ }
+
+ internal string/*!*/ ReadUTF8(int bytesToRead)
+ {
+ char[] buffer = new char[bytesToRead];
+ byte* pb = this.pb;
+ this.pb += bytesToRead;
+ int j = 0;
+ while (bytesToRead > 0)
+ {
+ byte b = *pb++; bytesToRead--;
+ if ((b & 0x80) == 0 || bytesToRead == 0)
+ {
+ buffer[j++] = (char)b;
+ continue;
+ }
+ char ch;
+ byte b1 = *pb++; bytesToRead--;
+ if ((b & 0x20) == 0)
+ ch = (char)(((b & 0x1F) << 6) | (b1 & 0x3F));
+ else
+ {
+ if (bytesToRead == 0)
+ { //Dangling lead bytes, do not decompose
+ buffer[j++] = (char)((b << 8) | b1);
+ break;
+ }
+ byte b2 = *pb++; bytesToRead--;
+ uint ch32;
+ if ((b & 0x10) == 0)
+ ch32 = (uint)(((b & 0x0F) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F));
+ else
+ {
+ if (bytesToRead == 0)
+ { //Dangling lead bytes, do not decompose
+ buffer[j++] = (char)((b << 8) | b1);
+ buffer[j++] = (char)b2;
+ break;
+ }
+ byte b3 = *pb++; bytesToRead--;
+ ch32 = (uint)(((b & 0x07) << 18) | ((b1 & 0x3F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
+ }
+ if ((ch32 & 0xFFFF0000) == 0)
+ ch = (char)ch32;
+ else
+ { //break up into UTF16 surrogate pair
+ buffer[j++] = (char)((ch32 >> 10) | 0xD800);
+ ch = (char)((ch32 & 0x3FF) | 0xDC00);
+ }
+ }
+ buffer[j++] = ch;
+ }
+ if (j > 0 && buffer[j - 1] == 0) j--;
+ return new String(buffer, 0, j);
+ }
+
+ internal string/*!*/ ReadUTF8()
+ {
+ byte* pb = this.pb;
+ StringBuilder sb = new StringBuilder();
+ byte b = 0;
+ for (; ; )
+ {
+ b = *pb++;
+ if (b == 0) break;
+ if ((b & 0x80) == 0)
+ {
+ sb.Append((char)b);
+ continue;
+ }
+ char ch;
+ byte b1 = *pb++;
+ if (b1 == 0)
+ { //Dangling lead byte, do not decompose
+ sb.Append((char)b);
+ break;
+ }
+ if ((b & 0x20) == 0)
+ {
+ ch = (char)(((b & 0x1F) << 6) | (b1 & 0x3F));
+ }
+ else
+ {
+ byte b2 = *pb++;
+ if (b2 == 0)
+ { //Dangling lead bytes, do not decompose
+ sb.Append((char)((b << 8) | b1));
+ break;
+ }
+ uint ch32;
+ if ((b & 0x10) == 0)
+ ch32 = (uint)(((b & 0x0F) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F));
+ else
+ {
+ byte b3 = *pb++;
+ if (b3 == 0)
+ { //Dangling lead bytes, do not decompose
+ sb.Append((char)((b << 8) | b1));
+ sb.Append((char)b2);
+ break;
+ }
+ ch32 = (uint)(((b & 0x07) << 18) | ((b1 & 0x3F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
+ }
+ if ((ch32 & 0xFFFF0000) == 0)
+ ch = (char)ch32;
+ else
+ { //break up into UTF16 surrogate pair
+ sb.Append((char)((ch32 >> 10) | 0xD800));
+ ch = (char)((ch32 & 0x3FF) | 0xDC00);
+ }
+ }
+ sb.Append(ch);
+ }
+ this.pb = pb;
+ return sb.ToString();
+ }
+
+ internal string/*!*/ ReadUTF16(int charsToRead)
+ {
+ char* pc = (char*)this.pb;
+ char[] buffer = new char[charsToRead];
+ for (int i = 0; i < charsToRead; i++)
+ buffer[i] = *pc++;
+ this.pb = (byte*)pc;
+ return new String(buffer, 0, charsToRead);
+ }
+
+ internal string/*!*/ ReadUTF16()
+ {
+ string result = new string((char*)this.pb);
+ this.pb += (result.Length + 1) * 2;
+ return result;
+ }
+
+ internal string/*!*/ ReadASCII(int bytesToRead)
+ {
+ int c = bytesToRead;
+ if (bytesToRead == -1) c = 128; //buffer size
+ byte* pb = this.pb;
+ char[] buffer = new char[c];
+ int j = 0;
+ byte b = 0;
+ Restart:
+ while (j < c)
+ {
+ b = *pb++;
+ if (b == 0) break;
+ buffer[j++] = (char)b;
+ }
+ if (bytesToRead == -1)
+ {
+ if (b != 0)
+ {
+ char[] newBuffer = new char[c *= 2];
+ for (int copy = 0; copy < j; copy++)
+ newBuffer[copy] = buffer[copy];
+ buffer = newBuffer;
+ goto Restart;
+ }
+ this.pb = pb;
+ }
+ else
+ this.pb += bytesToRead;
+ return new String(buffer, 0, j);
+ }
+
+ internal string/*!*/ ReadASCII() { return ReadASCII(-1); }
+ }
+
+#if !ROTOR
+#if !FxCop
+ /// <summary>
+ /// Public only for use by the Framework. Do not use this class.
+ /// Well, if you really really must, use it only if you can tolerate keeping the file locked for at least as long as any Identifier
+ /// derived from the file stays alive.
+ /// </summary>
+ unsafe public sealed class MemoryMappedFile : IDisposable, ISourceTextBuffer
+ {
+#else
+ unsafe sealed class MemoryMappedFile : IDisposable{
+#endif
+ private byte* buffer;
+ private int length;
+
+ public MemoryMappedFile(string fileName)
+ {
+ this.OpenMap(fileName);
+ }
+ ~MemoryMappedFile()
+ {
+ this.CloseMap();
+ }
+ public void Dispose()
+ {
+ this.CloseMap();
+ GC.SuppressFinalize(this);
+ }
+
+ public byte* Buffer
+ {
+ get
+ {
+ Debug.Assert(this.buffer != null);
+ return this.buffer;
+ }
+ }
+ public int Length
+ {
+ get
+ {
+ Debug.Assert(this.buffer != null);
+ return this.length;
+ }
+ }
+#if !FxCop
+ string ISourceText.Substring(int start, int length)
+ {
+ Debug.Assert(false, "Can't use Substring on memory mapped files");
+ return null;
+ }
+ char ISourceText.this[int index]
+ {
+ get
+ {
+ Debug.Assert(false, "Can't access memory mapped files via an indexer, use Buffer");
+ return ' ';
+ }
+ }
+#endif
+ private void OpenMap(string filename)
+ {
+ IntPtr hmap;
+ int length;
+ using (FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ if (stream.Length > Int32.MaxValue)
+ throw new FileLoadException(ExceptionStrings.FileTooBig, filename);
+ length = unchecked((int)stream.Length);
+#if WHIDBEY && !OldWhidbey
+ hmap = CreateFileMapping(stream.SafeFileHandle.DangerousGetHandle(), IntPtr.Zero, PageAccess.PAGE_READONLY, 0, length, null);
+#else
+ hmap = CreateFileMapping(stream.Handle, IntPtr.Zero, PageAccess.PAGE_READONLY, 0, length, null);
+#endif
+ if (hmap == IntPtr.Zero)
+ {
+ int rc = Marshal.GetLastWin32Error();
+ throw new FileLoadException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.CreateFileMappingReturnedErrorCode, rc.ToString()), filename);
+ }
+ }
+ this.buffer = (byte*)MapViewOfFile(hmap, FileMapAccess.FILE_MAP_READ, 0, 0, (IntPtr)length);
+ MemoryMappedFile.CloseHandle(hmap);
+ if (this.buffer == null)
+ {
+ int rc = Marshal.GetLastWin32Error();
+ throw new FileLoadException(String.Format(CultureInfo.CurrentCulture,
+ ExceptionStrings.MapViewOfFileReturnedErrorCode, rc.ToString()), filename);
+ }
+ this.length = length;
+ }
+ private void CloseMap()
+ {
+ if (buffer != null)
+ {
+ UnmapViewOfFile(buffer);
+ buffer = null;
+ }
+ }
+#if !FxCop
+ void ISourceText.MakeCollectible()
+ {
+ }
+#endif
+
+ private enum PageAccess : int { PAGE_READONLY = 0x02 };
+ private enum FileMapAccess : int { FILE_MAP_READ = 0x0004 };
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern IntPtr CreateFileMapping(
+ IntPtr hFile, // handle to file
+ IntPtr lpAttributes, // security
+ PageAccess flProtect, // protection
+ int dwMaximumSizeHigh, // high-order DWORD of size
+ int dwMaximumSizeLow, // low-order DWORD of size
+ string lpName // object name
+ );
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern void* MapViewOfFile(
+ IntPtr hFileMappingObject, // handle to file-mapping object
+ FileMapAccess dwDesiredAccess, // access mode
+ int dwFileOffsetHigh, // high-order DWORD of offset
+ int dwFileOffsetLow, // low-order DWORD of offset
+ IntPtr dwNumberOfBytesToMap // number of bytes to map
+ );
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool UnmapViewOfFile(
+ void* lpBaseAddress // starting address
+ );
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool CloseHandle(
+ IntPtr hObject // handle to object
+ );
+ }
+#endif
+}