<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_地狱之门</title><subtitle type="text">欢迎来到地狱!</subtitle><id>http://feed.cnblogs.com/blog/u/9539/rss</id><updated>2012-02-09T16:42:22Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/9539/rss"/><entry><id>http://www.cnblogs.com/Rex/archive/2012/02/10/2344735.html</id><title type="text">YUKI类型框架库</title><summary type="text">YUKI类型框架库地狱门神(F.R.C.)本框架的目标是建立一个跨平台跨语言的类型系统，并提供对应的序列化支持。本框架的主要用途是将定义好的元数据文件通过代码生成得到各个语言的类型定义和序列化代码。支持的代码生成分成两类：基于对象数据结构的代码生成和基于关系数据结构的代码生成。</summary><published>2012-02-09T16:42:00Z</published><updated>2012-02-09T16:42:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2012/02/10/2344735.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2012/02/10/2344735.html"/><content type="html">&lt;p&gt;Yummy Ultimate Kata Infrastructure (YUKI类型框架库)&lt;br /&gt;&lt;br /&gt;地狱门神(F.R.C.)&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下载 &lt;a href="https://sourceforge.net/projects/fflf/files/"&gt;https://sourceforge.net/projects/fflf/files/&lt;/a&gt; | &lt;a href="http://files.cnblogs.com/Rex/YUKI.rar"&gt;http://files.cnblogs.com/Rex/YUKI.rar&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;SVN地址 &lt;a href="https://fflf.svn.sourceforge.net/svnroot/fflf/trunk/Yuki/"&gt;https://fflf.svn.sourceforge.net/svnroot/fflf/trunk/Yuki/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;1 概论&lt;br /&gt;&lt;br /&gt;本框架的目标是建立一个跨平台跨语言的类型系统，并提供对应的序列化支持。&lt;br /&gt;本框架的主要用途是将定义好的元数据文件通过代码生成得到各个语言的类型定义和序列化代码。&lt;br /&gt;&lt;br /&gt;支持的代码生成分成两类：基于对象数据结构的代码生成和基于关系数据结构的代码生成。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2 基于对象数据结构的代码生成&lt;br /&gt;&lt;br /&gt;基于对象的数据结构是用于存储和通讯用的数据结构。&lt;br /&gt;&lt;br /&gt;基于对象的数据结构是指的由&lt;br /&gt;基元类型(Primitive)&lt;br /&gt;别名(Alias)&lt;br /&gt;记录(Record)&lt;br /&gt;标签联合(TaggedUnion)&lt;br /&gt;枚举(Enum)&lt;br /&gt;客户端方法(ClientCommand)&lt;br /&gt;服务端事件(ServerCommand)&lt;br /&gt;组成的数据结构。&lt;br /&gt;&lt;br /&gt;基元类型 Primitive&lt;br /&gt;没有泛型参数，指由所有相关外部系统均理解的基础类型，如32位有符号整数、字符串等。&lt;br /&gt;&lt;br /&gt;别名 Alias&lt;br /&gt;可有泛型参数，用以表示一个基元类型、别名、记录、标签联合或其泛型特化，以及多元组。&lt;br /&gt;&lt;br /&gt;记录 Record&lt;br /&gt;可有泛型参数，用以表示一个有多个字段的顺序结构。&lt;br /&gt;&lt;br /&gt;标签联合 TaggedUnion&lt;br /&gt;可有泛型参数，用以表示一个有标签和多个字段的选择结构，其实例只表示多个字段中的一个。&lt;br /&gt;&lt;br /&gt;枚举 Enum&lt;br /&gt;没有泛型参数，相当于一个所有字段的类型都是空类型(Unit)的标签联合。&lt;br /&gt;&lt;br /&gt;客户端方法 ClientCommand&lt;br /&gt;没有泛型参数，在通讯中表示由客户端发出的方法，由一个多个字段的顺序结构表示客户端传给服务端的参数，由一个有标签和多个字段的选择结构表示服务端返回给客户端的返回值。&lt;br /&gt;&lt;br /&gt;服务端事件 ServerCommand&lt;br /&gt;没有泛型参数，在通讯中表示由服务端发出的方法，由一个多个字段的顺序结构表示服务端传给客户端的参数。&lt;br /&gt;&lt;br /&gt;元组 Tuple&lt;br /&gt;一个匿名的有多个匿名字段的顺序结构，类型的一种组合方法。&lt;br /&gt;&lt;br /&gt;泛型特化 GenericTypeSpec&lt;br /&gt;一个匿名的数据结构，表示将某个有泛型参数的类型代入参数的结果。&lt;br /&gt;&lt;br /&gt;这部分的代码生成主要分成四个部分：类型定义、二进制序列化、JSON序列化、通讯。&lt;br /&gt;下面列出各语言代码生成支持的部分。&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;类型定义        二进制序列化        JSON序列化      通讯&lt;br /&gt;C&lt;span style="color: #000000;"&gt;#                  &amp;radic;              Firefly库动态支持   &amp;radic;              &amp;radic;&lt;br /&gt;&lt;/span&gt;Java                &amp;times;              &amp;times;                  &amp;times;              &amp;times;&lt;br /&gt;C++2011             &amp;radic;              &amp;radic;                  &amp;times;              &amp;times;&lt;br /&gt;ActionScript        &amp;radic;              &amp;times;                  &amp;radic;              &amp;radic;&lt;br /&gt;Xhtml               &amp;radic;              无需                无需            &amp;radic;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;其中，C#和ActionScript的二进制序列化和C++2011的通讯功能，将会在今后逐步增加。&lt;br /&gt;Java的四项功能也将逐步增加。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3 基于关系数据结构的代码生成&lt;br /&gt;&lt;br /&gt;基于关系的数据结构用于生成数据库创建和数据导入代码。&lt;br /&gt;&lt;br /&gt;基于关系的数据结构是指由&lt;br /&gt;基元类型(Primitive)&lt;br /&gt;记录(Record)&lt;br /&gt;枚举(Enum)&lt;br /&gt;组成的数据结构。&lt;br /&gt;&lt;br /&gt;基元类型 Primitive&lt;br /&gt;没有泛型参数，指由所有相关外部系统均理解的基础类型，如32位有符号整数、字符串等。&lt;br /&gt;&lt;br /&gt;记录 Record&lt;br /&gt;没有泛型参数，表示一个数据表，有多个字段。&lt;br /&gt;&lt;br /&gt;枚举 Enum&lt;br /&gt;没有泛型参数，由若干标签名和对应的整数组成。&lt;br /&gt;&lt;br /&gt;这部分的代码生成主要是SQL的代码生成，目前只支持SQL Server。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4 环境要求&lt;br /&gt;&lt;br /&gt;本框架使用 Visual C# 3.0 编写，开发时需要 Microsoft .Net Framework 4.0 编译器 或 Visual Studio 2010 支持。&lt;br /&gt;本框架运行时需要 Microsoft .Net Framework 4 或 Microsoft .Net Framework 4 Client Profile 运行库支持。&lt;br /&gt;Microsoft .Net Framework 4 (x86/x64，48.1MB)&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe"&gt;http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe&lt;/a&gt;&lt;br /&gt;Microsoft .NET Framework 4 Client Profile (x86，28.8MB)&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/3/1/8/318161B8-9874-48E4-BB38-9EB82C5D6358/dotNetFx40_Client_x86.exe"&gt;http://download.microsoft.com/download/3/1/8/318161B8-9874-48E4-BB38-9EB82C5D6358/dotNetFx40_Client_x86.exe&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5 用户使用协议&lt;br /&gt;&lt;br /&gt;本框架是免费自由软件，所有源代码和可执行程序按照BSD许可证授权，详见License.zh.txt。&lt;br /&gt;本框架的所有文档不按照BSD许可证授权，你可以不经修改的复制、传播这些文档，你还可以引用、翻译这些文档，其他一切权利保留。&lt;br /&gt;&lt;br /&gt;本框架所依赖的Firefly框架的使用协议请参见对应文档。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6 备注&lt;br /&gt;&lt;br /&gt;如果发现了BUG，或者有什么意见或建议，请到以下网址与我联系。&lt;br /&gt;&lt;a href="http://www.cnblogs.com/Rex/Contact.aspx?id=1"&gt;http://www.cnblogs.com/Rex/Contact.aspx?id=1&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Rex/aggbug/2344735.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Rex/archive/2012/02/10/2344735.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Rex/archive/2011/01/02/1924327.html</id><title type="text">在Windows7下玩老游戏花屏的解决办法</title><summary type="text">在Windows7下玩老游戏，如星际争霸，会出现花屏的现象。本文介绍两种方法，来解决这个问题。</summary><published>2011-01-02T15:32:00Z</published><updated>2011-01-02T15:32:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2011/01/02/1924327.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2011/01/02/1924327.html"/><content type="html">&lt;p&gt;在Windows7下玩老游戏花屏的解决办法&lt;/p&gt;&#xD;
&lt;p&gt;地狱门神&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;在Windows7下玩老游戏，如星际争霸，会出现花屏的现象。&lt;/p&gt;&#xD;
&lt;p&gt;这个现象的原因是Win7的DirectDraw的256色调色板的兼容性问题，据说是默认配置下，程序无法获取调色板锁。&lt;/p&gt;&#xD;
&lt;p&gt;一个简单的解决方法是杀掉explorer进程，估计这样就会停止桌面主题修改调色板。&lt;/p&gt;&#xD;
&lt;p&gt;但是这不是一个一劳永逸的办法。&lt;/p&gt;&#xD;
&lt;p&gt;经过在网上搜索，发现有这样一个解决方案。&lt;/p&gt;&#xD;
&lt;p&gt;DirectDraw有一个注册表项，用于开启兼容模式，位于&lt;/p&gt;&#xD;
&lt;p&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DirectDraw\Compatibility&lt;/p&gt;&#xD;
&lt;p&gt;(Win7 x64)&lt;/p&gt;&#xD;
&lt;p&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectDraw\Compatibility&lt;/p&gt;&#xD;
&lt;p&gt;(Win7 x86)&lt;/p&gt;&#xD;
&lt;p&gt;在这个注册表项下添加需要启用兼容模式的exe，如：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Windows Registry Editor Version 5.00&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DirectDraw\Compatibility\StarCraft116]&lt;br /&gt;"Name"="Starcraft.EXE"&lt;br /&gt;"ID"=hex:ca,89,65,49&lt;br /&gt;"Flags"=hex:00,08,00,00&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;(Win7 x64)&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;就可以使得对应的程序运行于兼容模式下。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这三个键值中，Name是程序的文件名，Flags是常量，而ID是程序的时间戳。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;以星际争霸1.161为例，我们可以使用&lt;a href="http://www.ntcore.com/exsuite.php"&gt;CFF Explorer&lt;/a&gt;打开Starcraft.exe，然后在Nt Headers-File Header中找到TimeDateStamp一项，发现其值为496589CA。&lt;/p&gt;&#xD;
&lt;p&gt;将该整数倒过来写作低字节优先的形式(little-endian)，就是ca,89,65,49，这就是注册表中的ID值。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;网上的有解决方案声称HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\DirectDraw\MostRecentApplication下的ID记录的就是上一次运行的游戏的时间戳。&lt;/p&gt;&#xD;
&lt;p&gt;但是我验证的时候发现不一致。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;通过此方法，星际争霸已经可以在我的机器上正常运行。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;此外，还有一种方法是通过Hook掉DirectDraw的函数来完成的，见&lt;/p&gt;&#xD;
&lt;p&gt;&lt;a href="http://sol.gfxile.net/ddhack/"&gt;http://sol.gfxile.net/ddhack/&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;不过这个实现是通过软件方法来进行 索引-&amp;gt;颜色 转换的，没有使用到显卡加速，在运行星际争霸时比较卡。&lt;/p&gt;&#xD;
&lt;p&gt;但这种方法只需要在程序文件夹下放入一个ddraw.dll的文件就可以实现，比较方便。&lt;/p&gt;&#xD;
&lt;p&gt;也许以后会有人通过DirectX或者OpenGL来模拟DirectDraw的功能，能够比较完善的解决这个问题。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Rex/aggbug/1924327.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Rex/archive/2011/01/02/1924327.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Rex/archive/2010/12/05/1896918.html</id><title type="text">手工下载器</title><summary type="text">手工下载器(ManualDownloader) 本程序用于1)作为HTTP代理服务器拦截服务器二进制文件响应对应的请求2)通过HTTP报文手工下载3)下载到已有文件</summary><published>2010-12-05T07:26:00Z</published><updated>2010-12-05T07:26:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2010/12/05/1896918.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2010/12/05/1896918.html"/><content type="html">&lt;p&gt;手工下载器(ManualDownloader)&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;地狱门神(F.R.C.)&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;下载地址：&lt;a href="http://files.cnblogs.com/Rex/ManualDownloader.rar"&gt;http://files.cnblogs.com/Rex/ManualDownloader.rar&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;1 概论&lt;/p&gt;&#xD;
&lt;p&gt;有一个困扰我很久的问题，就是老是有一些网站下载某个东西要验证，导致支持断点续传的下载软件失效，使得一些文件一旦断掉，很难重新连上。&lt;br /&gt;同时，目前的浏览器或者下载软件，一般都没有办法将一个下载的一半的文件手动更换为另一个链接。&lt;br /&gt;为了对付这些问题，我制作了这个程序。&lt;/p&gt;&#xD;
&lt;p&gt;本程序用于&lt;br /&gt;1)作为HTTP代理服务器拦截服务器二进制文件响应对应的请求&lt;br /&gt;2)通过HTTP报文手工下载&lt;br /&gt;3)下载到已有文件&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;2 使用说明&lt;/p&gt;&#xD;
&lt;p&gt;最简单的场景：下载一个文件。&lt;/p&gt;&#xD;
&lt;p&gt;1)捕捉请求&lt;br /&gt;在浏览器中按照浏览到下载文件之前的最后一步。&lt;br /&gt;点Listen，并将浏览器的HTTP代理服务器设置为127.0.0.1，端口为界面上显示的端口。&lt;br /&gt;点Capture。&lt;br /&gt;在浏览器中点击下载文件。&lt;br /&gt;此时应该在Header框中出现对应的HTTP请求头，如果没有出现，多试几次。如果还不出现，请修改代码解决。&lt;br /&gt;出现之后，可以停止Listen。&lt;/p&gt;&#xD;
&lt;p&gt;2)选择文件和下载范围&lt;br /&gt;文件在File框中选择，之后修改Header中的Range字段。&lt;br /&gt;如果文件已经下载到一半，可以按FromFile自动修改Range字段为从文件结束位置开始。&lt;/p&gt;&#xD;
&lt;p&gt;3)下载&lt;br /&gt;点击Download。等待进度结束。如果中间出现错误，需要重新修改Range。&lt;/p&gt;&#xD;
&lt;p&gt;4)检验&lt;br /&gt;点击Verify，软件会自动选取1024个Range，从每个Range的头部取1024字节和文件对比。如果出错，会在最后显示出错的范围。&lt;/p&gt;&#xD;
&lt;p&gt;还可在其他场景中使用，用得来人自然用得来。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;3 环境要求&lt;/p&gt;&#xD;
&lt;p&gt;本程序使用 Visual Basic 10.0 编写，开发时需要 Microsoft .Net Framework 4.0 编译器 或 Visual Studio 2010 支持。&lt;br /&gt;本程序运行时需要 Microsoft .Net Framework 4 或 Microsoft .Net Framework 4 Client Profile 运行库支持。&lt;br /&gt;Microsoft .Net Framework 4 (x86/x64，48.1MB)&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe"&gt;http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe&lt;/a&gt;&lt;br /&gt;Microsoft .NET Framework 4 Client Profile (x86，28.8MB)&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/3/1/8/318161B8-9874-48E4-BB38-9EB82C5D6358/dotNetFx40_Client_x86.exe"&gt;http://download.microsoft.com/download/3/1/8/318161B8-9874-48E4-BB38-9EB82C5D6358/dotNetFx40_Client_x86.exe&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;4 用户使用协议&lt;/p&gt;&#xD;
&lt;p&gt;本程序是免费自由软件，所有源代码和可执行程序按照BSD许可证授权，详见License.zh.txt。&lt;br /&gt;本程序的所有文档不按照BSD许可证授权，你可以不经修改的复制、传播这些文档，你还可以引用、翻译这些文档，其他一切权利保留。&lt;br /&gt;本程序使用的Firefly.Core.dll和Firefly.GUI.dll是萤火虫框架库的一部分，按照Firefly-License.zh.txt授权。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;5 备注&lt;/p&gt;&#xD;
&lt;p&gt;如果发现了BUG，或者有什么意见或建议，请直接跟贴。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Rex/aggbug/1896918.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Rex/archive/2010/12/05/1896918.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Rex/archive/2010/11/18/1880902.html</id><title type="text">使用代码生成建立可扩展序列化器(上)</title><summary type="text">介绍通过代码生成实现可扩展序列化器的方法，避免.Net默认实现带来的代码污染和可定制性缺乏的问题。</summary><published>2010-11-18T08:09:00Z</published><updated>2010-11-18T08:09:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2010/11/18/1880902.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2010/11/18/1880902.html"/><content type="html">&lt;style&gt;&lt;!--&#xD;
	@page { size: 21.59cm 27.94cm; margin-top: 2.54cm; margin-bottom: 2.54cm; margin-left: 3.175cm; margin-right: 3.175cm }&#xD;
	table { border-collapse:collapse; border-spacing:0; empty-cells:show }&#xD;
	td, th { vertical-align:top; font-size:12pt;}&#xD;
	h1, h2, h3, h4, h5, h6 { clear:both }&#xD;
	ol, ul { margin:0; padding:0;}&#xD;
	li { list-style: none; margin:0; padding:0;}&#xD;
	li span.odfLiEnd { clear: both; line-height:0; width:0; height:0; margin:0; padding:0; }&#xD;
	span.footnodeNumber { padding-right:1em; }&#xD;
	* { margin:0; }&#xD;
	.P1 { font-size:10pt; font-family:宋体; }&#xD;
	.P2 { font-size:12pt; font-family:宋体; }&#xD;
	.P3 { font-size:10pt; font-family:宋体; color:#008000; }&#xD;
	.P4 { font-size:10pt; font-family:宋体; color:#2b91af; }&#xD;
	.P5 { font-size:10pt; font-family:宋体; }&#xD;
	.T1 { color:#0000ff; font-size:10pt; }&#xD;
	.T2 { font-size:10pt; }&#xD;
	.T3 { color:#2b91af; font-size:10pt; }&#xD;
	.T4 { color:#a31515; font-size:10pt; }&#xD;
	.T5 { color:#ff0000; font-size:10pt; }&#xD;
	.T6 { color:#008000; font-size:10pt; }&#xD;
	.T7 { color:#6464b9; font-size:10pt; }&#xD;
	&lt;!  ODF styles with no properties representable as CSS&#xD;
--&gt;&lt;/style&gt;&#xD;
&lt;p &gt;使用代码生成建立可扩展序列化器(上)&lt;/p&gt;&#xD;
&lt;p &gt;地狱门神&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;在很多程序中，配置文件和用户数据的保存和读取都是一个需要考虑的问题。&lt;/p&gt;&#xD;
&lt;p &gt;在以前，用户数据经常保存在INI文件中，后来出现了注册表，于是也有保存在注册表中的。&lt;/p&gt;&#xD;
&lt;p &gt;注册表不是一种稳定的方式，不便于用户管理。&lt;/p&gt;&#xD;
&lt;p &gt;INI和注册表都难以保存复杂结构的对象，需要手写很多代码。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;随着XML和.Net的兴起，越来越多的程序使用XML文件来保存用户数据。&lt;/p&gt;&#xD;
&lt;p &gt;不过.Net的内置序列化器System.Xml.Serialization.XmlSerializer是在.Net 2.0之前推出的，对泛型的支持有限。&lt;/p&gt;&#xD;
&lt;p &gt;同时，由于其使用特性来标记数据模型中的类和变量，并需要对象实现IXmlSerializable。这是对数据模型的严重污染，非常不利于程序维护。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;此外，出于性能的考虑，在数据达到一定规模之后，我们必须使用二进制序列化，以加快加载速度。&lt;/p&gt;&#xD;
&lt;p &gt;对于二进制序列化，有很多实现，而且一般都互不兼容。&lt;/p&gt;&#xD;
&lt;p &gt;由于很多二进制格式是已经事先确定的，要实现对这些二进制格式的反序列化和序列化支持，是非常困难的，没有很好的工具解决这个问题，经常需要手工维护读文件和写文件两部分代码。&lt;/p&gt;&#xD;
&lt;p &gt;.Net的默认实现使得类必须实现ISerializable。这和XML序列化的问题是一样的。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;这两种序列化器均难以方便的实现定制功能。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;由于这些问题，我建立了两个全新的可扩展序列化器，并使用相同的基础结构。&lt;/p&gt;&#xD;
&lt;p &gt;设计目标是：&lt;/p&gt;&#xD;
&lt;p &gt;1)可扩展性，二进制序列化应可扩展支持任意二进制格式；&lt;/p&gt;&#xD;
&lt;p &gt;2)性能，不能太慢，对于多次序列化、反序列化，每次不应有较大的性能损失；&lt;/p&gt;&#xD;
&lt;p &gt;3)无污染，不应对模型数据进行任何插入式的标记；&lt;/p&gt;&#xD;
&lt;p &gt;4)可加的版本支持，这一部分应通过可扩展性来实现；&lt;/p&gt;&#xD;
&lt;p &gt;5)自动支持泛型集合，特别是List(T)和Dictionary(TKey, TValue)。&lt;/p&gt;&#xD;
&lt;p &gt;6)自动支持不变类型，即只读的公开属性和构造函数参数匹配的类型，例如KeyValuePair(TKey, TValue)。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;.Net对于泛型的支持不够完整，缺乏泛型&amp;lambda;表达式、泛型委托等语法元素，泛型约束也有很大的限制。&lt;/p&gt;&#xD;
&lt;p &gt;因此，代码生成是唯一的强类型的选择。另一个选择是使用弱类型进行动态绑定，不过感觉性能和类型安全都不能保证，所以不用。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;先上代码。C#的代码请参见附件。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;数据模型如下：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; Name &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; Data &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;()&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ImmutableDataEntry&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; T)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ReadOnly&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Property&lt;/span&gt;&lt;span &gt; Name &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Get&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; NameValue&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Get&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Property&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ReadOnly&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Property&lt;/span&gt;&lt;span &gt; Data &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;T&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Get&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; DataValue&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Get&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Property&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Private&lt;/span&gt;&lt;span &gt; NameValue &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Private&lt;/span&gt;&lt;span &gt; DataValue &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;T&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Sub&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Name &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Data &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;T&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Me&lt;/span&gt;&lt;span &gt;.NameValue = Name&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Me&lt;/span&gt;&lt;span &gt;.DataValue = Data&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Sub&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; DataEntries &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Dictionary&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; ImmutableDataEntries &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Dictionary&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;ImmutableDataEntry&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;()))&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;XML序列化代码如下：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'创建自定义XML序列化器实例&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; mxs &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; Firefly.Mapping.&lt;/span&gt;&lt;span &gt;XmlSerializer&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'创建数据&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; Obj &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Obj.DataEntries.Add(&lt;/span&gt;&lt;span &gt;"DataEntry1"&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;With&lt;/span&gt;&lt;span &gt; {.Name = &lt;/span&gt;&lt;span &gt;"DataEntry1"&lt;/span&gt;&lt;span &gt;, .Data = &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;() {1, 2, 3, 4, 5}})&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Obj.DataEntries.Add(&lt;/span&gt;&lt;span &gt;"DataEntry2"&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;With&lt;/span&gt;&lt;span &gt; {.Name = &lt;/span&gt;&lt;span &gt;"DataEntry2"&lt;/span&gt;&lt;span &gt;, .Data = &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;() {6, 7, 8, 9, 10}})&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Obj.ImmutableDataEntries.Add(&lt;/span&gt;&lt;span &gt;"ImmutableDataEntry1"&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ImmutableDataEntry&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;())(&lt;/span&gt;&lt;span &gt;"ImmutableDataEntry1"&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;() {1, 2, 3, 4, 5}))&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Obj.ImmutableDataEntries.Add(&lt;/span&gt;&lt;span &gt;"ImmutableDataEntry2"&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ImmutableDataEntry&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;())(&lt;/span&gt;&lt;span &gt;"ImmutableDataEntry2"&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;() {6, 7, 8, 9, 10}))&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'XML序列化&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; Element = mxs.Write(Obj)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'XML反序列化&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; RoundTripped = mxs.Read(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;span &gt;)(Element)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'输出到命令行&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; Setting = &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;XmlWriterSettings&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;With&lt;/span&gt;&lt;span &gt; {.Encoding = &lt;/span&gt;&lt;span &gt;Console&lt;/span&gt;&lt;span &gt;.Out.Encoding, .Indent = &lt;/span&gt;&lt;span &gt;True&lt;/span&gt;&lt;span &gt;, .OmitXmlDeclaration = &lt;/span&gt;&lt;span &gt;False&lt;/span&gt;&lt;span &gt;}&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Using&lt;/span&gt;&lt;span &gt; w = &lt;/span&gt;&lt;span &gt;XmlWriter&lt;/span&gt;&lt;span &gt;.Create(&lt;/span&gt;&lt;span &gt;Console&lt;/span&gt;&lt;span &gt;.Out, Setting)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;Element.Save(w)&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Using&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;这样就自动生成以下XML文本：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;?&lt;/span&gt;&lt;span &gt;xml&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;version&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;1.0&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;encoding&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;gb2312&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;?&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;DataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;3&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;4&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;5&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;6&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;7&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;8&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;9&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;10&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;DataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;3&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;4&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;5&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;6&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;7&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;8&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;9&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;10&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;ImmutableDataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;这个文件中，字节数组使用了默认的集合表示，不利于查看和修改，我们可以使用扩展机制来处理这个问题。&lt;/p&gt;&#xD;
&lt;p &gt;两个序列化器均提供三种扩展机制：&lt;/p&gt;&#xD;
&lt;p &gt;1) PutReader|PutWriter，用于提供直接的读写替代，直接操作需要读写的对象和数据流|数据树；&lt;/p&gt;&#xD;
&lt;p &gt;2) PutReaderTranslator|PutWriterTranslator，提供更高层的抽象，用于将需要读写的对象替代成另一种对象，交给序列化器做后续处理；&lt;/p&gt;&#xD;
&lt;p &gt;3) (ReaderResolver|WriterResolver).(ProjectorResolvers|AggregatorResolvers)，提供直接的类型解析替代，但此机制中类型均为运行时类型，编写代码较麻烦。&lt;/p&gt;&#xD;
&lt;p &gt;详细的说明将在后面介绍，这里我们使用2)，即对象替代。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;声明对象替代器：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'用于将字节数组转换为字符串处理&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Private&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ByteArrayCodec&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorRangeTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;(), &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span &gt;'Reader&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorDomainTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;(), &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span &gt;'Writer&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt; TranslateProjectorToProjectorRange(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; D)(&lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Projector &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;D&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;)) &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;D&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;()) &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorRangeTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;(), &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;).TranslateProjectorToProjectorRange&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt;(k) &lt;/span&gt;&lt;span &gt;Regex&lt;/span&gt;&lt;span &gt;.Split(Projector(k).Trim(&lt;/span&gt;&lt;span &gt;" \t\r\n"&lt;/span&gt;&lt;span &gt;.Descape.ToCharArray), &lt;/span&gt;&lt;span &gt;"( |\t|\r|\n)+"&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;RegexOptions&lt;/span&gt;&lt;span &gt;.ExplicitCapture).Select(&lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt;(s) &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;.Parse(s, Globalization.&lt;/span&gt;&lt;span &gt;NumberStyles&lt;/span&gt;&lt;span &gt;.HexNumber)).ToArray&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt; TranslateProjectorToProjectorDomain(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; R)(&lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Projector &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;R&lt;/span&gt;&lt;span &gt;)) &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;(), &lt;/span&gt;&lt;span &gt;R&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorDomainTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;(), &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;).TranslateProjectorToProjectorDomain&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt;(ba) Projector(&lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;span &gt;.Join(&lt;/span&gt;&lt;span &gt;" "&lt;/span&gt;&lt;span &gt;, (ba.Select(&lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt;(b) b.ToString(&lt;/span&gt;&lt;span &gt;"X2"&lt;/span&gt;&lt;span &gt;)).ToArray)))&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;将对象替代器注册到序列化器：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; mxs &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; Firefly.Mapping.&lt;/span&gt;&lt;span &gt;XmlSerializer&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;mxs.PutReaderTranslator(&lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ByteArrayCodec&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;mxs.PutWriterTranslator(&lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;ByteArrayCodec&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;这样就自动生成以下XML文本：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;?&lt;/span&gt;&lt;span &gt;xml&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;version&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;1.0&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;encoding&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;gb2312&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;?&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;DataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;01 02 03 04 05&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;DataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;06 07 08 09 0A&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndDataEntry&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;DataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry1&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;01 02 03 04 05&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Key&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;ImmutableDataEntry2&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Name&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;06 07 08 09 0A&lt;/span&gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;Data&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;Value&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;KeyValuePairOfStringAndImmutableDataEntryOfArrayOfByte&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span &gt;ImmutableDataEntries&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;/&lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;这里解释一下ByteArrayCodec的作用。&lt;/p&gt;&#xD;
&lt;p &gt;ByteArrayCodec是一个转换字节数组到字符串，并转换回来的类，实现了两个接口：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Interface&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorRangeTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; R, M)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt; TranslateProjectorToProjectorRange(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; D)(&lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Projector &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; Func(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; D, &lt;/span&gt;&lt;span &gt;M&lt;/span&gt;&lt;span &gt;)) &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; Func(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; D, &lt;/span&gt;&lt;span &gt;R&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Interface&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Interface&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorDomainTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; D, M)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt; TranslateProjectorToProjectorDomain(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; R)(&lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Projector &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; Func(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;M&lt;/span&gt;&lt;span &gt;, R)) &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; Func(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;D&lt;/span&gt;&lt;span &gt;, R)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Interface&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;这两个接口，其实是用来约束两个泛型高阶函数。D是输入类型，M是中间类型，R是输出类型。&lt;/p&gt;&#xD;
&lt;p &gt;所谓的Projector，是指投影函数，即一个将原来的对象转换为具有相同信息或者更少信息的对象的函数。&lt;/p&gt;&#xD;
&lt;p &gt;与其相对的，我还定义了一种叫Aggregator的东西，即聚合函数，用于将一个对象的信息加入到另一个已有对象。这个现在暂不描述。&lt;/p&gt;&#xD;
&lt;p &gt;通常我们认为Projector比Aggregator更好书写。&lt;/p&gt;&#xD;
&lt;p &gt;IProjectorToProjectorRangeTranslator，就是用来将一个Projector的值域类型变换到另一个类型，也就是：&lt;/p&gt;&#xD;
&lt;p &gt;IProjectorToProjectorRangeTranslator(D, M, R): Projector(D, M) -&amp;gt; Projector(D, R)&lt;/p&gt;&#xD;
&lt;p &gt;由于.Net不支持返回泛型&amp;lambda;表达式，不能做泛型参数偏特化，因此将本来的三个泛型参数(D, M, R)分成两组(R, M)和(D)，(R, M)定义为接口参数，(D)定义成函数类型参数。&lt;/p&gt;&#xD;
&lt;p &gt;这样我们可以先对(R, M)进行特化，再对(D)进行特化，使得高阶函数的实现与定义域类型D无关。&lt;/p&gt;&#xD;
&lt;p &gt;同样，IProjectorToProjectorDomainTranslator用于将一个Projector的定义域类型变换到另一个类型。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;在ByteArrayCodec中：&lt;/p&gt;&#xD;
&lt;p &gt;TranslateProjectorToProjectorRange用于将Projector(D, String)转化为Projector(D, Byte())，内部做了String到Byte()的转换，使用正则表达式实现；&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;TranslateProjectorToProjectorDomain用于将Projector(Byte(), R)转化为Projector(String, R)，内部做了Byte()到String的转换，使用Byte.ToString(&lt;/span&gt;&lt;span &gt;"X2"&lt;/span&gt;&lt;span &gt;)来完成。&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;下一步，我们需要变更数据模型，但需要保持对已有用户数据的兼容。&lt;/p&gt;&#xD;
&lt;p &gt;这个时候，我们仍然通过对象替代来解决。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;首先变更数据模型，将DataEntry增加一个Attribute字段，原DataEntry更名保留：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'版本1的DataEntry&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; Name &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; Data &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;()&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;'当前版本(版本2)的DataEntry&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; Name &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; Data &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Byte&lt;/span&gt;&lt;span &gt;()&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; Attribute &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;String&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;增加一个对象替代器：&lt;/p&gt;&#xD;
&lt;p &gt;'用于适配DataEntry的版本1和版本2&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntryVersion1To2Translator&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorRangeTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span &gt;'Reader&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorDomainTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span &gt;'Writer&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt; TranslateProjectorToProjectorRange(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; D)(&lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Projector &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;D&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;span &gt;)) &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;D&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorRangeTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;span &gt;).TranslateProjectorToProjectorRange&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt;(DomainValue)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; v1 = Projector(DomainValue)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;With&lt;/span&gt;&lt;span &gt; {.Name = v1.Name, .Data = v1.Data, .Attribute = &lt;/span&gt;&lt;span &gt;"Version1's attribute"&lt;/span&gt;&lt;span &gt;}&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Public&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt; TranslateProjectorToProjectorDomain(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; R)(&lt;/span&gt;&lt;span &gt;ByVal&lt;/span&gt;&lt;span &gt; Projector &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;R&lt;/span&gt;&lt;span &gt;)) &lt;/span&gt;&lt;span &gt;As&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Func&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;R&lt;/span&gt;&lt;span &gt;) &lt;/span&gt;&lt;span &gt;Implements&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;IProjectorToProjectorDomainTranslator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;Of&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntry&lt;/span&gt;&lt;span &gt;, &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;span &gt;).TranslateProjectorToProjectorDomain&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;span &gt;(v2)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; v1 = &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;DataEntryVersion1&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;With&lt;/span&gt;&lt;span &gt; {.Name = v2.Name, .Data = v2.Data}&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span &gt;Return&lt;/span&gt;&lt;span &gt; Projector(v1)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Function&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;End&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Class&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;然后声明两个版本的序列化器，版本1不放入DataEntryVersion1To2Translator，版本2放入DataEntryVersion1To2Translator。&lt;/p&gt;&#xD;
&lt;p &gt;为了在文档中加入版本标志，我们可以使用XML元素的Attribute，在写入后增加标记，如：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; Element = SerializerVersion2.Write(Obj)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Element&lt;/span&gt;&lt;span &gt;.@&amp;lt;&lt;/span&gt;&lt;span &gt;SchemaType&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt; = &lt;/span&gt;&lt;span &gt;"MyDataFormat"&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Element&lt;/span&gt;&lt;span &gt;.@&amp;lt;&lt;/span&gt;&lt;span &gt;Version&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt; = 2&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;在读取的时候，首先读取XElement：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; SchemaType = Element&lt;/span&gt;&lt;span &gt;.@&amp;lt;&lt;/span&gt;&lt;span &gt;SchemaType&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;If&lt;/span&gt;&lt;span &gt; SchemaType &amp;lt;&amp;gt; &lt;/span&gt;&lt;span &gt;"MyDataFormat"&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Then&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Throw&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;New&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;InvalidDataException&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span &gt;"数据不是MYDF格式数据"&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;Dim&lt;/span&gt;&lt;span &gt; Version = &lt;/span&gt;&lt;span &gt;Integer&lt;/span&gt;&lt;span &gt;.Parse(Element&lt;/span&gt;&lt;span &gt;.@&amp;lt;&lt;/span&gt;&lt;span &gt;Version&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;再通过版本号来选择序列化器进行反序列化。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;?&lt;/span&gt;&lt;span &gt;xml&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;version&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;1.0&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;encoding&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;gb2312&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;?&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span &gt;DataObject&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;SchemaType&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;MyDataFormat&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt; &lt;/span&gt;&lt;span &gt;Version&lt;/span&gt;&lt;span &gt;=&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;2&lt;/span&gt;&lt;span &gt;"&lt;/span&gt;&lt;span &gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;这样生成的第二个版本的XML文件就会具有版本号，同时程序可以对各个版本的文件进行兼容。&lt;/p&gt;&#xD;
&lt;p &gt;不会出现手写代码时，由于要兼容，出现多套数据模型或者难以修改数据模型的问题。&lt;/p&gt;&#xD;
&lt;p &gt;详细的代码，以及二进制序列化的示例请参见附件，有VB和C#两个版本的示例代码，和一个简化的库。&lt;/p&gt;&#xD;
&lt;p &gt;简化的库是因为这两个序列化器均是作为&lt;a href="http://www.cnblogs.com/Rex/archive/2008/11/08/1329759.html"&gt;萤火虫汉化框架&lt;/a&gt;的一部分来开发的。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;关于内部实现，主要是通过System.Linq.Expression来进行的，生成的表达式可以被垃圾回收。&lt;/p&gt;&#xD;
&lt;p &gt;实现我将在下篇中描述。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;所有的示例代码均按Public Domain授权，所有的库代码均按BSD协议授权。如果需要在GPL程序中使用，请与我单独联系授权。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;最后携带一点私货，为了解耦我们不要拘泥于面向对象。&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&#xD;
&lt;p &gt;示例下载地址：&lt;/p&gt;&#xD;
&lt;p &gt;&lt;a href="http://files.cnblogs.com/Rex/FireflyForSerializing.rar"&gt;http://files.cnblogs.com/Rex/FireflyForSerializing.rar&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p &gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Rex/aggbug/1880902.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Rex/archive/2010/11/18/1880902.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Rex/archive/2010/09/30/1839537.html</id><title type="text">关于x86下VB、C#、VC中的整数运算需要注意的地方</title><summary type="text">在x86下VB、C#、VC中，整数除法、模运算、移位运算存在一些需要注意的地方。本文描述了这些问题，并给出修正方法。</summary><published>2010-09-30T07:34:00Z</published><updated>2010-09-30T07:34:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2010/09/30/1839537.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2010/09/30/1839537.html"/><content type="html">&lt;p&gt;关于x86下VB、C#、VC中的整数运算需要注意的地方&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;请大家看这段代码：&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;using System;&#xD;
&#xD;
namespace IntegerArithmetic&#xD;
{&#xD;
    class Program&#xD;
    {&#xD;
        static void Main(string[] args)&#xD;
        {&#xD;
            Int32 a = (-1) / 8;                   //0&#xD;
            Int32 b = (-1) % 8;                   //-1&#xD;
            Int32 c = 1 &amp;lt;&amp;lt; 32;                    //1&#xD;
            UInt32 d = 1U &amp;lt;&amp;lt; 32;                  //1&#xD;
  &#xD;
            Int32 e = (-1) / (-8);                //0&#xD;
            Int32 f = (-1) % (-8);                //-1&#xD;
            Int32 g = (-1) &amp;lt;&amp;lt; 32;                 //-1&#xD;
            Int32 h;                              //-1&#xD;
            Int32 i = Math.DivRem(-1, 8, out h);  //0&#xD;
&#xD;
            Console.WriteLine(String.Format("a = {0}", a));&#xD;
            Console.WriteLine(String.Format("b = {0}", b));&#xD;
            Console.WriteLine(String.Format("c = {0}", c));&#xD;
            Console.WriteLine(String.Format("d = {0}", d));&#xD;
            Console.WriteLine(String.Format("e = {0}", e));&#xD;
            Console.WriteLine(String.Format("f = {0}", f));&#xD;
            Console.WriteLine(String.Format("g = {0}", g));&#xD;
            Console.WriteLine(String.Format("h = {0}", h));&#xD;
            Console.WriteLine(String.Format("i = {0}", i));&#xD;
        }&#xD;
    }&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这些结果中不少是反常识的。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;1.整数除法和模运算&lt;/p&gt;&#xD;
&lt;p&gt;在x86下的VB、C#、VC中，整数除法和模运算的定义为&#xD;
&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;x DIV y = TruncToZero(x / y)&#xD;
x MOD y = x - (x DIV y) * y&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;其中&lt;br /&gt;MOD表示模运算(VB中为Mod, C#和C++中为%)；&lt;br /&gt;DIV表示整数除法(VB中为\，C#和C++中为/)；&lt;br /&gt;TruncToZero(r)是指取一个符号与r相同，且绝对值不大于|r|的绝对值最大的整数；&lt;br /&gt;TruncToZero(r) = sign(r) * max{|x|: |x| &amp;lt;= |r|}&lt;br /&gt;/表示实数除法。&lt;/p&gt;&#xD;
&lt;p&gt;这种定义导致的问题是(负数 MOD 正数)的结果为负数。&lt;br /&gt;例如[1]：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;bool is_odd(int n) {&#xD;
    return n % 2 == 1;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这个函数在传入任意负数n时会返回false。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;这几种语言在x86下的表现，可能是编译器考虑到运行效率直接使用x86机器指令IDIV实现的缘故。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;有两种修正的定义，请参阅[1]：&lt;/p&gt;&#xD;
&lt;p&gt;floored division：模得的值的符号与模数一致&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;x DIV y = floor(x / y)&#xD;
x MOD y = x - (x DIV y) * y&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;Euclidean definition: 模得的值始终为正&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;x DIV y = if y &amp;gt; 0&#xD;
              floor(x / y)&#xD;
          else&#xD;
              ceil(x / y)&#xD;
x MOD y = x - (x DIV y) * y&#xD;
&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;我们可以在C#中实现采用floored division方式修正的代码。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;/// &amp;lt;summary&amp;gt;modulo from Knuth's floored division&amp;lt;/summary&amp;gt;&#xD;
public static Int32 Mod(this Int32 a, Int32 m) {&#xD;
    Int32 s = Math.Sign(m);&#xD;
    Int32 pm = Math.Abs(m);&#xD;
    return s * (((s * a) % pm) + pm) % pm;&#xD;
}&#xD;
&#xD;
/// &amp;lt;summary&amp;gt;Knuth's floored division&amp;lt;/summary&amp;gt;&#xD;
public static Int32 Div(this Int32 a, Int32 b)&#xD;
{&#xD;
    return (a - a.Mod(b)) / b;&#xD;
}&#xD;
&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;不过这个方法可能会出现整数溢出。特别是C#默认没有开启整数溢出异常，可能导致计算出错。&lt;br /&gt;下面是没有整数溢出的版本。不过正确是有代价的，逻辑很复杂。&amp;nbsp;&#xD;
&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public static Int32 Mod(this Int32 a, Int32 m)&#xD;
{&#xD;
    Int32 r = a % m;&#xD;
    if (((r &amp;lt; 0) &amp;amp;&amp;amp; (m &amp;gt; 0)) || ((r &amp;gt; 0) &amp;amp;&amp;amp; (m &amp;lt; 0))) { r += m; }&#xD;
    return r;&#xD;
}&#xD;
&#xD;
public static Int32 Div(this Int32 a, Int32 b)&#xD;
{&#xD;
    if (b == 0) { throw new DivideByZeroException(); }&#xD;
    Int32 r = a.Mod(b);&#xD;
    if ((a &amp;gt; 0) &amp;amp;&amp;amp; (r &amp;lt; 0))&#xD;
    {&#xD;
        if (a - Int32.MaxValue &amp;gt; r) { return (a - Math.Abs(b) - r) / b + Math.Sign(b); }&#xD;
    }&#xD;
    else if ((a &amp;lt; 0) &amp;amp;&amp;amp; (r &amp;gt; 0))&#xD;
    {&#xD;
        if (a - Int32.MinValue &amp;lt; r) { return (a + Math.Abs(b) - r) / b - Math.Sign(b); }&#xD;
    }&#xD;
    return (a - r) / b;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;2.移位运算&lt;br /&gt;在x86下的VB、C#、VC中，移位运算的定义为&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;Int32 x, Int32 y&#xD;
x &amp;lt;&amp;lt; y = x SAL (y MOD 32)&#xD;
x &amp;gt;&amp;gt; y = x SAR (y MOD 32)&#xD;
UInt32 x, Int32 y&#xD;
x &amp;lt;&amp;lt; y = x SHL (y MOD 32)&#xD;
x &amp;gt;&amp;gt; y = x SHR (y MOD 32)&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;其中SAR是最高位补原最高位的算术右移，SHR是最高位补0的逻辑右移，SAL、SHL是左移。&lt;br /&gt;y MOD 32 = y AND 0x1F&lt;/p&gt;&#xD;
&lt;p&gt;这应该是x86指令集所决定的。&lt;/p&gt;&#xD;
&lt;p&gt;不过需要注意到VC编译器对常数和变量的处理不一致。&lt;br /&gt;在y为常数且超过0..31的范围时，会出现&amp;ldquo;shift count negative or too big, undefined behavior&amp;rdquo;的警告。&lt;br /&gt;当x也为常数时，常量会按常识正确计算。&lt;/p&gt;&#xD;
&lt;p&gt;修正：&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;public static UInt32 SHL(this UInt32 a, Int32 n)&#xD;
{&#xD;
    if (n &amp;gt;= 32) { return 0; }&#xD;
    if (n &amp;lt; 0) { return a.SHR(-n); }&#xD;
    return a &amp;lt;&amp;lt; n;&#xD;
}&#xD;
&#xD;
public static UInt32 SHR(this UInt32 a, Int32 n)&#xD;
{&#xD;
    if (n &amp;gt;= 32) { return 0; }&#xD;
    if (n &amp;lt; 0) { return a.SHL(-n); }&#xD;
    return a &amp;gt;&amp;gt; n;&#xD;
}&#xD;
&#xD;
public static Int32 SAL(this Int32 a, Int32 n)&#xD;
{&#xD;
    if (n &amp;gt;= 32) { return 0; }&#xD;
    if (n &amp;lt; 0) { return a.SAR(-n); }&#xD;
    return a &amp;lt;&amp;lt; n;&#xD;
}&#xD;
&#xD;
public static Int32 SAR(this Int32 a, Int32 n)&#xD;
{&#xD;
    if (n &amp;gt;= 32)&#xD;
    {&#xD;
        if (Convert.ToBoolean(a &amp;amp; Int32.MinValue))&#xD;
        {&#xD;
            return -1;&#xD;
        }&#xD;
        else&#xD;
        {&#xD;
            return 0;&#xD;
        }&#xD;
    }&#xD;
    if (n &amp;lt; 0) { return a.SAL(-n); }&#xD;
    return a &amp;gt;&amp;gt; n;&#xD;
}&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;3.修正的使用时机&lt;/p&gt;&#xD;
&lt;p&gt;前述的两个修正是完备的。但是不能很好的融入语法，且性能损失是可以预测到的。&lt;br /&gt;因此，下面给出使用的时机判断方法。&lt;/p&gt;&#xD;
&lt;p&gt;1)整数除法和模运算修正的使用时机是：&lt;br /&gt;被除数x和除数y中有一个可能为负数的时候。&lt;/p&gt;&#xD;
&lt;p&gt;通常除数是正数，而被除数有时候是负数。&lt;br /&gt;但是，有时被除数看起来可能会出现负数，却可以较容易的修正为正数表达式，如：&lt;br /&gt;求&#xD;
&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;(n - 1) MOD m&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;其中n为非负整数，m为正整数。&lt;br /&gt;这里n = 0时不修正会出现问题。&lt;br /&gt;但是我们可以写成&#xD;
&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;(n + m -1) MOD m&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这个就不会出现问题。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;2)移位运算修正的使用时机&lt;/p&gt;&#xD;
&lt;p&gt;在移位的位数y为变量时使用。&lt;br /&gt;例如我们需要获得一个掩码。&#xD;
&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;Int32 Mask = 1 &amp;lt;&amp;lt; n - 1&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这里n为Int32变量。&lt;br /&gt;则我们必须使用&#xD;
&lt;/p&gt;&#xD;
&lt;div &gt;&#xD;
&lt;pre &gt;Int32 Mask = 1.SAL(n) - 1&#xD;
&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;否则，在n = 32时会出现问题。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;4.结论&lt;/p&gt;&#xD;
&lt;p&gt;x86下的整数运算远比人们所想象的复杂。&lt;br /&gt;稍不注意，就会导致出现无法察觉的bug。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;参考：&lt;br /&gt;[1] http://en.wikipedia.org/wiki/Modulo_operation&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Rex/aggbug/1839537.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Rex/archive/2010/09/30/1839537.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Rex/archive/2010/09/18/1830291.html</id><title type="text">VolumeViewer</title><summary type="text"/><published>2010-09-18T09:24:00Z</published><updated>2010-09-18T09:24:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2010/09/18/1830291.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2010/09/18/1830291.html"/><content type="html">&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/img/Rex/201009/2010091817220477.png" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/img/Rex/201009/2010091817222358.png" /&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Rex/aggbug/1830291.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Rex/archive/2010/09/18/1830291.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Rex/archive/2010/07/14/1777172.html</id><title type="text">萤火虫框架漩涡文本本地化工具项目</title><summary type="text">萤火虫框架漩涡文本本地化工具项目(Firefly.Eddy)地狱门神(F.R.C.)本项目为萤火虫框架中原有的文本本地化工具及附属插件分离而来，用于进行显示和保存对照的几组本地化文本。本项目的文本本地化工具有一些附属的插件，用于辅助翻译工作。</summary><published>2010-07-14T05:16:00Z</published><updated>2010-07-14T05:16:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2010/07/14/1777172.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2010/07/14/1777172.html"/><content type="html">&lt;p&gt;萤火虫框架漩涡文本本地化工具项目(Firefly.Eddy)&lt;br /&gt;&lt;br /&gt;地狱门神(F.R.C.)&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;下载 &lt;a href="https://sourceforge.net/projects/fflf/files/"&gt;https://sourceforge.net/projects/fflf/files/&lt;/a&gt; | 备用链接 &lt;a href="http://files.cnblogs.com/Rex/Eddy.rar"&gt;http://files.cnblogs.com/Rex/Eddy.rar&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;SVN地址 &lt;a href="https://fflf.svn.sourceforge.net/svnroot/fflf/trunk/Eddy/"&gt;https://fflf.svn.sourceforge.net/svnroot/fflf/trunk/Eddy/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;文本工具示例 &lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;a href="https://sourceforge.net/projects/fflf/files/"&gt;https://sourceforge.net/projects/fflf/files/&lt;/a&gt; |&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt; 备用链接&lt;/span&gt;&lt;/span&gt; &lt;/span&gt;&lt;/span&gt;&lt;a href="http://files.cnblogs.com/Rex/EddyDemo.rar"&gt;http://files.cnblogs.com/Rex/EddyDemo.rar&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;文本工具示例&lt;/span&gt;&lt;/span&gt;.Net 2.0/3.5最终版&lt;/span&gt;&lt;/span&gt; &lt;a href="http://files.cnblogs.com/Rex/TextLocalizerDemo_DotNet2.rar"&gt;http://files.cnblogs.com/Rex/TextLocalizerDemo_DotNet2.rar&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;1 概论&lt;br /&gt;&lt;br /&gt;本项目为萤火虫框架中原有的文本本地化工具及附属插件分离而来，用于进行显示和保存对照的几组本地化文本。&lt;br /&gt;本项目的文本本地化工具有一些附属的插件，用于辅助翻译工作。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2 各程序集功能介绍&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;2.1 主程序(Eddy.exe)&lt;br /&gt;文本本地化工具主程序。&#xD;
&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;2.2 接口库(Eddy.Interfaces.dll)&lt;br /&gt;本库定义了插件的接口。&lt;br /&gt;&lt;br /&gt;2.3 基础库(Eddy.Interfaces.dll)&lt;br /&gt;本库定义了界面插件的接口及其他基础设施。&lt;br /&gt;&lt;br /&gt;2.4 WinForm界面库(Eddy.WinForm.dll)&lt;br /&gt;实现了WinForm制作的主界面。&lt;br /&gt;&lt;br /&gt;2.5 差异比较高亮插件(Eddy.DifferenceHighlighter.dll)&lt;br /&gt;实现差异比较高亮。&lt;br /&gt;&lt;br /&gt;2.6 控制符高亮插件(Eddy.EscapeSequenceHighlighter.dll)&lt;br /&gt;实现控制符高亮。&lt;br /&gt;&lt;br /&gt;2.7 朗读插件(Eddy.Voice.dll)&lt;br /&gt;实现使用TTS进行语音朗读。&lt;br /&gt;需要安装VM Misaki之类的软件后方能使用。&lt;br /&gt;&lt;br /&gt;2.8 查找替换插件(Eddy.FindReplace.dll)&lt;br /&gt;实现查找替换。&lt;br /&gt;&lt;br /&gt;2.9 WQSG文本插件(Eddy.WQSG.dll)&lt;br /&gt;实现对WQSG格式的支持。&lt;br /&gt;&lt;br /&gt;2.10 日汉转换插件(Eddy.J2G.dll)&lt;br /&gt;实现日本汉字到简体汉字的转换。&lt;br /&gt;&lt;br /&gt;2.11 模板翻译插件(Eddy.TemplateTranslate.dll)&lt;br /&gt;实现按模板翻译重复文本。&lt;br /&gt;&lt;br /&gt;2.12 在线词典(Eddy.OnlineDictionary.dll)&lt;br /&gt;实现通过在线网页查词。使用时先选中单词，然后点击对应的词典图标，即可打开相应的网页。&lt;br /&gt;默认支持金山词霸(英汉、汉英)、Yahoo!辞書(日日、日英)、沪江小D(日汉、汉日)、Babylon(多英、英多)。&lt;br /&gt;&lt;br /&gt;2.13 版本控制(Eddy.Version.dll)&lt;br /&gt;实现在程序内调用版本控制软件，更新和提交文本。&lt;br /&gt;默认支持TortoiseSVN，请从http://tortoisesvn.net/downloads.html下载最新的版本(及语言包)。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;3 环境要求&lt;br /&gt;&lt;br /&gt;本项目使用 Visual Basic 10.0 编写，开发时需要 Microsoft .Net Framework 4.0 编译器 或 Visual Studio 2010 支持。&lt;br /&gt;本项目运行时需要 Microsoft .Net Framework 4 或 Microsoft .Net Framework 4 Client Profile 运行库支持。&lt;br /&gt;Microsoft .Net Framework 4 (x86/x64，48.1MB)&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe"&gt;http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Microsoft .NET Framework 4 Client Profile (x86，28.8MB)&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/3/1/8/318161B8-9874-48E4-BB38-9EB82C5D6358/dotNetFx40_Client_x86.exe"&gt;http://download.microsoft.com/download/3/1/8/318161B8-9874-48E4-BB38-9EB82C5D6358/dotNetFx40_Client_x86.exe&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;4 用户使用协议&lt;br /&gt;&lt;br /&gt;以下协议不针对示例(Examples文件夹)：&lt;br /&gt;本项目是免费自由软件，所有源代码和可执行程序按照BSD许可证授权，详见License.zh.txt。&lt;br /&gt;本项目的所有文档不按照BSD许可证授权，你可以不经修改的复制、传播这些文档，你还可以引用、翻译这些文档，其他一切权利保留。&lt;br /&gt;&lt;br /&gt;以下协议针对示例(Examples文件夹)：&lt;br /&gt;本项目的示例进入公有领域，可以随意修改使用。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5 备注&lt;br /&gt;&lt;br /&gt;如果发现了BUG，或者有什么意见或建议，请到以下网址与我联系。&lt;br /&gt;http://www.cnblogs.com/Rex/Contact.aspx?id=1&lt;br /&gt;常见的问题将在今后编制成Q&amp;amp;A。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;-------------------&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;萤火虫框架漩涡文本本地化工具项目示例说明&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;地狱门神(F.R.C.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;示例说明如下，其中部分示例需要运行Build.cmd编译，因此请确保有编译环境：&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;GlyphText&lt;br /&gt;演示图形文本工具的配置和使用。&lt;br /&gt;配置文件为GlyphText\Bin\FFX2.locproj。&lt;br /&gt;GlyphText\FFX2.locproj为有注释的版本，可供参考。&lt;br /&gt;&lt;span style="font-family: Verdana;"&gt;&lt;img src="http://pic002.cnblogs.com/img/Rex/200907/2009070721472445.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;&lt;span style="font-family: Verdana;"&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/6245/2010122923163632.png" alt="" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span style="font-family: Verdana;"&gt;WQSGText&lt;br /&gt;演示WQSG文本工具的配置和使用。&lt;br /&gt;配置文件为WQSGText\Bin\Untitled.locproj。&lt;br /&gt;WQSGText\Untitled.locproj为有注释的版本，可供参考。&lt;br /&gt;&lt;/span&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/6245/2010122923165193.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Plugin&lt;br /&gt;演示文本工具高亮插件的制作。&lt;br /&gt;配置文件为Plugin\Bin\Untitled.locproj。&lt;br /&gt;插件最终形式为Plugin\Bin\LengthHighlighter.dll。&lt;br /&gt;插件源代码在Plugin\Src\LengthHighlighter.vb。&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2010/6245/2010122923170313.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;本框架的示例进入公有领域，可以随意修改使用。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/Rex/aggbug/1777172.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/Rex/archive/2010/07/14/1777172.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/Rex/archive/2009/02/20/1395188.html</id><title type="text">用Java写成的Tiger到JVM编译器</title><summary type="text">用Java写成的Tiger到JVM编译器地狱门神源代码http://files.cnblogs.com/Rex/TigerCompiler.rar</summary><published>2009-02-20T14:33:00Z</published><updated>2009-02-20T14:33:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2009/02/20/1395188.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2009/02/20/1395188.html"/></entry><entry><id>http://www.cnblogs.com/Rex/archive/2009/02/20/1395173.html</id><title type="text">魔王的反击</title><summary type="text">魔王的反击爪哇之角小组2008-07一般的空战游戏都是你控制一架小型战斗机，通过战斗获得武器等级提升，然后于关卡中的BOSS战机进行战斗，BOSS通常都是行动模式单一，但火力强劲的家伙，换句话说就是四肢发达，头脑简单，闪避敌人的子弹是通常战机中的首要技巧。本作品突破传统空战游戏，采用大逆转思路，将玩家与AI逆转，玩家在游戏中扮演普通空战中的BOSS机体，而你的对手则是一部（或多部）由AI控制的普通...</summary><published>2009-02-20T14:04:00Z</published><updated>2009-02-20T14:04:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2009/02/20/1395173.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2009/02/20/1395173.html"/></entry><entry><id>http://www.cnblogs.com/Rex/archive/2008/11/08/1329759.html</id><title type="text">萤火虫框架</title><summary type="text">萤火虫框架(Firefly)地狱门神(F.R.C.)本类库集成了游戏修改中常常需要用到的一些工具和工具类。</summary><published>2008-11-08T11:16:00Z</published><updated>2008-11-08T11:16:00Z</updated><author><name>地狱门神</name><uri>http://www.cnblogs.com/Rex/</uri></author><link rel="alternate" href="http://www.cnblogs.com/Rex/archive/2008/11/08/1329759.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/Rex/archive/2008/11/08/1329759.html"/></entry></feed>
