Пример #1
0
        internal int exportObject(ClassDescriptor desc, byte[] body, int offs, int indent)
        {
            ClassDescriptor.FieldDescriptor[] all = desc.allFields;
			
            for (int i = 0, n = all.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = all[i];
                FieldInfo f = fd.field;
                indentation(indent);
                String fieldName = exportIdentifier(fd.fieldName);
                writer.Write("<" + fieldName + ">");
                switch (fd.type)
                {
#if NET_FRAMEWORK_20
                    case ClassDescriptor.FieldType.tpNullableBoolean: 
                        writer.Write(body[offs++] == 0 ? "null" : body[offs++] != 0?"1":"0");
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableByte: 
                        writer.Write(body[offs++] == 0 ? "null" : System.Convert.ToString((byte) body[offs++]));
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableSByte: 
                        writer.Write(body[offs++] == 0 ? "null" : System.Convert.ToString((sbyte) body[offs++]));
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableChar: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                            offs += 2;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableShort: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                            offs += 2;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableUShort: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                            offs += 2;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableInt: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs)));
                            offs += 4;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableUInt: 
                    case ClassDescriptor.FieldType.tpNullableEnum:
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs)));
                            offs += 4;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableLong: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs)));
                            offs += 8;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableULong: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs)));
                            offs += 8;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableFloat: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs)));
                            offs += 4;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableDouble: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs)));
                            offs += 8;
                        }
                        break;
    				
                    case ClassDescriptor.FieldType.tpNullableGuid:
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(Bytes.unpackGuid(body, offs).ToString());
                            offs += 16;
                        }
                        break;
    
                    case ClassDescriptor.FieldType.tpNullableDecimal:
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write(Bytes.unpackDecimal(body, offs).ToString());
                            offs += 16;
                        }
                        break;
    
                    case ClassDescriptor.FieldType.tpNullableDate: 
                        if (body[offs++] == 0) { 
                            writer.Write("null");
                        } else {
                            writer.Write("\"" + Bytes.unpackDate(body, offs).ToString() + "\"");
                            offs += 8;
                        }
                        break;
#endif
                    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.tpEnum:
                        writer.Write(Enum.ToObject(fd.MemberType, Bytes.unpack4(body, offs)));
                        offs += 4;
                        break;

                    case ClassDescriptor.FieldType.tpUInt: 
                        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) + "\"");
                        offs += 16;
                        break;

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

                    case ClassDescriptor.FieldType.tpString: 
                    case ClassDescriptor.FieldType.tpType: 
                        offs = exportString(body, offs);
                        break;
					
                    case ClassDescriptor.FieldType.tpDate: 
                    {
                        long msec = Bytes.unpack8(body, offs);
                        offs += 8;
                        if (msec >= 0)
                        {
                            writer.Write("\"" + new System.DateTime(msec) + "\"");
                        }
                        else
                        {
                            writer.Write("null");
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpObject: 
                    case ClassDescriptor.FieldType.tpOid: 
                        offs = exportRef(body, offs, indent);
                        break;

                    case ClassDescriptor.FieldType.tpValue: 
                        writer.Write('\n');
                        offs = exportObject(fd.valueDesc, body, offs, indent + 1);
                        indentation(indent);
                        break;
					
                    case ClassDescriptor.FieldType.tpArrayOfByte: 
                    case ClassDescriptor.FieldType.tpArrayOfSByte: 
                        offs = exportBinary(body, offs);
                        break;
					
                    case ClassDescriptor.FieldType.tpCustom:
                    {
                        MemoryReader reader = new MemoryReader(storage, body, offs, null, true, false);
                        object obj = storage.serializer.Unpack(reader);
                        offs = reader.Position;                        
                        writer.Write("\"");
                        foreach (char ch in storage.serializer.Print(obj)) 
                        { 
                            exportChar(ch);
                        }
                        writer.Write("\"");
                        break;
                    }

                    case ClassDescriptor.FieldType.tpArrayOfBoolean: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + (body[offs++] != 0?"1":"0") + "</element>\n");
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfChar: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + (Bytes.unpack2(body, offs) & 0xFFFF) + "</element>\n");
                                offs += 2;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfShort: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + Bytes.unpack2(body, offs) + "</element>\n");
                                offs += 2;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfUShort: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + (ushort)Bytes.unpack2(body, offs) + "</element>\n");
                                offs += 2;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfInt: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + Bytes.unpack4(body, offs) + "</element>\n");
                                offs += 4;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfEnum: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            Type elemType = fd.MemberType.GetElementType();
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + Enum.ToObject(elemType, Bytes.unpack4(body, offs)) + "</element>\n");
                                offs += 4;
                            }
                            indentation(indent);
                        }
                        break;
                    }

                    case ClassDescriptor.FieldType.tpArrayOfUInt: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + (uint)Bytes.unpack4(body, offs) + "</element>\n");
                                offs += 4;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfLong: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + Bytes.unpack8(body, offs) + "</element>\n");
                                offs += 8;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfULong: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + (ulong)Bytes.unpack8(body, offs) + "</element>\n");
                                offs += 8;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfFloat: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + Bytes.unpackF4(body, offs) + "</element>\n");
                                offs += 4;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfDouble: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>" + Bytes.unpackF8(body, offs) + "</element>\n");
                                offs += 8;
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfDate: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>\"" + Bytes.unpackDate(body, offs) + "\"</element>\n");
                                offs += 8;
                            }
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfGuid: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                writer.Write("<element>\"" + Bytes.unpackGuid(body, offs) + "\"</element>\n");
                                offs += 16;
                            }
                        }
                        break;
                    }

                    case ClassDescriptor.FieldType.tpArrayOfDecimal: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                writer.Write("<element>\"" + Bytes.unpackDecimal(body, offs) + "\"</element>\n");
                                offs += 16;
                            }
                        }
                        break;
                    }

                    case ClassDescriptor.FieldType.tpArrayOfString: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>");
                                offs = exportString(body, offs);
                                writer.Write("</element>\n");
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpLink: 
                    case ClassDescriptor.FieldType.tpArrayOfObject: 
                    case ClassDescriptor.FieldType.tpArrayOfOid: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent+1);
                                writer.Write("<element>");
                                offs = exportRef(body, offs, indent+1);
                                writer.Write("</element>\n");
                            }
                            indentation(indent);
                        }
                        break;
                    }
					
                    case ClassDescriptor.FieldType.tpArrayOfValue: 
                    {
                        int len = Bytes.unpack4(body, offs);
                        offs += 4;
                        if (len < 0)
                        {
                            writer.Write("null");
                        }
                        else
                        {
                            writer.Write('\n');
                            while (--len >= 0)
                            {
                                indentation(indent + 1);
                                writer.Write("<element>\n");
                                offs = exportObject(fd.valueDesc, body, offs, indent + 2);
                                indentation(indent + 1);
                                writer.Write("</element>\n");
                            }
                            indentation(indent);
                        }
                        break;
                    }					
                }
                writer.Write("</" + fieldName + ">\n");
            }
            return offs;
        }
Пример #2
0
 internal int exportRef(byte[] body, int offs, int indent) 
 { 
     int oid = Bytes.unpack4(body, offs);
     offs += 4;
     if (oid < 0) 
     {
         int tid = -1-oid;
         switch ((ClassDescriptor.FieldType)tid)
         {
             case ClassDescriptor.FieldType.tpType:
                 writer.Write("<type name=\"");
                 offs = exportString(body, offs);
                 writer.Write("\"/>");
                 break;
             case ClassDescriptor.FieldType.tpString:
             {
                 offs = exportString(body, offs);
                 break;
             }
             case ClassDescriptor.FieldType.tpBoolean:
             case ClassDescriptor.FieldType.tpByte:
             case ClassDescriptor.FieldType.tpSByte:
             case ClassDescriptor.FieldType.tpChar:
             case ClassDescriptor.FieldType.tpShort:
             case ClassDescriptor.FieldType.tpUShort:
             case ClassDescriptor.FieldType.tpInt:
             case ClassDescriptor.FieldType.tpUInt:
             case ClassDescriptor.FieldType.tpLong:
             case ClassDescriptor.FieldType.tpULong:
             case ClassDescriptor.FieldType.tpFloat:
             case ClassDescriptor.FieldType.tpDouble:
             case ClassDescriptor.FieldType.tpDate:
             case ClassDescriptor.FieldType.tpDecimal:
             case ClassDescriptor.FieldType.tpGuid:
             case ClassDescriptor.FieldType.tpEnum:
             {
                 int len = ClassDescriptor.Sizeof[tid];
                 writer.Write("<scalar type=\"" + tid + "\" value=\"");
                 while (--len >= 0) {
                     byte b = body[offs++];
                     writer.Write(hexDigit[(b >> 4) & 0xF]);
                     writer.Write(hexDigit[b & 0xF]);
                 }
                 writer.Write("\"/>");
                 break;
             }
             case ClassDescriptor.FieldType.tpCustom:
             {
                 MemoryReader reader = new MemoryReader(storage, body, offs, null, true, false);
                 object obj = storage.serializer.Unpack(reader);
                 offs = reader.Position;                        
                 writer.Write("<scalar type=\"" + tid + "\" value=\"");
                 foreach (char ch in storage.serializer.Print(obj)) 
                 { 
                     exportChar(ch);
                 }
                 writer.Write("\"/>");
                 break;
             }
             default:
             {
                 if (tid >= (int)ClassDescriptor.FieldType.tpValueTypeBias) 
                 { 
                     int typeOid = -(int)ClassDescriptor.FieldType.tpValueTypeBias - oid;
                     ClassDescriptor desc = storage.findClassDescriptor(typeOid);
                     if (desc.isCollection) 
                     { 
                         int len = Bytes.unpack4(body, offs);   
                         offs += 4;
                         String className = exportIdentifier(desc.name);
                         writer.Write("\n");
                         indentation(indent + 1);
                         writer.Write("<" + className + ">\n");
                         for (int i = 0; i < len; i++) 
                         { 
                             indentation(indent + 2);
                             writer.Write("<element>");
                             offs = exportRef(body, offs, indent + 2);
                             writer.Write("</element>\n");
                         }                            
                         indentation(indent + 1);
                         writer.Write("</" + className + ">\n");
                         indentation(indent);
                     } 
                     else if (desc.isDictionary) 
                     { 
                         int len = Bytes.unpack4(body, offs);   
                         offs += 4;
                         String className = exportIdentifier(desc.name);
                         writer.Write("\n");
                         indentation(indent + 1);
                         writer.Write("<" + className + ">\n");
                         for (int i = 0; i < len; i++) 
                         { 
                             indentation(indent + 2);
                             writer.Write("<element>\n");
                             indentation(indent + 4);
                             writer.Write("<key>");
                             offs = exportRef(body, offs, indent + 4);
                             writer.Write("</key>\n");
                             indentation(indent + 4);
                             writer.Write("<value>");
                             offs = exportRef(body, offs, indent + 4);
                             writer.Write("</value>\n");
                             indentation(indent + 2);
                             writer.Write("</element>\n");
                         }                            
                         indentation(indent + 1);
                         writer.Write("</" + className + ">\n");
                         indentation(indent);
                     } 
                     else 
                     {
                         string className = exportIdentifier(desc.name);
                         writer.Write("\n");
                         indentation(indent + 1);
                         writer.Write("<" + className + ">\n");
                         offs = exportObject(desc, body, offs, indent + 2);
                         indentation(indent + 1);
                         writer.Write("</" + className + ">\n");
                         indentation(indent);
                     }
                     break;
                 } 
                 else 
                 { 
                     throw new StorageError(StorageError.ErrorCode.UNSUPPORTED_TYPE);
                 }
             }
         }       
     } 
     else
     {
         writer.Write("<ref id=\"" + oid + "\"/>");
         if (oid != 0 && (exportedBitmap[oid >> 5] & (1 << (oid & 31))) == 0) 
         { 
             markedBitmap[oid >> 5] |= 1 << (oid & 31);
         }
     }
     return offs;
 }