Exemplo n.º 1
0
 internal int importBinary(XMLElement elem, int offs, ByteBuffer buf, String fieldName)
 {
     if (elem == null || elem.isNullValue())
     {
         buf.extend(offs + 4);
         Bytes.pack4(buf.arr, offs, -1);
         offs += 4;
     }
     else if (elem.isStringValue())
     {
         String hexStr = elem.StringValue;
         int len = hexStr.Length;
         if (hexStr.StartsWith("#"))
         {
             buf.extend(offs + 4 + len / 2 - 1);
             Bytes.pack4(buf.arr, offs, -2 - getHexValue(hexStr[1]));
             offs += 4;
             for (int j = 2; j < len; j += 2)
             {
                 buf.arr[offs++] = (byte)((getHexValue(hexStr[j]) << 4) | getHexValue(hexStr[j + 1]));
             }
         }
         else
         {
             buf.extend(offs + 4 + len / 2);
             Bytes.pack4(buf.arr, offs, len / 2);
             offs += 4;
             for (int j = 0; j < len; j += 2)
             {
                 buf.arr[offs++] = (byte)((getHexValue(hexStr[j]) << 4) | getHexValue(hexStr[j + 1]));
             }
         }
     }
     else
     {
         XMLElement refElem = elem.getSibling("ref");
         if (refElem != null)
         {
             buf.extend(offs + 4);
             Bytes.pack4(buf.arr, offs, mapId(getIntAttribute(refElem, "id")));
             offs += 4;
         }
         else
         {
             XMLElement item = elem.getSibling("element");
             int len = (item == null) ? 0 : item.Counter;
             buf.extend(offs + 4 + len);
             Bytes.pack4(buf.arr, offs, len);
             offs += 4;
             while (--len >= 0)
             {
                 if (item.isIntValue())
                 {
                     buf.arr[offs] = (byte)item.IntValue;
                 }
                 else if (item.isRealValue())
                 {
                     buf.arr[offs] = (byte)item.RealValue;
                 }
                 else
                 {
                     throwException("Conversion for field " + fieldName + " is not possible");
                 }
                 item = item.NextSibling;
                 offs += 1;
             }
         }
     }
     return offs;
 }
Exemplo n.º 2
0
        internal int packObject(XMLElement objElem, ClassDescriptor desc, int offs, ByteBuffer buf)
        {
            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;
            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                String fieldName = fd.fieldName;
                XMLElement elem = (objElem != null) ? objElem.getSibling(fieldName) : null;

                switch (fd.type)
                {
                    case ClassDescriptor.FieldType.tpByte:
                    case ClassDescriptor.FieldType.tpSByte:
                        buf.extend(offs + 1);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.arr[offs] = (byte)elem.IntValue;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.arr[offs] = (byte)elem.RealValue;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 1;
                        continue;

                    case ClassDescriptor.FieldType.tpBoolean:
                        buf.extend(offs + 1);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.arr[offs] = (byte)(elem.IntValue != 0 ? 1 : 0);
                            }
                            else if (elem.isRealValue())
                            {
                                buf.arr[offs] = (byte)(elem.RealValue != 0.0 ? 1 : 0);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 1;
                        continue;

                    case ClassDescriptor.FieldType.tpShort:
                    case ClassDescriptor.FieldType.tpUShort:
                    case ClassDescriptor.FieldType.tpChar:
                        buf.extend(offs + 2);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack2(buf.arr, offs, (short)elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack2(buf.arr, offs, (short)elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 2;
                        continue;

                    case ClassDescriptor.FieldType.tpEnum:
                        buf.extend(offs + 4);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int)elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int)elem.RealValue);
                            }
                            else if (elem.isStringValue())
                            {
                                try
                                {
            #if CF
                                    Bytes.pack4(buf.arr, offs, (int)ClassDescriptor.parseEnum(f.FieldType, elem.StringValue));
            #else
                                    Bytes.pack4(buf.arr, offs, (int)Enum.Parse(f.FieldType, elem.StringValue));
            #endif
                                }
                                catch (ArgumentException)
                                {
                                    throwException("Invalid enum value");
                                }
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 4;
                        continue;

                    case ClassDescriptor.FieldType.tpInt:
                    case ClassDescriptor.FieldType.tpUInt:
                        buf.extend(offs + 4);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int)elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int)elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 4;
                        continue;

                    case ClassDescriptor.FieldType.tpLong:
                    case ClassDescriptor.FieldType.tpULong:
                        buf.extend(offs + 8);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack8(buf.arr, offs, elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack8(buf.arr, offs, (long)elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 8;
                        continue;

                    case ClassDescriptor.FieldType.tpFloat:
                        buf.extend(offs + 4);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.packF4(buf.arr, offs, (float)elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.packF4(buf.arr, offs, (float)elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 4;
                        continue;

                    case ClassDescriptor.FieldType.tpDouble:
                        buf.extend(offs + 8);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.packF8(buf.arr, offs, (double)elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.packF8(buf.arr, offs, elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 8;
                        continue;

                    case ClassDescriptor.FieldType.tpDecimal:
                        buf.extend(offs + 16);
                        if (elem != null)
                        {
                            decimal d = 0;
                            if (elem.isIntValue())
                            {
                                d = elem.IntValue;
                            }
                            else if (elem.isRealValue())
                            {
                                d = (decimal)elem.RealValue;
                            }
                            else if (elem.isStringValue())
                            {
                                try
                                {
                                    d = Decimal.Parse(elem.StringValue);
                                }
                                catch (FormatException)
                                {
                                    throwException("Invalid date");
                                }
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                            Bytes.packDecimal(buf.arr, offs, d);

                        }
                        offs += 16;
                        continue;

                    case ClassDescriptor.FieldType.tpGuid:
                        buf.extend(offs + 16);
                        if (elem != null)
                        {
                            if (elem.isStringValue())
                            {
                                Guid guid = new Guid(elem.StringValue);
                                byte[] bits = guid.ToByteArray();
                                Array.Copy(bits, 0, buf.arr, offs, 16);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 16;
                        continue;

                    case ClassDescriptor.FieldType.tpDate:
                        buf.extend(offs + 8);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack8(buf.arr, offs, elem.IntValue);
                            }
                            else if (elem.isNullValue())
                            {
                                Bytes.pack8(buf.arr, offs, -1);
                            }
                            else if (elem.isStringValue())
                            {
                                try
                                {
                                    Bytes.packDate(buf.arr, offs, DateTime.Parse(elem.StringValue));
                                }
                                catch (FormatException)
                                {
                                    throwException("Invalid date");
                                }
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 8;
                        continue;

                    case ClassDescriptor.FieldType.tpString:
                        if (elem != null)
                        {
                            System.String val = null;
                            if (elem.isIntValue())
                            {
                                val = System.Convert.ToString(elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                val = elem.RealValue.ToString();
                            }
                            else if (elem.isStringValue())
                            {
                                val = elem.StringValue;
                            }
                            else if (elem.isNullValue())
                            {
                                val = null;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                            offs = buf.packString(offs, val);
                            continue;
                        }
                        buf.extend(offs + 4);
                        Bytes.pack4(buf.arr, offs, -1);
                        offs += 4;
                        continue;

                    case ClassDescriptor.FieldType.tpOid:
                    case ClassDescriptor.FieldType.tpObject:
                        {
                            int oid = 0;
                            if (elem != null)
                            {
                                XMLElement refElem = elem.getSibling("ref");
                                if (refElem == null)
                                {
                                    throwException("<ref> element expected");
                                }
                                oid = mapId(getIntAttribute(refElem, "id"));
                            }
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, oid);
                            offs += 4;
                            continue;
                        }

                    case ClassDescriptor.FieldType.tpValue:
                        offs = packObject(elem, fd.valueDesc, offs, buf);
                        continue;

                    case ClassDescriptor.FieldType.tpRaw:
                    case ClassDescriptor.FieldType.tpArrayOfByte:
                    case ClassDescriptor.FieldType.tpArrayOfSByte:
                        offs = importBinary(elem, offs, buf, fieldName);
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfBoolean:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    buf.arr[offs] = (byte)(item.IntValue != 0 ? 1 : 0);
                                }
                                else if (item.isRealValue())
                                {
                                    buf.arr[offs] = (byte)(item.RealValue != 0.0 ? 1 : 0);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 1;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfChar:
                    case ClassDescriptor.FieldType.tpArrayOfShort:
                    case ClassDescriptor.FieldType.tpArrayOfUShort:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 2);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack2(buf.arr, offs, (short)item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack2(buf.arr, offs, (short)item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 2;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfEnum:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            Type elemType = f.FieldType.GetElementType();
                            buf.extend(offs + 4 + len * 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int)item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int)item.RealValue);
                                }
                                else if (item.isStringValue())
                                {
                                    try
                                    {
            #if CF
                                        Bytes.pack4(buf.arr, offs, (int)ClassDescriptor.parseEnum(elemType, item.StringValue));
            #else
                                        Bytes.pack4(buf.arr, offs, (int)Enum.Parse(elemType, item.StringValue));
            #endif
                                    }
                                    catch (ArgumentException)
                                    {
                                        throwException("Invalid enum value");
                                    }
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 4;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfInt:
                    case ClassDescriptor.FieldType.tpArrayOfUInt:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int)item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int)item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 4;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfLong:
                    case ClassDescriptor.FieldType.tpArrayOfULong:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 8);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack8(buf.arr, offs, item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack8(buf.arr, offs, (long)item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 8;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfFloat:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.packF4(buf.arr, offs, (float)item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.packF4(buf.arr, offs, (float)item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 4;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfDouble:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 8);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.packF8(buf.arr, offs, (double)item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.packF8(buf.arr, offs, item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 8;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfDate:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 8);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isNullValue())
                                {
                                    Bytes.pack8(buf.arr, offs, -1);
                                }
                                else if (item.isStringValue())
                                {
                                    try
                                    {
                                        Bytes.packDate(buf.arr, offs, DateTime.Parse(item.StringValue));
                                    }
                                    catch (FormatException)
                                    {
                                        throwException("Conversion for field " + fieldName + " is not possible");
                                    }
                                }
                                item = item.NextSibling;
                                offs += 8;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfDecimal:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 16);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isStringValue())
                                {
                                    try
                                    {
                                        Bytes.packDecimal(buf.arr, offs, Decimal.Parse(item.StringValue));
                                    }
                                    catch (FormatException)
                                    {
                                        throwException("Conversion for field " + fieldName + " is not possible");
                                    }
                                }
                                item = item.NextSibling;
                                offs += 16;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfGuid:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 16);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isStringValue())
                                {
                                    try
                                    {
                                        Bytes.packGuid(buf.arr, offs, new Guid(item.StringValue));
                                    }
                                    catch (FormatException)
                                    {
                                        throwException("Conversion for field " + fieldName + " is not possible");
                                    }
                                }
                                item = item.NextSibling;
                                offs += 16;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfString:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                System.String val = null;
                                if (item.isIntValue())
                                {
                                    val = System.Convert.ToString(item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    val = item.RealValue.ToString();
                                }
                                else if (item.isStringValue())
                                {
                                    val = item.StringValue;
                                }
                                else if (item.isNullValue())
                                {
                                    val = null;
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                offs = buf.packString(offs, val);
                                item = item.NextSibling;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfObject:
                    case ClassDescriptor.FieldType.tpArrayOfOid:
                    case ClassDescriptor.FieldType.tpLink:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            buf.extend(offs + 4 + len * 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                XMLElement href = item.getSibling("ref");
                                if (href == null)
                                {
                                    throwException("<ref> element expected");
                                }
                                int oid = mapId(getIntAttribute(href, "id"));
                                Bytes.pack4(buf.arr, offs, oid);
                                item = item.NextSibling;
                                offs += 4;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfValue:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            ClassDescriptor elemDesc = fd.valueDesc;
                            while (--len >= 0)
                            {
                                offs = packObject(item, elemDesc, offs, buf);
                                item = item.NextSibling;
                            }
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpArrayOfRaw:
                        if (elem == null || elem.isNullValue())
                        {
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, -1);
                            offs += 4;
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null) ? 0 : item.Counter;
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                offs = importBinary(item, offs, buf, fieldName);
                                item = item.NextSibling;
                            }
                        }
                        continue;
                }
            }
            return offs;
        }
Exemplo n.º 3
0
        internal int packObject(XMLElement objElem, ClassDescriptor desc, int offs, ByteBuffer buf)
        {
            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;
            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                String fieldName = fd.fieldName;
                XMLElement elem = (objElem != null)?objElem.getSibling(fieldName):null;
                ClassDescriptor.FieldType type = fd.type;				
                switch (fd.type)
                {
#if NET_FRAMEWORK_20
                    case ClassDescriptor.FieldType.tpNullableByte: 
                    case ClassDescriptor.FieldType.tpNullableSByte: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 2);
                                buf.arr[offs++] = (byte) 1;
                                buf.arr[offs++] = (byte) elem.IntValue;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 2);
                                buf.arr[offs++] = (byte) 1;
                                buf.arr[offs++] = (byte) elem.RealValue;
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        } 
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpNullableBoolean: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 2);
                                buf.arr[offs++] = (byte) 1;
                                buf.arr[offs++] = (byte) (elem.IntValue != 0?1:0);
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 2);
                                buf.arr[offs++] = (byte) 1;
                                buf.arr[offs++] = (byte) (elem.RealValue != 0.0?1:0);
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        } 
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpNullableShort: 
                    case ClassDescriptor.FieldType.tpNullableUShort: 
                    case ClassDescriptor.FieldType.tpNullableChar: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 3);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack2(buf.arr, offs, (short) elem.IntValue);
                                offs += 2;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 3);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack2(buf.arr, offs, (short) elem.RealValue);
                                offs += 2;
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        } 
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpNullableEnum: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 5);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack4(buf.arr, offs, (int) elem.IntValue);        
                                offs += 4;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 5);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack4(buf.arr, offs, (int) elem.RealValue);
                                offs += 4;
                            }
                            else if (elem.isStringValue()) 
                            {
                                try 
                                {
                                    buf.extend(offs + 5);
                                    buf.arr[offs++] = (byte) 1;
                                    Bytes.pack4(buf.arr, offs, (int)ClassDescriptor.parseEnum(f.FieldType, elem.StringValue));
                                } 
                                catch (ArgumentException)
                                {
                                    throwException("Invalid enum value");
                                }
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					

                    case ClassDescriptor.FieldType.tpNullableInt: 
                    case ClassDescriptor.FieldType.tpNullableUInt: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 5);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack4(buf.arr, offs, (int) elem.IntValue);
                                offs += 4;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 5);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack4(buf.arr, offs, (int) elem.RealValue);
                                offs += 4;
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpNullableLong: 
                    case ClassDescriptor.FieldType.tpNullableULong: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 9);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack8(buf.arr, offs, elem.IntValue);
                                offs += 9;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 9);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack8(buf.arr, offs, (long) elem.RealValue);
                                offs += 9;
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpNullableFloat: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 5);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.packF4(buf.arr, offs, (float)elem.IntValue);
                                offs += 4;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 5);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.packF4(buf.arr, offs, (float) elem.RealValue);
                                offs += 4;
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpNullableDouble: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 9);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.packF8(buf.arr, offs, (double) elem.IntValue);
                                offs += 8;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.extend(offs + 9);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.packF8(buf.arr, offs, elem.RealValue);
                                offs += 8;
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpNullableDecimal: 
                        if (elem != null)
                        {
                            decimal d = 0;
                            if (elem.isIntValue())
                            {
                                d = elem.IntValue;
                            }
                            else if (elem.isRealValue())
                            {
                                d = (decimal)elem.RealValue;
                            }
                            else if (elem.isStringValue())
                            {
                                try 
                                { 
                                    d = Decimal.Parse(elem.StringValue);
                                } 
                                catch (FormatException) 
                                {
                                    throwException("Invalid date");
                                }
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                                continue;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                            buf.extend(offs + 17);
                            buf.arr[offs++] = (byte) 1;
                            Bytes.packDecimal(buf.arr, offs, d);
                            offs += 16;
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
  
                    case ClassDescriptor.FieldType.tpNullableGuid: 
                        if (elem != null)
                        {
                            if (elem.isStringValue())
                            {
                                buf.extend(offs + 17);
                                buf.arr[offs++] = (byte) 1;
                                Guid guid = new Guid(elem.StringValue);
                                byte[] bits = guid.ToByteArray();
                                Array.Copy(bits, 0, buf.arr, offs, 16);
                                offs += 16;
                            }
                            else if (elem.isNullValue())
                            {
                                 buf.extend(offs + 1);
                                 buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;
                    
                    case ClassDescriptor.FieldType.tpNullableDate: 
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.extend(offs + 9);
                                buf.arr[offs++] = (byte) 1;
                                Bytes.pack8(buf.arr, offs, elem.IntValue);
                                offs += 8;
                            }
                            else if (elem.isStringValue())
                            {
                                try 
                                { 
                                    buf.extend(offs + 9);
                                    buf.arr[offs++] = (byte) 1;
                                    Bytes.packDate(buf.arr, offs, DateTime.Parse(elem.StringValue));
                                    offs += 8;
                                } 
                                catch (FormatException) 
                                {
                                    throwException("Invalid date");
                                }
                            }
                            else if (elem.isNullValue())
                            {
                                buf.extend(offs + 1);
                                buf.arr[offs++] = (byte) 0;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        else 
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        }
                        continue;

                    case ClassDescriptor.FieldType.tpNullableValue: 
                        if (elem != null || elem.isNullValue())
                        {
                            buf.extend(offs + 1);
                            buf.arr[offs++] = (byte) 0;
                        } 
                        else                         
                        { 
                            offs = packObject(elem, fd.valueDesc, offs, buf);
                        }
                        continue;
#endif

                    case ClassDescriptor.FieldType.tpByte: 
                    case ClassDescriptor.FieldType.tpSByte: 
                        buf.extend(offs + 1);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.arr[offs] = (byte) elem.IntValue;
                            }
                            else if (elem.isRealValue())
                            {
                                buf.arr[offs] = (byte) elem.RealValue;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 1;
                        continue;
					
                    case ClassDescriptor.FieldType.tpBoolean: 
                        buf.extend(offs + 1);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                buf.arr[offs] = (byte) (elem.IntValue != 0?1:0);
                            }
                            else if (elem.isRealValue())
                            {
                                buf.arr[offs] = (byte) (elem.RealValue != 0.0?1:0);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 1;
                        continue;
					
                    case ClassDescriptor.FieldType.tpShort: 
                    case ClassDescriptor.FieldType.tpUShort: 
                    case ClassDescriptor.FieldType.tpChar: 
                        buf.extend(offs + 2);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack2(buf.arr, offs, (short) elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack2(buf.arr, offs, (short) elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 2;
                        continue;
					
                    case ClassDescriptor.FieldType.tpEnum: 
                        buf.extend(offs + 4);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int) elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int) elem.RealValue);
                            }
                            else if (elem.isStringValue()) 
                            {
                                try
                                {
                                    Bytes.pack4(buf.arr, offs, (int)ClassDescriptor.parseEnum(f.FieldType, elem.StringValue));
                                } 
                                catch (ArgumentException)
                                {
                                    throwException("Invalid enum value");
                                }
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 4;
                        continue;
					

                    case ClassDescriptor.FieldType.tpInt: 
                    case ClassDescriptor.FieldType.tpUInt: 
                        buf.extend(offs + 4);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int) elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack4(buf.arr, offs, (int) elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 4;
                        continue;
					
                    case ClassDescriptor.FieldType.tpLong: 
                    case ClassDescriptor.FieldType.tpULong: 
                        buf.extend(offs + 8);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack8(buf.arr, offs, elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.pack8(buf.arr, offs, (long) elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 8;
                        continue;
					
                    case ClassDescriptor.FieldType.tpFloat: 
                        buf.extend(offs + 4);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.packF4(buf.arr, offs, (float)elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.packF4(buf.arr, offs, (float) elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 4;
                        continue;
					
                    case ClassDescriptor.FieldType.tpDouble: 
                        buf.extend(offs + 8);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.packF8(buf.arr, offs, (double) elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                Bytes.packF8(buf.arr, offs, elem.RealValue);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 8;
                        continue;
					
                    case ClassDescriptor.FieldType.tpDecimal: 
                        buf.extend(offs + 16);
                        if (elem != null)
                        {
                            decimal d = 0;
                            if (elem.isIntValue())
                            {
                                d = elem.IntValue;
                            }
                            else if (elem.isRealValue())
                            {
                                d = (decimal)elem.RealValue;
                            }
                            else if (elem.isStringValue())
                            {
                                try 
                                { 
                                    d = Decimal.Parse(elem.StringValue);
                                } 
                                catch (FormatException) 
                                {
                                    throwException("Invalid date");
                                }
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                            Bytes.packDecimal(buf.arr, offs, d);

                        }
                        offs += 16;
                        continue;
  
                    case ClassDescriptor.FieldType.tpGuid: 
                        buf.extend(offs + 16);
                        if (elem != null)
                        {
                            if (elem.isStringValue())
                            {
                                Guid guid = new Guid(elem.StringValue);
                                byte[] bits = guid.ToByteArray();
                                Array.Copy(bits, 0, buf.arr, offs, 16);
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 16;
                        continue;
                    
                    case ClassDescriptor.FieldType.tpDate: 
                        buf.extend(offs + 8);
                        if (elem != null)
                        {
                            if (elem.isIntValue())
                            {
                                Bytes.pack8(buf.arr, offs, elem.IntValue);
                            }
                            else if (elem.isStringValue())
                            {
                                try 
                                { 
                                    Bytes.packDate(buf.arr, offs, DateTime.Parse(elem.StringValue));
                                } 
                                catch (FormatException) 
                                {
                                    throwException("Invalid date");
                                }
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                        }
                        offs += 8;
                        continue;
					
                    case ClassDescriptor.FieldType.tpString: 
                    case ClassDescriptor.FieldType.tpType: 
                        if (elem != null)
                        {
                            string val = null;
                            if (elem.isIntValue())
                            {
                                val = System.Convert.ToString(elem.IntValue);
                            }
                            else if (elem.isRealValue())
                            {
                                val = elem.RealValue.ToString();
                            }
                            else if (elem.isStringValue())
                            {
                                val = elem.StringValue;
                            }
                            else if (elem.isNullValue())
                            {
                                val = null;
                            }
                            else
                            {
                                throwException("Conversion for field " + fieldName + " is not possible");
                            }
                            offs = buf.packString(offs, val);
                            continue;
                        }
                        offs = buf.packI4(offs, -1);
                        continue;
					
                    case ClassDescriptor.FieldType.tpOid: 
                    case ClassDescriptor.FieldType.tpObject: 
                        offs = importRef(elem, offs, buf);
                        continue;
					
                    case ClassDescriptor.FieldType.tpValue: 
                        offs = packObject(elem, fd.valueDesc, offs, buf);
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfByte: 
                    case ClassDescriptor.FieldType.tpArrayOfSByte: 
                        offs = importBinary(elem, offs, buf, fieldName);
                        continue;
					
                    case ClassDescriptor.FieldType.tpCustom:
                    {
                        if (!elem.isStringValue()) 
                        {
                            throwException("text element expected");
                        }
                        String str = elem.StringValue;                    
                        object obj = storage.serializer.Parse(str);                        
                        storage.serializer.Pack(obj, buf.GetWriter());                    
                        offs = buf.used;
                        break;
                    }

                    case ClassDescriptor.FieldType.tpArrayOfBoolean: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    buf.arr[offs] = (byte) (item.IntValue != 0?1:0);
                                }
                                else if (item.isRealValue())
                                {
                                    buf.arr[offs] = (byte) (item.RealValue != 0.0?1:0);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 1;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfChar: 
                    case ClassDescriptor.FieldType.tpArrayOfShort: 
                    case ClassDescriptor.FieldType.tpArrayOfUShort: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 2);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack2(buf.arr, offs, (short) item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack2(buf.arr, offs, (short) item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 2;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfEnum: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            Type elemType = f.FieldType.GetElementType();
                            buf.extend(offs + 4 + len * 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int) item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int) item.RealValue);
                                }
                                else if (item.isStringValue()) 
                                {
                                    try
                                    {
                                        Bytes.pack4(buf.arr, offs, (int)ClassDescriptor.parseEnum(elemType, item.StringValue));
                                    } 
                                    catch (ArgumentException)
                                    {
                                        throwException("Invalid enum value");
                                    }
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 4;
                            }
                        }
                        continue;
                        

                    case ClassDescriptor.FieldType.tpArrayOfInt: 
                    case ClassDescriptor.FieldType.tpArrayOfUInt: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int) item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack4(buf.arr, offs, (int) item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 4;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfLong: 
                    case ClassDescriptor.FieldType.tpArrayOfULong: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 8);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.pack8(buf.arr, offs, item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.pack8(buf.arr, offs, (long) item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 8;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfFloat: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                   Bytes.packF4(buf.arr, offs, (float)item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.packF4(buf.arr, offs, (float)item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 4;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfDouble: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 8);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isIntValue())
                                {
                                    Bytes.packF8(buf.arr, offs, (double)item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    Bytes.packF8(buf.arr, offs, item.RealValue);
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                item = item.NextSibling;
                                offs += 8;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfDate: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 8);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isNullValue())
                                {
                                    Bytes.pack8(buf.arr, offs, -1);
                                }
                                else if (item.isStringValue())
                                {
                                    try 
                                    { 
                                        Bytes.packDate(buf.arr, offs, DateTime.Parse(item.StringValue));
                                    }
                                    catch (FormatException)
                                    {
                                        throwException("Conversion for field " + fieldName + " is not possible");
                                    }
                                }
                                item = item.NextSibling;
                                offs += 8;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfDecimal: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 16);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isStringValue())
                                {
                                    try 
                                    { 
                                        Bytes.packDecimal(buf.arr, offs, Decimal.Parse(item.StringValue));
                                    }
                                    catch (FormatException)
                                    {
                                        throwException("Conversion for field " + fieldName + " is not possible");
                                    }
                                }
                                item = item.NextSibling;
                                offs += 16;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfGuid: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4 + len * 16);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                if (item.isStringValue())
                                {
                                    try 
                                    { 
                                        Bytes.packGuid(buf.arr, offs, new Guid(item.StringValue));
                                    }
                                    catch (FormatException)
                                    {
                                        throwException("Conversion for field " + fieldName + " is not possible");
                                    }
                                }
                                item = item.NextSibling;
                                offs += 16;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfString: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            buf.extend(offs + 4);
                            Bytes.pack4(buf.arr, offs, len);
                            offs += 4;
                            while (--len >= 0)
                            {
                                string val = null;
                                if (item.isIntValue())
                                {
                                    val = System.Convert.ToString(item.IntValue);
                                }
                                else if (item.isRealValue())
                                {
                                    val = item.RealValue.ToString();
                                }
                                else if (item.isStringValue())
                                {
                                    val = item.StringValue;
                                }
                                else if (item.isNullValue())
                                {
                                    val = null;
                                }
                                else
                                {
                                    throwException("Conversion for field " + fieldName + " is not possible");
                                }
                                offs = buf.packString(offs, val);  
                                item = item.NextSibling;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfObject: 
                    case ClassDescriptor.FieldType.tpArrayOfOid: 
                    case ClassDescriptor.FieldType.tpLink: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            offs = buf.packI4(offs, len);
                            while (--len >= 0)
                            {
                                offs = importRef(item, offs, buf);
                                item = item.NextSibling;
                            }
                        }
                        continue;
					
                    case ClassDescriptor.FieldType.tpArrayOfValue: 
                        if (elem == null || elem.isNullValue())
                        {
                            offs = buf.packI4(offs, -1);
                        }
                        else
                        {
                            XMLElement item = elem.getSibling("element");
                            int len = (item == null)?0:item.Counter;
                            offs = buf.packI4(offs, len);
                            ClassDescriptor elemDesc = fd.valueDesc;
                            while (--len >= 0)
                            {
                                offs = packObject(item, elemDesc, offs, buf);
                                item = item.NextSibling;
                            }
                        }
                        continue;					
                }
            }
            return offs;
        }