对 MBCS 文本的 QuickSearch 搜索的误搜 节选

October 24, 2006

作者: JIURL
邮箱: thejiurl@gmail.com
主页: http://jiurl.blogsome.com/
http://jiurl.yeah.net/

[前言]

这篇文章是以前写给自己备忘的一个研究文档的节选。

[MBCS]

MBCS: Multi-Byte Character Set
DBCS: Double-Byte Character Set

MBCS 文本中,既可能有1个字节的 Ascii 字符,又可能有2个字节的 DBCS 字符。
硬盘上的大多数文本文件就是以 MBCS 方式来保存的。

[区分大小写的搜索]

QuickSearch 寻找匹配串,是以字节为单位来进行匹配的,
对字节的256个可能值,建立 MoveLenTable[] 表,来计算移动距离,
详细见 QuickSearch.txt 中的介绍。

对于 MBCS 文本来说,这样的匹配结果,可能有误搜,但是肯定没有漏搜。
我们应该去除掉误搜的情况。

会产生 DBCS TrailByte 引起的误搜。

DBCS TrailByte 引起的误搜,一种情况,比如:

szPattern 为 “gabc”
szText 为 “鎔abc xyz”

‘鎔’是一个 DBCS 字符,编码为 0xe6 0x67。
‘g’ 是一个 ASCII 字符,编码为 0x67。

用 szPattern 对 szText 进行区分大小写的搜索,会得到一个匹配,
匹配串从 DBCS 字符 ‘鎔’ 的 TrailByte 开始,
而实际上,并不应该有匹配,所以就出现了误搜。

DBCS TrailByte 引起的误搜,另一种情况,比如:

略。

[不区分大小写的搜索]

对于不区分大小写的搜索,

对于文本中的每个字节,不管它是一个 ascii 字符,还是一个 dbcs 字符的 LeadByte,TrailByte,都当作 ascii 字节来处理,只要它落在了 ascii 英文字母的范围内就进行不区分大小写处理。

由此,可能引起误搜,所以对匹配结果还需要进行误搜处理,去掉误搜的情况即可。

不区分大小写处理,包括:
建立 MoveLenTable[] 的时候,同一个英文字母,大写对应项,和,小写对应项,的值相同。

比较 chFirstPatternChar 的时候,应该既和 chFirstPatternChar 的大写值比较,又和 chFirstPatternChar 小写值比较。

进行串匹配的时候,也应该进行 不区分大小写 的串匹配。

详细实现参考 QuickSearchNotMatchCase() 函数的源码。

对于 MBCS 文本来说,这样的匹配结果,可能有误搜,但是肯定没有漏搜。
我们应该去除掉误搜的情况。

同样存在和 区分大小写的搜索 一样的,DBCS TrailByte 引起的误搜。
除此之外,还存在 不区分大小写 引起的误搜。

不区分大小写 引起的误搜,比如:

szPattern 为 “鎔abc”
szText 为 “鍳abc xyz”

‘鎔’是一个 DBCS 字符,编码为 0xe6 0x67。
‘鍳’是一个 DBCS 字符,编码为 0xe6 0x47。

DBCS 的 TrailByte 本身是一个字符的一部分,不存在大小写问题,但是,
匹配是以字节来进行的,并不知道这个字节是否是一个 DBCS 的 TrailByte,只要看到了这个字节的值落在了英文字母的范围内,就进行不区分大小写的处理,导致了认为 0x67 和 0x47 是匹配的。

用 szPattern 对 szText 进行区分大小写的搜索,会得到一个匹配,
匹配串为”鍳abc”,
而实际上,并不应该有匹配,所以就出现了误搜。

可以看到,只有 szPattern 中含有 DBCS 字符,才可能出现这种误搜。

[误搜的去除]

略。

[误搜的出现几率]

误搜的出现几率是非常小的,这是因为:

不管是两种误搜中的哪种,都是由于 DBCS 字符的 TrailByte 小于 0x80,落在了 ascii 字符的范围内,而本身 DBCS 的 TrailByte 小于 0x80 的字符,都是些不太常用的汉字。

出现 DBCS 字符 TrailByte 小于 0x80 的几率较小,
又碰巧出现 szPattern 和 szText 的误搜的几率就更小了。

gdi显卡驱动节选

作者: JIURL
邮箱: thejiurl@gmail.com
主页: http://jiurl.blogsome.com/
http://jiurl.yeah.net/

[前言]

这篇文章是以前写给自己备忘的一个研究文档的节选。

[gdi 显卡驱动]

显卡驱动将讨论,显卡驱动中支持 gdi 实现的部分。

如果是一个纯 frame buffer 的话,显卡不作任何加速,所有 gdi 的实现都是 win32k 中的代码软件实现,gdi 把 frame buffer 当作一个位图,直接访问,进行相应的绘制。当然,这种情况除非特意设计,否则的话,是不会出现的。

不是纯 frame buffer 的情况,gdi 不直接访问 frame buffer,
显卡硬件实现了某些硬件加速,可能实现了某些 gdi 需要的硬件加速。gdi 中,有硬件加速的,就交给显卡驱动来完成,没有硬件加速的,gdi 软件实现,然后把结果交给显卡驱动来完成显示。

显卡驱动至少需要实现,DrvCopyBits, DrvTextOut 和 DrvStrokePath,其他 gdi 函数可以软件实现,最终调用这几个驱动实现的函数,来把结果写入 frame buffer。

显卡驱动可以实现的 gdi 的功能:
DrvBitBlt
DrvPlgBlt
DrvStretchBlt
DrvStretchBltROP
DrvTextOut
DrvStrokePath
DrvFillPath
DrvStrokeAndFillPath
DrvLineTo
DrvCopyBits
DrvAlphaBlend
DrvGradientFill
DrvTransparentBlt

更多细节可以参考关于 SURFACE, HDC 等的讨论。

[显卡驱动]

显卡驱动(支持gdi部分)相关内容主要在下面的4个文件中:

win32k.sys
VideoPort.sys

disp 驱动 (.dll) (如 vga.dll)
mini port 驱动 (.sys) (如 vga.sys)

win32k.sys 和 VideoPort.sys 是系统文件。
disp 驱动 (.dll) 和 mini port 驱动 (.sys) 是显卡驱动。

[win32k.sys]
gdi 就是在 win32k.sys 中实现的。EngXxx 是在 win32k.sys 中实现的。

[VideoPort.sys]

mini port 驱动 将会调用 VideoPort.sys 导出的函数。
VideoPort.sys 导出的函数,例如:

VideoPortWritePortUlong
VideoPortZeroMemory
VideoPortInitialize

只是做了个简单封装,这样逻辑性更好一些,也使得 mini port 驱动的代码和 平台(体系结构)无关。
比如 VideoPortWritePortUlong,对x86,基本上也就是一条 out 指令。

[mini port 驱动 (.sys)]

查询显卡支持的所有可用的模式,查询和设置当前的显示模式(比如,1280*1024 16位色 刷新率60hz)。
大致也就是完成,对显卡初始化,对显卡的状态进行查询和设置,将寄存器映射到虚拟地址空间,等工作。

也就是一些对应 IOCTL_VIDEO_XXX 的实现的工作。

在 DriverEntry 中,调用 VideoPortInitiaze,设置 DRIVER_OBJECT 的 MajorFunction[],IoCreateDevice 创建 DEVICE_OBJECT。

[disp 驱动 (.dll)]

显卡驱动中最重要的部分。显卡驱动的主要工作在 “disp 驱动 (.dll)” 中完成。

它知道显卡硬件的细节,知道如何向显卡发命令,来让显卡硬件完成某个工作。

它将直接访问显卡的寄存器,来向显卡发命令,或者读取显卡的情况。可能显卡的一块寄存器最终映射到虚拟地址空间的话,那么驱动中就直接访问这部分虚拟地址空间。也可能还需要访问 io 端口。

DrvXxx 函数就是由 “disp 驱动 (.dll)” 提供的。

“disp 驱动 (.dll)” 中会调用 EngXxx。比如 EngCreateDeviceSurface,EngDeviceIoControl。也可能调用 EngXxx 来帮助完成某项绘制功能。

注意:disp 驱动 (.dll) 的入口点为 DrvEnableDriver。它将被载入系统地址空间。

汉朝定都于长安的原因

October 22, 2006

公元前202年(两千二百多年前),汉朝开国皇帝刘邦定都于长安。

大概是这么回事,当时有两派意见。一派主要是俩人:娄敬,张良,主张定都于长安。另一派是好多大臣,主张定都于洛阳。

这事发生在洛阳。
最开头是,娄敬求见刘邦,跟刘邦说了一大套,怂恿刘邦定都长安。
我估计,一来,刘邦跟娄敬不熟,有点半信半疑。二来,刘邦是大风大浪过来的人,可能还是比较爱听大伙都说两句。
于是,就跟群臣说这事,大伙的意思是定都洛阳。
据司马迁推测,因为这帮人大多不是长安附近的,定都洛阳离这伙人家近点,所以他们都起哄让定都洛阳。我估计,这可能也是个原因。他们嘴上说的是:周朝定都洛阳,痛快了好几百年,秦朝定都长安,只过了二世的瘾。我估计,很多人可能也是真诚的。
刘邦可能觉得两边说的都有点道理,就犹豫不决。
张良就跟刘邦说了一通,基本上也是老词,跟娄敬那套差不多,让他定都长安。刘邦立刻就决定定都长安了。我估计,一来,刘邦是大风大浪过来的人,一听就知道娄敬,张良说的也在理。二来,刘邦跟张良那是太熟了,知道这就是一个人精啊,听他的,保准吃不了亏。所以,这事就这么定了。

娄敬,张良,他们说长安有各种的好处。所以,刘邦最终决定,定都于长安。
他们是怎么说的?长安到底有什么好处呢?。。。你猜。。。

另外:
史籍资料,未必可信,所以应该首先考证它的可信度,但是,咱们没那个功夫,就算了。凭感觉,司马迁的这部《史记》,可信度应该还是比较高的。

所有内容来源于:
《史记·留候世家》
《史记·刘敬叔孙通列传》

http://jiurl.blogsome.com/