Mono源代码学习笔记:Console类(三)

Buffer 类 (public static class)

下面就是 mcs/class/corlib/System/Buffer.cs:

001:  //
002:  // System.Buffer.cs
003:  //
004:  // Authors:
005:  //   Paolo Molaro ([email protected])
006:  //   Dan Lewis ([email protected])
007:  //
008:  // (C) 2001 Ximian, Inc.  http://www.ximian.com
009:  //
010:  
011:  //
012:  // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
013:  //
014:  // Permission is hereby granted, free of charge, to any person obtaining
015:  // a copy of this software and associated documentation files (the
016:  // "Software"), to deal in the Software without restriction, including
017:  // without limitation the rights to use, copy, modify, merge, publish,
018:  // distribute, sublicense, and/or sell copies of the Software, and to
019:  // permit persons to whom the Software is furnished to do so, subject to
020:  // the following conditions:
021:  //
022:  // The above copyright notice and this permission notice shall be
023:  // included in all copies or substantial portions of the Software.
024:  //
025:  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
026:  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
027:  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
028:  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
029:  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
030:  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
031:  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
032:  //
033:  
034:  using System.Runtime.CompilerServices;
035:  using System.Runtime.InteropServices;
036:
037:  namespace System {
038:      [ComVisible (true)]
039:      public static class Buffer {
040:
041:          public static int ByteLength (Array array)
042:          {
043:              // note: the other methods in this class also use ByteLength to test for
044:              // null and non-primitive arguments as a side-effect.
045:  
046:              if (array == null)
047:                  throw new ArgumentNullException ("array");
048:
049:              int length = ByteLengthInternal (array);
050:              if (length < 0)
051:                  throw new ArgumentException (Locale.GetText ("Object must be an array of primitives."));
052:
053:              return length;
054:          }
055:
056:          public static byte GetByte (Array array, int index)
057:          {
058:              if (index < 0 || index >= ByteLength (array))
059:                  throw new ArgumentOutOfRangeException ("index", Locale.GetText(
060:                      "Value must be non-negative and less than the size of the collection."));
061:
062:              return GetByteInternal (array, index);
063:          }
064:
065:          public static void SetByte (Array array, int index, byte value)
066:          {
067:              if (index < 0 || index >= ByteLength (array))
068:                  throw new ArgumentOutOfRangeException ("index", Locale.GetText(
069:                      "Value must be non-negative and less than the size of the collection."));
070:
071:              SetByteInternal (array, index, value);
072:          }
073:
074:          public static void BlockCopy (Array src, int srcOffset, Array dst, int dstOffset, int count)
075:          {
076:              if (src == null)
077:                  throw new ArgumentNullException ("src");
078:
079:              if (dst == null)
080:                  throw new ArgumentNullException ("dst");
081:
082:              if (srcOffset < 0)
083:                  throw new ArgumentOutOfRangeException ("srcOffset", Locale.GetText(
084:                      "Non-negative number required."));
085:
086:              if (dstOffset < 0)
087:                  throw new ArgumentOutOfRangeException ("dstOffset", Locale.GetText (
088:                      "Non-negative number required."));
089:
090:              if (count < 0)
091:                  throw new ArgumentOutOfRangeException ("count", Locale.GetText (
092:                      "Non-negative number required."));
093:
094:              // We do the checks in unmanaged code for performance reasons
095:              bool res = BlockCopyInternal (src, srcOffset, dst, dstOffset, count);
096:              if (!res) {
097:                  // watch for integer overflow
098:                  if ((srcOffset > ByteLength (src) - count) || (dstOffset > ByteLength (dst) - count))
099:                      throw new ArgumentException (Locale.GetText (
100:                          "Offset and length were out of bounds for the array or count is greater than " +
101:                          "the number of elements from index to the end of the source collection."));
102:              }
103:          }
104:
105:          // private
106:          [MethodImplAttribute (MethodImplOptions.InternalCall)]
107:          private extern static int ByteLengthInternal (Array array);
108:
109:          [MethodImplAttribute (MethodImplOptions.InternalCall)]
110:          private extern static byte GetByteInternal (Array array, int index);
111:
112:          [MethodImplAttribute (MethodImplOptions.InternalCall)]
113:          private extern static void SetByteInternal (Array array, int index, int value);
114:
115:          [MethodImplAttribute (MethodImplOptions.InternalCall)]
116:          internal extern static bool BlockCopyInternal (Array src, int src_offset, Array dest, int dest_offset, int count);
117:      }
118:  }

上述源程序定义了 Buffer 类。这是一个公共静态类,用于操作基元类型的数组,数组中的每个基元类型都被视为一系列字节。它的公共成员只有以下四个公共静态方法,这些方法比 System.Array 类中相似的方法提供更好的性能:

  1. BtyeLength: public static,返回指定数组中的字节数。(41 – 54 行)
  2. GetByte: public static,在指定数组中检索指定位置处的字节。(56 – 63 行)
  3. SetByte: public static,将指定的值分配给指定数组中特定位置处的字节。(65 – 72 行)
  4. BlockCopy: public static,将指定数目的字节从起始于特定偏移量的源数组复制到起始于特定偏移量的目标数组。(74 – 103 行)

上述四个方法仅仅是在作一些必要的参数检查后调用下述四个非公共的外部静态方法:

  1. ByteLengthInternal: private extern static (106 – 107 行)
  2. GetByteInternal: private extern static (109 – 110 行)
  3. SetByteInternal: private extern static (112 –114 行)
  4. BlockCopyInternal: internal extern static (115 – 116 行)

上述四个方法都被标记为 [MethodImpl(MethodImplOptions.InternalCall)],也就是说,这四个方法都是对在公共语言运行时本身内部实现的方法的调用。请注意
BlockCopyInternal 方法是 internal 的,而不象其他三个方法那样是 private 的。实际上,在 Console.dll 项目中,BlockCopyInternal 方法在 TermInfoReader.cs 中被调用。而 Buffer 类的四个公共方法在 Console.dll 项目中都没有被调用。

IConsoleDriver 接口 (internal interface)

下面就是 mcs/class/corlib/System/IConsoleDriver.cs:

01:  //
02:  // System.IConsoleDriver
03:  //
04:  // Author:
05:  //    Gonzalo Paniagua Javier ([email protected])
06:  //
07:  // (C) 2005 Novell, Inc. (http://www.novell.com)
08:  //
09:  
10:  // Permission is hereby granted, free of charge, to any person obtaining
11:  // a copy of this software and associated documentation files (the
12:  // "Software"), to deal in the Software without restriction, including
13:  // without limitation the rights to use, copy, modify, merge, publish,
14:  // distribute, sublicense, and/or sell copies of the Software, and to
15:  // permit persons to whom the Software is furnished to do so, subject to
16:  // the following conditions:
17:  //
18:  // The above copyright notice and this permission notice shall be
19:  // included in all copies or substantial portions of the Software.
20:  //
21:  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22:  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23:  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24:  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25:  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26:  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27:  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28:  //
29:  namespace System {
30:      interface IConsoleDriver {
31:          ConsoleColor BackgroundColor { get; set; }
32:          int BufferHeight { get; set; }
33:          int BufferWidth { get; set; }
34:          bool CapsLock { get; }
35:          int CursorLeft { get; set; }
36:          int CursorSize { get; set; }
37:          int CursorTop { get; set; }
38:          bool CursorVisible { get; set; }
39:          ConsoleColor ForegroundColor { get; set; }
40:          bool KeyAvailable { get; }
41:          bool Initialized { get; }
42:          int LargestWindowHeight { get; }
43:          int LargestWindowWidth { get; }
44:          bool NumberLock { get; }
45:          string Title { get; set; }
46:          bool TreatControlCAsInput { get; set; }
47:          int WindowHeight { get; set; }
48:          int WindowLeft { get; set; }
49:          int WindowTop { get; set; }
50:          int WindowWidth { get; set; }
51:
52:          void Init ();
53:          void Beep (int frequency, int duration);
54:          void Clear ();
55:          void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
56:                      int targetLeft, int targetTop, Char sourceChar,
57:                      ConsoleColor sourceForeColor, ConsoleColor sourceBackColor);
58:
59:          ConsoleKeyInfo ReadKey (bool intercept);
60:          void ResetColor ();
61:          void SetBufferSize (int width, int height);
62:          void SetCursorPosition (int left, int top);
63:          void SetWindowPosition (int left, int top);
64:          void SetWindowSize (int width, int height);
65:          string ReadLine ();
66:      }
67:  }

上述源程序定义了 IConsoleDriver 接口。上述源程序第 30 行没有明确指出访问修饰符,那么这个接口默认为 internal 的,只能在本程序集中使用。IConsoleDriver 接口是我在这个系列学习笔记第一篇的末尾指出的六个最核心的类型之一,它规定了所有的控制台都必须实现的基本功能。IConsoleDriver
共定义了 11 个方法,20 个属性,其中 6 个是只读属性。

NullConsoleDriver 类 (internal class)

下面就是 mcs/class/corlib/System/NullConsoleDriver.cs:

001:  //
002:  // System.NullConsoleDriver
003:  //
004:  // Author:
005:  //    Gonzalo Paniagua Javier ([email protected])
006:  //
007:  // (C) 2006 Novell, Inc. (http://www.novell.com)
008:  //
009:  
010:  // Permission is hereby granted, free of charge, to any person obtaining
011:  // a copy of this software and associated documentation files (the
012:  // "Software"), to deal in the Software without restriction, including
013:  // without limitation the rights to use, copy, modify, merge, publish,
014:  // distribute, sublicense, and/or sell copies of the Software, and to
015:  // permit persons to whom the Software is furnished to do so, subject to
016:  // the following conditions:
017:  //
018:  // The above copyright notice and this permission notice shall be
019:  // included in all copies or substantial portions of the Software.
020:  //
021:  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
022:  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
023:  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
024:  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
025:  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
026:  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
027:  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
028:  //
029:  #if !NET_2_1
030:  using System.Runtime.InteropServices;
031:  using System.Text;
032:  namespace System {
033:      class NullConsoleDriver : IConsoleDriver {
034:          public ConsoleColor BackgroundColor {
035:              get { return ConsoleColor.Black; }
036:              set {
037:              }
038:          }
039:
040:          public int BufferHeight {
041:              get { return 0; }
042:              set {}
043:          }
044:
045:          public int BufferWidth {
046:              get { return 0; }
047:              set {}
048:          }
049:
050:          public bool CapsLock {
051:              get { return false; }
052:          }
053:
054:          public int CursorLeft {
055:              get { return 0; }
056:              set {}
057:          }
058:
059:          public int CursorSize {
060:              get { return 0; }
061:              set { }
062:          }
063:
064:          public int CursorTop {
065:              get { return 0; }
066:              set {}
067:          }
068:
069:          public bool CursorVisible {
070:              get { return false; }
071:              set {}
072:          }
073:
074:          public ConsoleColor ForegroundColor {
075:              get { return ConsoleColor.Black; }
076:              set {}
077:          }
078:
079:          public bool KeyAvailable {
080:              get { return false; } // FIXME: throw?
081:          }
082:
083:          public bool Initialized {
084:              get { return true; }
085:          }
086:
087:          public int LargestWindowHeight {
088:              get { return 0; }
089:          }
090:
091:          public int LargestWindowWidth {
092:              get { return 0; }
093:          }
094:
095:          public bool NumberLock {
096:              get { return false; }
097:          }
098:
099:          public string Title {
100:              get { return ""; }
101:              set {}
102:          }
103:
104:          public bool TreatControlCAsInput {
105:              get { return false; }
106:              set {}
107:          }
108:
109:          public int WindowHeight {
110:              get { return 0; }
111:              set {}
112:          }
113:
114:          public int WindowLeft {
115:              get { return 0; }
116:              set {}
117:          }
118:
119:          public int WindowTop {
120:              get { return 0; }
121:              set {}
122:          }
123:
124:          public int WindowWidth {
125:              get { return 0; }
126:              set {}
127:          }
128:
129:          public void Beep (int frequency, int duration)
130:          {
131:          }
132:
133:          public void Clear ()
134:          {
135:          }
136:
137:          public void MoveBufferArea (int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight,
138:                      int targetLeft, int targetTop, Char sourceChar,
139:                      ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
140:          {
141:          }
142:
143:          public void Init ()
144:          {
145:          }
146:
147:          public string ReadLine ()
148:          {
149:              return null;
150:          }
151:
152:          public ConsoleKeyInfo ReadKey (bool intercept)
153:          {
154:              return ConsoleKeyInfo.Empty;
155:          }
156:
157:          public void ResetColor ()
158:          {
159:          }
160:
161:          public void SetBufferSize (int width, int height)
162:          {
163:          }
164:
165:          public void SetCursorPosition (int left, int top)
166:          {
167:          }
168:
169:          public void SetWindowPosition (int left, int top)
170:          {
171:          }
172:
173:          public void SetWindowSize (int width, int height)
174:          {
175:          }
176:      }
177:  }
178:  #endif

上述源程序定义了 NullConsoleDriver 类。整个源程序(除了开头的注释以外)被第 29 行的“#if !NET_2_1” 和第 178 行的“#endif”预处理指令括了起来,表明该类不能用在 Moonlight 中,实际上 Moonlight 是应用于 Web
的,不需要控制台的概念。这里的 NET_2_1 表示 .NET 2.1,而 Moonlight 是基于 .NET 2.1 的,具体请参见:MoonlightNotes

从上述源程序可以看出,该类的所有成员都是 public 的,而且刚好有 31 个成员,仅仅是满足 IConsoleDriver 接口的要求。

第 34 行到第 127 行是 20 个属性,这些属性的 set 方法(如果不是只读属性的话)都是空的,get 方法也仅仅是返回空字符串、零、null、false、true、或者 ConsoleColor.Black。

第 129 行到第 176 行是 11 个方法,这些方法或者是空的,或者仅仅返回 null 或者 ConsoleKeyInfo.Empty。

NullConsoleDriver 类实践了 Null Object 设计模式。

在 Console.dll 项目中,NullConsoleDriver 类仅在 ConsoleDriver.cs 中被使用过一次。

版权声明:本文为博主http://www.zuiniusn.com原创文章,未经博主允许不得转载。

时间: 2024-11-05 16:02:51

Mono源代码学习笔记:Console类(三)的相关文章

Mono源代码学习笔记:Console类(一)

前言 我们知道,Mono 是 .NET Framework 跨平台的开源实现.Mono 的源代码就是金矿,等待我们去挖掘. 目前 Mono 的最新版本是 Mono 2.8.2,可以到 http://ftp.novell.com/pub/mono/sources/mono/ 下载 mono-2.8.2.tar.bz2,文件大小是30MB.可以参阅"在 Ubuntu 10.10 操作系统安装 Mono 2.8.2"一文. 现在,让我们来看看 Mono 是如何实现 .NET Framewor

Mono源代码学习笔记:Console类(四)

NullStream 类 (internal class) 下面就是 mcs/class/corlib/System.IO/NullStream.cs: 01: namespace System.IO 02: { 03: class NullStream : Stream 04: { 05: public override bool CanRead { get { return true; } } 06: public override bool CanSeek { get { return t

Mono源代码学习笔记:Console类(六)

Unix 终端的基础知识 许多 Unix 系统使用终端.但是在今天的许多情况下,终端也许是一个运行终端程序的 PC 机.从历史上来说,不同的生产商提供了大量的硬件终端.Linux 操作系统包含一个环境变量 TERM,用来表示我们正在使用的终端的类型,如下所示: [email protected]:~$ w 16:35:13 up 6 days, 7:36, 2 users, load average: 0.62, 0.34, 0.25 USER TTY FROM [email protected

Mono源代码学习笔记:Console类(五)

CStreamReader 类 (internal class) 下面就是 mcs/class/corlib/System/CStreamReader.cs: 001: // 002: // System.CStreamReader 003: // 004: // Authors: 005: // Dietmar Maurer ([email protected]) 006: // Miguel de Icaza ([email protected]) 007: // Dick Porter (

Mono源码学习笔记:Console类(三)

Buffer 类 (public static class) 以下就是 mcs/class/corlib/System/Buffer.cs: 001: // 002: // System.Buffer.cs 003: // 004: // Authors: 005: // Paolo Molaro ([email protected]) 006: // Dan Lewis ([email protected]) 007: // 008: // (C) 2001 Ximian, Inc. http

Mono源码学习笔记:Console类(四)

NullStream 类 (internal class) 以下就是 mcs/class/corlib/System.IO/NullStream.cs: 01: namespace System.IO 02: { 03: class NullStream : Stream 04: { 05: public override bool CanRead { get { return true; } } 06: public override bool CanSeek { get { return t

C++ Primer 学习笔记_19_类与数据抽象(5)_初始化列表(const和引用成员)、拷贝构造函数

C++ Primer 学习笔记_19_类与数据抽象(5)_初始化列表(const和引用成员).拷贝构造函数  从概念上将,可以认为构造函数分为两个阶段执行: 1)初始化阶段: 2)普通的计算阶段.计算阶段由构造函数函数体中的所有语句组成. 一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 1.对象成员及其初始化 <span style="font-size:14px;">#include <iostream> using namespace std;

C++ Primer 学习笔记_57_类与数据抽象 --管理指针成员

复制控制 --管理指针成员 引言: 包含指针的类需要特别注意复制控制,原因是复制指针时只是复制了指针中的地址,而不会复制指针指向的对象! 将一个指针复制到另一个指针时,两个指针指向同一对象.当两个指针指向同一对象时,可能使用任一指针改变基础对象.类似地,很可能一个指针删除了一对象时,另一指针的用户还认为基础对象仍然存在.指针成员默认具有与指针对象同样的行为. 大多数C++类采用以下三种方法之一管理指针成员: 1)指针成员采取常规指针型行为:这样的类具有指针的所有缺陷但无需特殊的复制控制! 2)类

C++ Primer 学习笔记_55_类与数据抽象 --析构函数

复制控制 --析构函数 引言: 在构造函数中分配了资源之后,需要一个对应操作自动回收或释放资源.析构函数就是这样的一个特殊函数,它可以完成所需的资源回收,作为类构造函数的补充. 1.何时调用析构函数 撤销类对象时会自动调用析构函数: Sales_item *p = new Sales_item; { Sales_item item(*p); //调用复制构造函数 delete p; //调用指针p的析构函数 } //调用对象item的析构函数 动态分配的对象只有在指向该对象的指针被删除时才撤销,