记录

记录.
    internal interface IBinaryXmlElement
    {
        
void Read (BinaryXmlReader reader);
        
void Write (BinaryXmlWriter writer);
    }

using System;
using System.Collections;

internal class BinaryXmlTypeMap
    {
        Hashtable types 
= new Hashtable ();
        Hashtable names 
= new Hashtable ();
        
        
public BinaryXmlTypeMap ()
        {
        }
        
        
public BinaryXmlTypeMap (params Type[] types)
        {
            
foreach (Type t in types)
                RegisterType (t);
        }
        
        
public void RegisterType (Type type)
        {
            RegisterType (type, type.Name);
        }
        
        
public void RegisterType (Type type, string name)
        {
            names [type] 
= name;
            types [name] 
=  type;
        }
        
        
public string GetTypeName (object ob)
        {
            
string s = (string) names [ob.GetType ()];
            
if (s == null)
                
throw new InvalidOperationException ("Type not registered: " + ob.GetType ());
            
return s;
        }
        
        
public IBinaryXmlElement CreateObject (string typeName)
        {
            Type t 
= (Type) types [typeName];
            
if (t == null)
                
return null;
            
return (IBinaryXmlElement) Activator.CreateInstance (t,true);
        }
    }


using System;
using System.Collections;
using System.Text;
using System.IO;

internal class BinaryXmlReader
    {
        BinaryReader reader;
        
        
internal const byte TagBeginElement = 1;
        
internal const byte TagEndElement = 2;
        
internal const byte TagValue = 4;
        
        
internal const byte TagObject = 5;
        
internal const byte TagObjectArray = 6;
        
internal const byte TagObjectDictionary = 7;
        
internal const byte TagObjectNull = 8;
        
        
byte currentType;
        
string currentName;
        ArrayList stringTable 
= new ArrayList ();
        BinaryXmlTypeMap typeMap;
        
object contextData;
        
bool ignoreDesc;
        
        
public BinaryXmlReader (Stream stream, BinaryXmlTypeMap typeMap)
        {
            reader 
= new BinaryReader (stream);
            
this.typeMap = typeMap;
            ReadNext ();
        }
        
        
public BinaryXmlTypeMap TypeMap {
            
get { return typeMap; }
            
set { typeMap = value; }
        }
        
        
public object ContextData {
            
get { return contextData; }
            
set { contextData = value; }
        }
        
        
// Returns 'true' if description data must be ignored when reading the contents of a file
        public bool IgnoreDescriptionData {
            
get { return ignoreDesc; }
            
set { ignoreDesc = value; }
        }
        
        
void ReadNext ()
        {
            
int b = reader.BaseStream.ReadByte ();
            
if (b == -1) {
                currentType 
= TagBeginElement;
                
return;
            }
            currentType 
= (byte) b;
            
if (currentType == TagBeginElement || currentType == TagValue)
                currentName 
= ReadString ();
        }
        
        
string ReadString ()
        {
            
// The first integer means:
            
// >=0: string of the specified length
            
// -1: null string
            
// <-1: a string from the string table
            
            
int len = reader.ReadInt32 ();
            
if (len == -1)
                
return null;
            
if (len < -1)
                
return (string) stringTable [-(len + 2)];

            
byte[] bytes = new byte [len];
            
int n = 0;
            
while (n < len)
                n 
+= reader.Read (bytes, n, len - n); 
            
string s = Encoding.UTF8.GetString (bytes);
            stringTable.Add (s);
            
return s;
        }
        
        
public string LocalName {
            
get { return currentName; }
        }
        
        
public bool IsElement {
            
get { return currentType == TagBeginElement; }
        }
        
        
public bool IsValue {
            
get { return currentType == TagValue; }
        }
        
        TypeCode ReadValueType (TypeCode type)
        {
            
if (currentType != TagValue)
                
throw new InvalidOperationException ("Reader not positioned on a value.");
            TypeCode t 
= (TypeCode) reader.ReadByte ();
            
if (t != type && type != TypeCode.Empty)
                
throw new InvalidOperationException ("Invalid value type. Expected " + type + ", found " + t);
            
return t;
        }
        
        
public string ReadStringValue (string name)
        {
            
if (!SkipToValue (name))
                
return null;
            
return ReadStringValue ();
        }
        
        
public string ReadStringValue ()
        {
            
if (currentType != TagValue)
                
throw new InvalidOperationException ("Reader not positioned on a value.");
                
            TypeCode t 
= (TypeCode) reader.ReadByte ();
            
if (t == TypeCode.Empty) {
                ReadNext ();
                
return null;
            }
            
if (t != TypeCode.String)
                
throw new InvalidOperationException ("Invalid value type. Expected String, found " + t);
            
            
string s = ReadString ();
            ReadNext ();
            
return s;
        }
        
        
public bool ReadBooleanValue (string name)
        {
            
if (!SkipToValue (name))
                
return false;
            
return ReadBooleanValue ();
        }
        
        
public bool ReadBooleanValue ()
        {
            ReadValueType (TypeCode.Boolean);
            
bool value = reader.ReadBoolean ();
            ReadNext ();
            
return value;
        }
        
        
public char ReadCharValue (string name)
        {
            
if (!SkipToValue (name))
                
return (char)0;
            
return ReadCharValue ();
        }
        
        
public char ReadCharValue ()
        {
            ReadValueType (TypeCode.Char);
            
char value = reader.ReadChar ();
            ReadNext ();
            
return value;
        }
        
        
public byte ReadByteValue (string name)
        {
            
if (!SkipToValue (name))
                
return (byte)0;
            
return ReadByteValue ();
        }
        
        
public byte ReadByteValue ()
        {
            ReadValueType (TypeCode.Byte);
            
byte value = reader.ReadByte ();
            ReadNext ();
            
return value;
        }
        
        
public short ReadInt16Value (string name)
        {
            
if (!SkipToValue (name))
                
return (short)0;
            
return ReadInt16Value ();
        }
        
        
public short ReadInt16Value ()
        {
            ReadValueType (TypeCode.Int16);
            
short value = reader.ReadInt16 ();
            ReadNext ();
            
return value;
        }
        
        
public int ReadInt32Value (string name)
        {
            
if (!SkipToValue (name))
                
return 0;
            
return ReadInt32Value ();
        }
        
        
public int ReadInt32Value ()
        {
            ReadValueType (TypeCode.Int32);
            
int value = reader.ReadInt32 ();
            ReadNext ();
            
return value;
        }
        
        
public long ReadInt64Value (string name)
        {
            
if (!SkipToValue (name))
                
return (long)0;
            
return ReadInt64Value ();
        }
        
        
public long ReadInt64Value ()
        {
            ReadValueType (TypeCode.Int64);
            
long value = reader.ReadInt64 ();
            ReadNext ();
            
return value;
        }
        
        
public DateTime ReadDateTimeValue (string name)
        {
            
if (!SkipToValue (name))
                
return DateTime.MinValue;
            
return ReadDateTimeValue ();
        }
        
        
public DateTime ReadDateTimeValue ()
        {
            ReadValueType (TypeCode.DateTime);
            DateTime value 
= new DateTime (reader.ReadInt64 ());
            ReadNext ();
            
return value;
        }
        
        
public object ReadValue (string name)
        {
            
if (!SkipToValue (name))
                
return null;
            
return ReadValue ();
        }
        
        
public object ReadValue ()
        {
            
object res = ReadValueInternal ();
            ReadNext ();
            
return res;
        }
        
        
public object ReadValue (string name, object targetInstance)
        {
            
if (!SkipToValue (name))
                
return null;
            
return ReadValue (targetInstance);
        }
        
        
public object ReadValue (object targetInstance)
        {
            TypeCode t 
= (TypeCode) reader.ReadByte ();
            
if (t == TypeCode.Empty) {
                ReadNext ();
                
return null;
            }
            
if (t != TypeCode.Object)
                
throw new InvalidOperationException ("Invalid value type. Expected Object, found " + t);
            
            
object res = ReadObject (targetInstance);
            ReadNext ();
            
return res;
        }
        
        
object ReadValueInternal ()
        {
            TypeCode t 
= (TypeCode) reader.ReadByte ();
            
if (t == TypeCode.Empty)
                
return null;
            
return ReadValueInternal (t);
        }
        
        
object ReadValueInternal (TypeCode t)
        {
            
object res;
            
switch (t) {
                
case TypeCode.Boolean: res = reader.ReadBoolean (); break;
                
case TypeCode.Char: res = reader.ReadChar (); break;
                
case TypeCode.SByte: res = reader.ReadSByte (); break;
                
case TypeCode.Byte: res = reader.ReadByte (); break;
                
case TypeCode.Int16: res = reader.ReadInt16 (); break;
                
case TypeCode.UInt16: res = reader.ReadUInt16 (); break;
                
case TypeCode.Int32: res = reader.ReadInt32 (); break;
                
case TypeCode.UInt32: res = reader.ReadUInt32 (); break;
                
case TypeCode.Int64: res = reader.ReadInt64 (); break;
                
case TypeCode.UInt64: res = reader.ReadUInt64 (); break;
                
case TypeCode.Single: res = reader.ReadSingle (); break;
                
case TypeCode.Double: res = reader.ReadDouble (); break;
                
case TypeCode.DateTime: res = new DateTime (reader.ReadInt64 ()); break;
                
case TypeCode.String: res = ReadString (); break;
                
case TypeCode.Object: res = ReadObject (null); break;
                
case TypeCode.Empty: res = nullbreak;
                
default:
                    
throw new InvalidOperationException ("Unexpected value type: " + t);
            }
            
return res;
        }
        
        
bool SkipToValue (string name)
        {
            
do {
                
if ((currentType == TagBeginElement || currentType == TagValue) && currentName == name)
                    
return true;
                
if (EndOfElement)
                    
return false;
                Skip ();
            } 
while (true);
        }

        
public void ReadBeginElement ()
        {
            
if (currentType != TagBeginElement)
                
throw new InvalidOperationException ("Reader not positioned on an element.");
            ReadNext ();
        }
        
        
public void ReadEndElement ()
        {
            
if (currentType != TagEndElement)
                
throw new InvalidOperationException ("Reader not positioned on an element.");
            ReadNext ();
        }
        
        
public bool EndOfElement {
            
get { return currentType == TagEndElement; }
        }
        
        
public void Skip ()
        {
            
if (currentType == TagValue)
                ReadValue ();
            
else if (currentType == TagEndElement)
                ReadNext ();
            
else if (currentType == TagBeginElement) {
                ReadNext ();
                
while (!EndOfElement)
                    Skip ();
                ReadNext ();
            }
        }
        
        
object ReadObject (object targetInstance)
        {
            
byte ot = reader.ReadByte ();
            
if (ot == TagObjectNull) {
                
return null;
            }
            
else if (ot == TagObject) {
                
string tname = ReadString ();
                IBinaryXmlElement ob;
                
if (targetInstance != null) {
                    ob 
= targetInstance as IBinaryXmlElement;
                    
if (ob == null)
                        
throw new InvalidOperationException ("Target instance has an invalid type. Expected an IBinaryXmlElement implementation.");
                } 
else {
                    ob 
= typeMap.CreateObject (tname);
                }
                ReadNext ();
                ob.Read (
this);
                
while (currentType != TagEndElement)
                    Skip ();
                
return ob;
            }
            
else if (ot == TagObjectArray) {
                TypeCode tc 
= (TypeCode) reader.ReadByte ();
                
int len = reader.ReadInt32 ();
                
if (targetInstance != null) {
                    IList list 
= targetInstance as IList;
                    
if (list == null)
                        
throw new InvalidOperationException ("Target instance has an invalid type. Expected an IList implementation.");
                    
for (int n=0; n<len; n++)
                        list.Add (ReadValueInternal ());
                    
return list;
                }
                
else {
                    Array obs 
= CreateArray (tc, len);
                    
for (int n=0; n<len; n++)
                        obs.SetValue (ReadValueInternal (), n);
                    
return obs;
                }
            }
            
else if (ot == TagObjectDictionary) {
                
int len = reader.ReadInt32 ();
                IDictionary table;
                
if (targetInstance != null) {
                    table 
= targetInstance as IDictionary;
                    
if (table == null)
                        
throw new InvalidOperationException ("Target instance has an invalid type. Expected an IDictionary implementation.");
                } 
else {
                    table 
= new Hashtable ();
                }
                
for (int n=0; n<len; n++) {
                    
object key = ReadValueInternal ();
                    
object val = ReadValueInternal ();
                    table [key] 
= val;
                }
                
return table;
            }
            
else
                
throw new InvalidOperationException ("Unknown object type tag: " + ot);
        }
        
        Array CreateArray (TypeCode t, 
int len)
        {
            
switch (t) {
                
case TypeCode.Boolean: return new bool [len];
                
case TypeCode.Char: return new Char [len];
                
case TypeCode.SByte: return new SByte [len];
                
case TypeCode.Byte: return new Byte [len];
                
case TypeCode.Int16: return new Int16 [len];
                
case TypeCode.UInt16: return new UInt16 [len];
                
case TypeCode.Int32: return new Int32 [len];
                
case TypeCode.UInt32: return new UInt32 [len];
                
case TypeCode.Int64: return new Int64 [len];
                
case TypeCode.UInt64: return new UInt64 [len];
                
case TypeCode.Single: return new Single [len];
                
case TypeCode.Double: return new Double [len];
                
case TypeCode.DateTime: return new DateTime [len];
                
case TypeCode.String: return new String [len];
                
case TypeCode.Object: return new Object [len];
                
default:
                    
throw new InvalidOperationException ("Unexpected value type: " + t);
            }
        }
        
        
const int IndSize = 2;
        
        
public static void DumpFile (string file)
        {
            Console.WriteLine (
"FILE: " + file);
            
using (Stream s = File.OpenRead (file)) {
                BinaryXmlReader r 
= new BinaryXmlReader (s, new BinaryXmlTypeMap ());
                r.Dump (
0);
            }
        }
        
        
public void Dump (int ind)
        {
            
if (currentType == TagValue) {
                Console.Write (
new string (' ', ind) + LocalName + "");
                DumpValue (ind);
                Console.WriteLine ();
            }
            
else if (currentType == TagBeginElement) {
                
string name = LocalName;
                Console.WriteLine (
new string (' ', ind) + "<" + name + ">");
                DumpElement (ind 
+ IndSize);
                Console.WriteLine (
new string (' ', ind) + "</" + name + ">");
            }
        }
        
        
public void DumpElement (int ind)
        {
            ReadNext ();
            
while (currentType != TagEndElement) {
                Dump (ind 
+ IndSize);
                ReadNext ();
            }
        }
        
        
void DumpValue (int ind)
        {
            TypeCode t 
= (TypeCode) reader.ReadByte ();
            
if (t != TypeCode.Object) {
                
object ob = ReadValueInternal (t);
                
if (ob == null) ob = "(null)";
                Console.Write (ob);
            } 
else {
                
byte ot = reader.ReadByte ();
                
switch (ot) {
                    
case TagObjectNull: {
                        Console.Write (
"(null)");
                        
break;
                    }
                    
case TagObject: {
                        
string tname = ReadString ();
                        Console.WriteLine (
"(" + tname + ")");
                        DumpElement (ind 
+ IndSize);
                        
break;
                    }
                    
case TagObjectArray: {
                        TypeCode tc 
= (TypeCode) reader.ReadByte ();
                        
int len = reader.ReadInt32 ();
                        Console.WriteLine (
"(" + tc + "[" + len + "])");
                        
for (int n=0; n<len; n++) {
                            Console.Write (
new string (' ', ind + IndSize) + n + "");
                            DumpValue (ind 
+ IndSize*2);
                            Console.WriteLine ();
                        }
                        
break;
                    }
                    
case TagObjectDictionary: {
                        
int len = reader.ReadInt32 ();
                        Console.WriteLine (
"(IDictionary)");
                        
for (int n=0; n<len; n++) {
                            Console.Write (
new string (' ', ind + IndSize) + "key: ");
                            DumpValue (ind 
+ IndSize*2);
                            Console.WriteLine ();
                            Console.Write (
new string (' ', ind + IndSize) + "val: ");
                            DumpValue (ind 
+ IndSize*2);
                            Console.WriteLine ();
                        }
                        
break;
                    }
                    
default:
                        
throw new InvalidOperationException ("Invalid object tag: " + ot);
                }
            }
        }
    }


using System;
using System.Collections;
using System.Text;
using System.IO;

internal class BinaryXmlWriter
    {
        BinaryWriter writer;
        BinaryXmlTypeMap typeMap;
        Hashtable stringTable 
= new Hashtable ();
        
        
public BinaryXmlWriter (Stream stream, BinaryXmlTypeMap typeMap)
        {
            
this.typeMap = typeMap;
            writer 
= new BinaryWriter (stream);
        }
        
        
public void WriteBeginElement (string name)
        {
            writer.Write (BinaryXmlReader.TagBeginElement);
            WriteString (name);
        }
        
        
public void WriteEndElement ()
        {
            writer.Write (BinaryXmlReader.TagEndElement);
        }
        
        
void WriteValueHeader (string name, TypeCode type)
        {
            writer.Write (BinaryXmlReader.TagValue);
            WriteString (name);
            writer.Write ((
byte) type);
        }
        
        
public void WriteValue (string name, bool b)
        {
            WriteValueHeader (name, TypeCode.Boolean);
            writer.Write (b);
        }
        
        
public void WriteValue (string name, string s)
        {
            WriteValueHeader (name, TypeCode.String);
            WriteString (s);
        }
        
        
public void WriteValue (string name, char value)
        {
            WriteValueHeader (name, TypeCode.Char);
            writer.Write (value);
        }
        
        
public void WriteValue (string name, byte value)
        {
            WriteValueHeader (name, TypeCode.Byte);
            writer.Write (value);
        }
        
        
public void WriteValue (string name, short value)
        {
            WriteValueHeader (name, TypeCode.Int16);
            writer.Write (value);
        }
        
        
public void WriteValue (string name, int value)
        {
            WriteValueHeader (name, TypeCode.Int32);
            writer.Write (value);
        }
        
        
public void WriteValue (string name, long value)
        {
            WriteValueHeader (name, TypeCode.Int64);
            writer.Write (value);
        }
        
        
public void WriteValue (string name, DateTime value)
        {
            WriteValueHeader (name, TypeCode.DateTime);
            writer.Write (value.Ticks);
        }
        
        
public void WriteValue (string name, object ob)
        {
            TypeCode t 
= ob != null ? Type.GetTypeCode (ob.GetType ()) : TypeCode.Empty;
            WriteValueHeader (name, t);
            
if (t != TypeCode.Empty)
                WriteValue (ob, t);
        }
        
        
public void WriteValue (string name, IBinaryXmlElement ob)
        {
            
if (ob == null)
                WriteValueHeader (name, TypeCode.Empty);
            
else {
                WriteValueHeader (name, TypeCode.Object);
                WriteObject (ob);
            }
        }
        
        
void WriteValue (object ob)
        {
            
if (ob == null)
                writer.Write ((
byte) TypeCode.Empty);
            
else {
                TypeCode t 
= Type.GetTypeCode (ob.GetType ());
                writer.Write ((
byte) t);
                WriteValue (ob, t);
            }
        }
        
        
void WriteValue (object ob, TypeCode t)
        {
            
switch (t) {
                
case TypeCode.Boolean: writer.Write ((bool)ob); break;
                
case TypeCode.Char: writer.Write ((char)ob); break;
                
case TypeCode.SByte: writer.Write ((sbyte)ob); break;
                
case TypeCode.Byte: writer.Write ((byte)ob); break;
                
case TypeCode.Int16: writer.Write ((short)ob); break;
                
case TypeCode.UInt16: writer.Write ((ushort)ob); break;
                
case TypeCode.Int32: writer.Write ((int)ob); break;
                
case TypeCode.UInt32: writer.Write ((uint)ob); break;
                
case TypeCode.Int64: writer.Write ((long)ob); break;
                
case TypeCode.UInt64: writer.Write ((ulong)ob); break;
                
case TypeCode.Single: writer.Write ((float)ob); break;
                
case TypeCode.Double: writer.Write ((double)ob); break;
                
case TypeCode.DateTime: writer.Write (((DateTime)ob).Ticks); break;
                
case TypeCode.String: WriteString ((string)ob); break;
                
case TypeCode.Object: WriteObject (ob); break;
                
default:
                    
throw new InvalidOperationException ("Unexpected value type: " + t);
            }
        }
        
        
void WriteObject (object ob)
        {
            
if (ob == null)
                writer.Write (BinaryXmlReader.TagObjectNull);
            
else {
                IBinaryXmlElement elem 
= ob as IBinaryXmlElement;
                
if (elem != null) {
                    writer.Write (BinaryXmlReader.TagObject);
                    WriteString (typeMap.GetTypeName (elem));
                    elem.Write (
this);
                    WriteEndElement ();
                }
                
else if (ob is IDictionary) {
                    IDictionary dict 
= (IDictionary) ob;
                    writer.Write (BinaryXmlReader.TagObjectDictionary);
                    writer.Write (dict.Count);
                    
foreach (DictionaryEntry e in dict) {
                        WriteValue (e.Key);
                        WriteValue (e.Value);
                    }
                }
                
else if (ob is ICollection) {
                    ICollection col 
= (ICollection) ob;
                    writer.Write (BinaryXmlReader.TagObjectArray);
                    
if (ob is Array)
                        writer.Write ((
byte) Type.GetTypeCode (ob.GetType().GetElementType ()));
                    
else
                        writer.Write ((
byte) TypeCode.Object);
                    writer.Write (col.Count);
                    
foreach (object e in col) {
                        WriteValue (e);
                    }
                }
                
else
                    
throw new InvalidOperationException ("Invalid object type: " + ob.GetType ());
            }
        }
        
        
void WriteString (string s)
        {
            
if (s == null)
                writer.Write (
-1);
            
else {
                
object ind = stringTable [s];
                
if (ind == null) {
                    stringTable.Add (s, stringTable.Count);
                    
byte[] bytes = Encoding.UTF8.GetBytes (s);
                    writer.Write (bytes.Length);
                    writer.Write (bytes);
                } 
else {
                    
// +2 because -1 is reserved for null, and 0 is considered positive
                    writer.Write (-((int)ind + 2));
                }
            }
        }
    }









转载于:https://www.cnblogs.com/QFW/archive/2007/09/17/896123.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值