⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmlexporter.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 3 页
字号:
namespace Perst.Impl    
{
    using System;
    using System.Reflection;
    using System.Diagnostics;
    using System.Text;
    using System.IO;
    using Perst;

    public class XMLExporter
    {
        public XMLExporter(StorageImpl storage, System.IO.StreamWriter writer)
        {
            this.storage = storage;
            this.writer = writer;
        }
		
        public virtual void  exportDatabase(int rootOid)
        {
            if (storage.encoding != null) 
            { 
                writer.Write("<?xml version=\"1.0\" encoding=\"" + storage.encoding + "\"?>\n");
            }
            else
            {
                writer.Write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
            }
            writer.Write("<database root=\"" + rootOid + "\">\n");
            exportedBitmap = new int[(storage.currIndexSize + 31) / 32];
            markedBitmap = new int[(storage.currIndexSize + 31) / 32];
            markedBitmap[rootOid >> 5] |= 1 << (rootOid & 31);
            int nExportedObjects;
            do 
            {
                nExportedObjects = 0;
                for (int i = 0; i < markedBitmap.Length; i++)
                {
                    int mask = markedBitmap[i];
                    if (mask != 0)
                    {
                        for (int j = 0, bit = 1; j < 32; j++, bit <<= 1)
                        {
                            if ((mask & bit) != 0)
                            {
                                int oid = (i << 5) + j;
                                exportedBitmap[i] |= bit;
                                markedBitmap[i] &= ~ bit;
                                byte[] obj = storage.get(oid);
                                int typeOid = ObjectHeader.getType(obj, 0);
                                ClassDescriptor desc = storage.findClassDescriptor(typeOid);
                                string name = desc.name;
#if USE_GENERICS
                                if (typeof(Btree).IsAssignableFrom(desc.cls)) 
                                {
                                    Type t = desc.cls.GetGenericTypeDefinition();
                                    if (t == typeof(Btree<,>) || t == typeof(BitIndex<>)) 
                                    { 
                                        exportIndex(oid, obj, name);
                                    }
                                    else if (t == typeof(PersistentSet<>))
                                    {
                                         exportSet(oid, obj, name);
                                    }
                                    else if (t == typeof(BtreeFieldIndex<,>))
                                    {
                                         exportFieldIndex(oid, obj, name);
                                    }
                                    else if (t == typeof(BtreeMultiFieldIndex<>))
                                    {
                                        exportMultiFieldIndex(oid, obj, name);
                                    }
                                    else if (t == typeof(BtreeCompoundIndex<>))
                                    {
                                        exportCompoundIndex(oid, obj, name);
                                    }
                                }
#else
                                if (desc.cls == typeof(Btree) || desc.cls == typeof(BitIndexImpl)) 
                                {
                                    exportIndex(oid, obj, name);
                                }
                                else if (desc.cls == typeof(PersistentSet))
                                {
                                    exportSet(oid, obj, name);
                                }
                                else if (desc.cls == typeof(BtreeFieldIndex))
                                {
                                    exportFieldIndex(oid, obj, name);
                                }
                                else if (desc.cls == typeof(BtreeMultiFieldIndex))
                                {
                                    exportMultiFieldIndex(oid, obj, name);
                                }
                                else if (desc.cls == typeof(BtreeCompoundIndex))
                                {
                                    exportCompoundIndex(oid, obj, name);
                                }
#endif
                                else
                                {
                                    String className = exportIdentifier(desc.name);
                                    writer.Write(" <" + className + " id=\"" + oid + "\">\n");
                                    exportObject(desc, obj, ObjectHeader.Sizeof, 2);
                                    writer.Write(" </" + className + ">\n");
                                }
                                nExportedObjects += 1;
                            }
                        }
                    }
                }
            }
            while (nExportedObjects != 0);
            writer.Write("</database>\n");
        }
		
        internal String exportIdentifier(String name) 
        { 
            name = name.Replace('+', '-');
#if USE_GENERICS
            name = name.Replace("`", ".1");
            name = name.Replace(",", ".2");
            name = name.Replace("[", ".3");
            name = name.Replace("]", ".4");
            name = name.Replace("=", ".5");
#endif
            return name;
        }

        Btree createBtree(int oid, byte[] data) 
        {
            Btree btree = storage.createBtreeStub(data, 0);
            storage.assignOid(btree, oid);
            return btree;
        }

        internal void exportSet(int oid, byte[] data, string name) 
        { 
            Btree btree = createBtree(oid, data);
            name = exportIdentifier(name);
            writer.Write(" <" + name + " id=\"" + oid + "\">\n");
            btree.export(this);
            writer.Write(" </" + name + ">\n");
        }

        internal void  exportIndex(int oid, byte[] data, string name)
        {
            Btree btree = createBtree(oid, data);
            name = exportIdentifier(name);
            writer.Write(" <" + name + " id=\"" + oid + "\" unique=\"" + (btree.IsUnique ? '1' : '0') 
                + "\" type=\"" + btree.FieldType + "\">\n");
            btree.export(this);
            writer.Write(" </" + name + ">\n");
        }
		
        internal void  exportFieldIndex(int oid, byte[] data, string name)
        {
            Btree btree = createBtree(oid, data);
            name = exportIdentifier(name);
            writer.Write(" <" + name + " id=\"" + oid + "\" unique=\"" + (btree.IsUnique?'1':'0') + "\" class=");
            int offs = exportString(data, btree.HeaderSize);
            writer.Write(" field=");
            offs = exportString(data, offs);
            writer.Write(" autoinc=\"" + Bytes.unpack8(data, offs) + "\">\n");
            btree.export(this);
            writer.Write(" </" + name + ">\n");
        }
		
        internal void exportMultiFieldIndex(int oid, byte[] data, string name) 
        { 
            Btree btree = createBtree(oid, data);
            name = exportIdentifier(name);
            writer.Write(" <" + name + " id=\"" + oid + "\" unique=\"" + (btree.IsUnique ? '1' : '0') 
                + "\" class=");
            int offs = exportString(data, btree.HeaderSize);
            int nFields = Bytes.unpack4(data, offs);
            offs += 4;
            for (int i = 0; i < nFields; i++) 
            { 
                writer.Write(" field" + i + "=");
                offs = exportString(data, offs);
            }
            writer.Write(">\n");
            int nTypes = Bytes.unpack4(data, offs);
            offs += 4;
            compoundKeyTypes = new ClassDescriptor.FieldType[nTypes];
            for (int i = 0; i < nTypes; i++) 
            { 
                compoundKeyTypes[i] = (ClassDescriptor.FieldType)Bytes.unpack4(data, offs);
                offs += 4;
            }
            btree.export(this); 
            compoundKeyTypes = null;
            writer.Write(" </" + name + ">\n");
        }

        internal void exportCompoundIndex(int oid, byte[] data, string name) 
        { 
            Btree btree = createBtree(oid, data);
            name = exportIdentifier(name);
            writer.Write(" <" + name + " id=\"" + oid + "\" unique=\"" + (btree.IsUnique ? '1' : '0') + "\"");
            int offs = btree.HeaderSize;
            int nTypes = Bytes.unpack4(data, offs);
            offs += 4;
            compoundKeyTypes = new ClassDescriptor.FieldType[nTypes];
            for (int i = 0; i < nTypes; i++) 
            { 
                ClassDescriptor.FieldType type = (ClassDescriptor.FieldType)Bytes.unpack4(data, offs);
                compoundKeyTypes[i] = type;
                writer.Write(" type" + i + "=\"" + type + "\"");
                offs += 4;
            }
            writer.Write(">\n");
            btree.export(this); 
            compoundKeyTypes = null;
            writer.Write(" </" + name + ">\n");
        }

        int exportKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type) 
        {
            switch (type)
            {
                case ClassDescriptor.FieldType.tpBoolean: 
                    writer.Write(body[offs++] != 0?"1":"0");
                    break;
				
                case ClassDescriptor.FieldType.tpByte: 
                    writer.Write(System.Convert.ToString((byte) body[offs++]));
                    break;
				
                case ClassDescriptor.FieldType.tpSByte: 
                    writer.Write(System.Convert.ToString((sbyte) body[offs++]));
                    break;
				
                case ClassDescriptor.FieldType.tpChar: 
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;
				
                case ClassDescriptor.FieldType.tpShort: 
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;
				
                case ClassDescriptor.FieldType.tpUShort: 
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;
				
                case ClassDescriptor.FieldType.tpInt: 
                    writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs)));
                    offs += 4;
                    break;
				
                case ClassDescriptor.FieldType.tpUInt: 
                case ClassDescriptor.FieldType.tpObject:  
                case ClassDescriptor.FieldType.tpOid:  
                case ClassDescriptor.FieldType.tpEnum:
                    writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs)));
                    offs += 4;
                    break;
				
                case ClassDescriptor.FieldType.tpLong: 
                    writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs)));
                    offs += 8;
                    break;
				
                case ClassDescriptor.FieldType.tpULong: 
                    writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs)));
                    offs += 8;
                    break;
				
                case ClassDescriptor.FieldType.tpFloat: 
                    writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs)));
                    offs += 4;
                    break;
				
                case ClassDescriptor.FieldType.tpDouble: 
                    writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs)));
                    offs += 8;
                    break;
				
                case ClassDescriptor.FieldType.tpGuid:
                    writer.Write(Bytes.unpackGuid(body, offs).ToString());
                    offs += 16;
                    break;

                case ClassDescriptor.FieldType.tpDecimal:
                    writer.Write(Bytes.unpackDecimal(body, offs).ToString());
                    offs += 16;
                    break;

                case ClassDescriptor.FieldType.tpString: 
                    for (int i = 0; i < size; i++)
                    {
                        exportChar((char) Bytes.unpack2(body, offs));
                        offs += 2;
                    }
                    break;
				
                case ClassDescriptor.FieldType.tpArrayOfByte:
                    for (int i = 0; i < size; i++) 
                    { 
                        byte b = body[offs++];
                        writer.Write(hexDigit[(b >> 4) & 0xF]);
                        writer.Write(hexDigit[b & 0xF]);
                    }
                    break;

                case ClassDescriptor.FieldType.tpDate: 
                    writer.Write(Bytes.unpackDate(body, offs).ToString());
                    offs += 8;
                    break;

                default:
                    Debug.Assert(false, "Invalid type");
                    break;
            }              
            return offs;                                            
        }
                                                                    
        void exportCompoundKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type) 
        { 
            Debug.Assert(type == ClassDescriptor.FieldType.tpArrayOfByte);
            int end = offs + size;
            for (int i = 0; i < compoundKeyTypes.Length; i++) 
            { 
                type = compoundKeyTypes[i];
                if (type == ClassDescriptor.FieldType.tpArrayOfByte || type == ClassDescriptor.FieldType.tpString) 
                { 
                    size = Bytes.unpack4(body, offs);
                    offs += 4;
                }
                writer.Write(" key" + i + "=\"");
                offs = exportKey(body, offs, size, type); 
                writer.Write("\"");
            }
            Debug.Assert(offs == end);
        }

        internal void  exportAssoc(int oid, byte[] body, int offs, int size, ClassDescriptor.FieldType type)
        {
            writer.Write("  <ref id=\"" + oid + "\"");
            if ((exportedBitmap[oid >> 5] & (1 << (oid & 31))) == 0)
            {
                markedBitmap[oid >> 5] |= 1 << (oid & 31);
            }
            if (compoundKeyTypes != null) 
            { 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -