Inheritance: Volante.Persistent
Exemple #1
0
 internal static int allocate(DatabaseImpl db, int root, ClassDescriptor.FieldType type, OldBtreeKey ins)
 {
     int pageId = db.allocatePage();
     Page pg = db.putPage(pageId);
     setnItems(pg, 1);
     if (type == ClassDescriptor.FieldType.tpString)
     {
         char[] sval = (char[])ins.key.oval;
         int len = sval.Length;
         setSize(pg, len * 2);
         setKeyStrOffs(pg, 0, keySpace - len * 2);
         setKeyStrSize(pg, 0, len);
         setKeyStrOid(pg, 0, ins.oid);
         setKeyStrOid(pg, 1, root);
         setKeyStrChars(pg, keySpace - len * 2, sval);
     }
     else if (type == ClassDescriptor.FieldType.tpArrayOfByte)
     {
         byte[] bval = (byte[])ins.key.oval;
         int len = bval.Length;
         setSize(pg, len);
         setKeyStrOffs(pg, 0, keySpace - len);
         setKeyStrSize(pg, 0, len);
         setKeyStrOid(pg, 0, ins.oid);
         setKeyStrOid(pg, 1, root);
         setKeyBytes(pg, keySpace - len, bval);
     }
     else
     {
         ins.pack(pg, 0);
         setReference(pg, maxItems - 2, root);
     }
     db.pool.unfix(pg);
     return pageId;
 }
Exemple #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;
        }
Exemple #3
0
        Key createKey(ClassDescriptor.FieldType type, String val)
        {
            switch (type)
            {
                case ClassDescriptor.FieldType.tpBoolean:
                    return new Key(Int32.Parse(val) != 0);

                case ClassDescriptor.FieldType.tpByte:
                    return new Key(Byte.Parse(val));

                case ClassDescriptor.FieldType.tpSByte:
                    return new Key(SByte.Parse(val));

                case ClassDescriptor.FieldType.tpChar:
                    return new Key((char)Int32.Parse(val));

                case ClassDescriptor.FieldType.tpShort:
                    return new Key(Int16.Parse(val));

                case ClassDescriptor.FieldType.tpUShort:
                    return new Key(UInt16.Parse(val));

                case ClassDescriptor.FieldType.tpInt:
                    return new Key(Int32.Parse(val));

                case ClassDescriptor.FieldType.tpUInt:
                case ClassDescriptor.FieldType.tpEnum:
                    return new Key(UInt32.Parse(val));

                case ClassDescriptor.FieldType.tpOid:
                    return new Key(ClassDescriptor.FieldType.tpOid, mapId((int)UInt32.Parse(val)));
                case ClassDescriptor.FieldType.tpObject:
                    return new Key(new PersistentStub(db, mapId((int)UInt32.Parse(val))));

                case ClassDescriptor.FieldType.tpLong:
                    return new Key(Int64.Parse(val));

                case ClassDescriptor.FieldType.tpULong:
                    return new Key(UInt64.Parse(val));

                case ClassDescriptor.FieldType.tpFloat:
                    return new Key(Single.Parse(val));

                case ClassDescriptor.FieldType.tpDouble:
                    return new Key(Double.Parse(val));

                case ClassDescriptor.FieldType.tpDecimal:
                    return new Key(Decimal.Parse(val));

                case ClassDescriptor.FieldType.tpGuid:
                    return new Key(new Guid(val));

                case ClassDescriptor.FieldType.tpString:
                    return new Key(val);

                case ClassDescriptor.FieldType.tpArrayOfByte:
                    {
                        byte[] buf = new byte[val.Length >> 1];
                        for (int i = 0; i < buf.Length; i++)
                        {
                            buf[i] = (byte)((getHexValue(val[i * 2]) << 4) | getHexValue(val[i * 2 + 1]));
                        }
                        return new Key(buf);
                    }

                case ClassDescriptor.FieldType.tpDate:
                    return new Key(DateTime.Parse(val));

                default:
                    throwException("Bad key type");
                    break;

            }
            return null;
        }
Exemple #4
0
        Key createCompoundKey(ClassDescriptor.FieldType[] types, String[] values)
        {
            ByteBuffer buf = new ByteBuffer();
            int dst = 0;

            for (int i = 0; i < types.Length; i++)
            {
                String val = values[i];
                switch (types[i])
                {
                    case ClassDescriptor.FieldType.tpBoolean:
                        dst = buf.packBool(dst, Int32.Parse(val) != 0);
                        break;

                    case ClassDescriptor.FieldType.tpByte:
                    case ClassDescriptor.FieldType.tpSByte:
                        dst = buf.packI1(dst, Int32.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpChar:
                    case ClassDescriptor.FieldType.tpShort:
                    case ClassDescriptor.FieldType.tpUShort:
                        dst = buf.packI2(dst, Int32.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpInt:
                        dst = buf.packI4(dst, Int32.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpEnum:
                    case ClassDescriptor.FieldType.tpUInt:
                        dst = buf.packI4(dst, (int)UInt32.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpObject:
                    case ClassDescriptor.FieldType.tpOid:
                        dst = buf.packI4(dst, mapId((int)UInt32.Parse(val)));
                        break;

                    case ClassDescriptor.FieldType.tpLong:
                        dst = buf.packI8(dst, Int64.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpULong:
                        dst = buf.packI8(dst, (long)UInt64.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpDate:
                        dst = buf.packDate(dst, DateTime.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpFloat:
                        dst = buf.packF4(dst, Single.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpDouble:
                        dst = buf.packF8(dst, Double.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpDecimal:
                        dst = buf.packDecimal(dst, Decimal.Parse(val));
                        break;

                    case ClassDescriptor.FieldType.tpGuid:
                        dst = buf.packGuid(dst, new Guid(val));
                        break;

                    case ClassDescriptor.FieldType.tpString:
                        dst = buf.packString(dst, val);
                        break;

                    case ClassDescriptor.FieldType.tpArrayOfByte:
                        buf.extend(dst + 4 + (val.Length >> 1));
                        Bytes.pack4(buf.arr, dst, val.Length >> 1);
                        dst += 4;
                        for (int j = 0, n = val.Length; j < n; j += 2)
                        {
                            buf.arr[dst++] = (byte)((getHexValue(val[j]) << 4) | getHexValue(val[j + 1]));
                        }
                        break;
                    default:
                        throwException("Bad key type");
                        break;
                }
            }
            return new Key(buf.toArray());
        }
Exemple #5
0
 internal static void purge(DatabaseImpl db, int pageId, ClassDescriptor.FieldType type, int height)
 {
     if (--height != 0)
     {
         Page pg = db.getPage(pageId);
         int n = getnItems(pg) + 1;
         if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
         {
             // page of strings
             while (--n >= 0)
             {
                 purge(db, getKeyStrOid(pg, n), type, height);
             }
         }
         else
         {
             while (--n >= 0)
             {
                 purge(db, getReference(pg, maxItems - n - 1), type, height);
             }
         }
         db.pool.unfix(pg);
     }
     db.freePage(pageId);
 }
Exemple #6
0
 public GeneratedSerializer Generate(ClassDescriptor desc)
 {
     ModuleBuilder module = EmitAssemblyModule();
     Type newCls = EmitClass(module, desc);
     return (GeneratedSerializer)module.Assembly.CreateInstance(newCls.Name);
 }
Exemple #7
0
        private void generatePackMethod(ClassDescriptor desc, MethodBuilder builder)
        {
            ILGenerator il = builder.GetILGenerator();
            il.Emit(OpCodes.Ldarg_2); // obj
            il.Emit(OpCodes.Castclass, desc.cls);
            obj = il.DeclareLocal(desc.cls);
            il.Emit(OpCodes.Stloc_0, obj);
            il.Emit(OpCodes.Ldc_I4, ObjectHeader.Sizeof);
            offs = il.DeclareLocal(typeof(int));
            il.Emit(OpCodes.Stloc_1, offs);

            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;

            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                switch (fd.type)
                {
                    case ClassDescriptor.FieldType.tpByte:
                    case ClassDescriptor.FieldType.tpSByte:
                        generatePackField(il, f, packI1);
                        continue;

                    case ClassDescriptor.FieldType.tpBoolean:
                        generatePackField(il, f, packBool);
                        continue;

                    case ClassDescriptor.FieldType.tpShort:
                    case ClassDescriptor.FieldType.tpUShort:
                    case ClassDescriptor.FieldType.tpChar:
                        generatePackField(il, f, packI2);
                        continue;

                    case ClassDescriptor.FieldType.tpEnum:
                    case ClassDescriptor.FieldType.tpInt:
                    case ClassDescriptor.FieldType.tpUInt:
                        generatePackField(il, f, packI4);
                        continue;

                    case ClassDescriptor.FieldType.tpLong:
                    case ClassDescriptor.FieldType.tpULong:
                        generatePackField(il, f, packI8);
                        continue;

                    case ClassDescriptor.FieldType.tpFloat:
                        generatePackField(il, f, packF4);
                        continue;

                    case ClassDescriptor.FieldType.tpDouble:
                        generatePackField(il, f, packF8);
                        continue;

                    case ClassDescriptor.FieldType.tpDecimal:
                        generatePackField(il, f, packDecimal);
                        continue;

                    case ClassDescriptor.FieldType.tpGuid:
                        generatePackField(il, f, packGuid);
                        continue;

                    case ClassDescriptor.FieldType.tpDate:
                        generatePackField(il, f, packDate);
                        continue;

                    case ClassDescriptor.FieldType.tpString:
                        generatePackField(il, f, packString);
                        continue;

                    default:
                        il.Emit(OpCodes.Ldarg_1); // db
                        il.Emit(OpCodes.Ldarg_3); // buf
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldfld, f);
                        il.Emit(OpCodes.Ldnull); // fd
                        il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Call, packField);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;
                }
            }
            il.Emit(OpCodes.Ldloc_1, offs);
            il.Emit(OpCodes.Ret);
        }
Exemple #8
0
        internal void extract(Page pg, int offs, ClassDescriptor.FieldType type)
        {
            byte[] data = pg.data;

            switch (type)
            {
                case ClassDescriptor.FieldType.tpBoolean:
                    key = new Key(data[offs] != 0);
                    break;

                case ClassDescriptor.FieldType.tpSByte:
                    key = new Key((sbyte)data[offs]);
                    break;
                case ClassDescriptor.FieldType.tpByte:
                    key = new Key(data[offs]);
                    break;

                case ClassDescriptor.FieldType.tpShort:
                    key = new Key(Bytes.unpack2(data, offs));
                    break;
                case ClassDescriptor.FieldType.tpUShort:
                    key = new Key((ushort)Bytes.unpack2(data, offs));
                    break;

                case ClassDescriptor.FieldType.tpChar:
                    key = new Key((char)Bytes.unpack2(data, offs));
                    break;

                case ClassDescriptor.FieldType.tpInt:
                    key = new Key(Bytes.unpack4(data, offs));
                    break;
                case ClassDescriptor.FieldType.tpEnum:
                case ClassDescriptor.FieldType.tpUInt:
                case ClassDescriptor.FieldType.tpObject:
                case ClassDescriptor.FieldType.tpOid:
                    key = new Key((uint)Bytes.unpack4(data, offs));
                    break;

                case ClassDescriptor.FieldType.tpLong:
                    key = new Key(Bytes.unpack8(data, offs));
                    break;
                case ClassDescriptor.FieldType.tpDate:
                case ClassDescriptor.FieldType.tpULong:
                    key = new Key((ulong)Bytes.unpack8(data, offs));
                    break;

                case ClassDescriptor.FieldType.tpFloat:
                    key = new Key(Bytes.unpackF4(data, offs));
                    break;

                case ClassDescriptor.FieldType.tpDouble:
                    key = new Key(Bytes.unpackF8(data, offs));
                    break;

                case ClassDescriptor.FieldType.tpGuid:
                    key = new Key(Bytes.unpackGuid(data, offs));
                    break;

                case ClassDescriptor.FieldType.tpDecimal:
                    key = new Key(Bytes.unpackDecimal(data, offs));
                    break;

                default:
                    Debug.Assert(false, "Invalid type");
                    break;

            }
        }
Exemple #9
0
        internal int exportObject(ClassDescriptor desc, byte[] body, int offs, int indent)
        {
            ClassDescriptor.FieldDescriptor[] all = desc.allFields;

            for (int i = 0, n = all.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = all[i];
                FieldInfo f = fd.field;
                indentation(indent);
                String fieldName = exportIdentifier(fd.fieldName);
                writer.Write("<" + fieldName + ">");
                switch (fd.type)
                {
                    case ClassDescriptor.FieldType.tpBoolean:
                        writer.Write(body[offs++] != 0 ? "1" : "0");
                        break;

                    case ClassDescriptor.FieldType.tpByte:
                        writer.Write(System.Convert.ToString((byte)body[offs++]));
                        break;

                    case ClassDescriptor.FieldType.tpSByte:
                        writer.Write(System.Convert.ToString((sbyte)body[offs++]));
                        break;

                    case ClassDescriptor.FieldType.tpChar:
                        writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                        offs += 2;
                        break;

                    case ClassDescriptor.FieldType.tpShort:
                        writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                        offs += 2;
                        break;

                    case ClassDescriptor.FieldType.tpUShort:
                        writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                        offs += 2;
                        break;

                    case ClassDescriptor.FieldType.tpInt:
                        writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs)));
                        offs += 4;
                        break;

                    case ClassDescriptor.FieldType.tpEnum:
                        writer.Write(Enum.ToObject(f.FieldType, Bytes.unpack4(body, offs)));
                        offs += 4;
                        break;

                    case ClassDescriptor.FieldType.tpUInt:
                        writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs)));
                        offs += 4;
                        break;

                    case ClassDescriptor.FieldType.tpLong:
                        writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs)));
                        offs += 8;
                        break;

                    case ClassDescriptor.FieldType.tpULong:
                        writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs)));
                        offs += 8;
                        break;

                    case ClassDescriptor.FieldType.tpFloat:
                        writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs)));
                        offs += 4;
                        break;

                    case ClassDescriptor.FieldType.tpDouble:
                        writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs)));
                        offs += 8;
                        break;

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

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

                    case ClassDescriptor.FieldType.tpString:
                        offs = exportString(body, offs);
                        break;

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

                    case ClassDescriptor.FieldType.tpObject:
                    case ClassDescriptor.FieldType.tpOid:
                        exportRef(Bytes.unpack4(body, offs));
                        offs += 4;
                        break;

                    case ClassDescriptor.FieldType.tpValue:
                        writer.Write('\n');
                        offs = exportObject(fd.valueDesc, body, offs, indent + 1);
                        indentation(indent);
                        break;

                    case ClassDescriptor.FieldType.tpRaw:
                    case ClassDescriptor.FieldType.tpArrayOfByte:
                    case ClassDescriptor.FieldType.tpArrayOfSByte:
                        offs = exportBinary(body, offs);
                        break;

                    case ClassDescriptor.FieldType.tpArrayOfBoolean:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    writer.Write("<element>" + (body[offs++] != 0 ? "1" : "0") + "</element>\n");
                                }
                                indentation(indent);
                            }
                            break;
                        }

                    case ClassDescriptor.FieldType.tpArrayOfChar:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    writer.Write("<element>" + (Bytes.unpack2(body, offs) & 0xFFFF) + "</element>\n");
                                    offs += 2;
                                }
                                indentation(indent);
                            }
                            break;
                        }

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

                    case ClassDescriptor.FieldType.tpArrayOfUShort:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    writer.Write("<element>" + (ushort)Bytes.unpack2(body, offs) + "</element>\n");
                                    offs += 2;
                                }
                                indentation(indent);
                            }
                            break;
                        }

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

                    case ClassDescriptor.FieldType.tpArrayOfEnum:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                Type elemType = f.FieldType.GetElementType();
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    writer.Write("<element>" + Enum.ToObject(elemType, Bytes.unpack4(body, offs)) + "</element>\n");
                                    offs += 4;
                                }
                                indentation(indent);
                            }
                            break;
                        }

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

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

                    case ClassDescriptor.FieldType.tpArrayOfULong:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    writer.Write("<element>" + (ulong)Bytes.unpack8(body, offs) + "</element>\n");
                                    offs += 8;
                                }
                                indentation(indent);
                            }
                            break;
                        }

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

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

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

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

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

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

                    case ClassDescriptor.FieldType.tpLink:
                    case ClassDescriptor.FieldType.tpArrayOfObject:
                    case ClassDescriptor.FieldType.tpArrayOfOid:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    int oid = Bytes.unpack4(body, offs);
                                    if (oid != 0 && (exportedBitmap[oid >> 5] & (1 << (oid & 31))) == 0)
                                    {
                                        markedBitmap[oid >> 5] |= 1 << (oid & 31);
                                    }
                                    writer.Write("<element><ref id=\"" + oid + "\"/></element>\n");
                                    offs += 4;
                                }
                                indentation(indent);
                            }
                            break;
                        }

                    case ClassDescriptor.FieldType.tpArrayOfValue:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    writer.Write("<element>\n");
                                    offs = exportObject(fd.valueDesc, body, offs, indent + 2);
                                    indentation(indent + 1);
                                    writer.Write("</element>\n");
                                }
                                indentation(indent);
                            }
                            break;
                        }

                    case ClassDescriptor.FieldType.tpArrayOfRaw:
                        {
                            int len = Bytes.unpack4(body, offs);
                            offs += 4;
                            if (len < 0)
                            {
                                writer.Write("null");
                            }
                            else
                            {
                                writer.Write('\n');
                                while (--len >= 0)
                                {
                                    indentation(indent + 1);
                                    writer.Write("<element>");
                                    offs = exportBinary(body, offs);
                                    writer.Write("</element>\n");
                                }
                                indentation(indent);
                            }
                            break;
                        }
                }
                writer.Write("</" + fieldName + ">\n");
            }
            return offs;
        }
Exemple #10
0
 internal void exportAssoc(int oid, byte[] body, int offs, int size, ClassDescriptor.FieldType type)
 {
     writer.Write("  <ref id=\"" + oid + "\"");
     if ((exportedBitmap[oid >> 5] & (1 << (oid & 31))) == 0)
     {
         markedBitmap[oid >> 5] |= 1 << (oid & 31);
     }
     if (compoundKeyTypes != null)
     {
         exportCompoundKey(body, offs, size, type);
     }
     else
     {
         writer.Write(" key=\"");
         exportKey(body, offs, size, type);
         writer.Write("\"");
     }
     writer.Write("/>\n");
 }
Exemple #11
0
        internal static OldBtreeResult handlePageUnderflow(DatabaseImpl db, Page pg, int r, ClassDescriptor.FieldType type, OldBtreeKey rem, int height)
        {
            int nItems = getnItems(pg);
            if (type == ClassDescriptor.FieldType.tpString)
            {
                Page a = db.putPage(getKeyStrOid(pg, r));
                int an = getnItems(a);
                if (r < nItems)
                {
                    // exists greater page
                    Page b = db.getPage(getKeyStrOid(pg, r + 1));
                    int bn = getnItems(b);
                    int merged_size = (an + bn) * strKeySize + getSize(a) + getSize(b);
                    if (height != 1)
                    {
                        merged_size += getKeyStrSize(pg, r) * 2 + strKeySize * 2;
                    }
                    if (merged_size > keySpace)
                    {
                        // reallocation of nodes between pages a and b
                        int i, j, k;
                        db.pool.unfix(b);
                        b = db.putPage(getKeyStrOid(pg, r + 1));
                        int size_a = getSize(a);
                        int size_b = getSize(b);
                        int addSize, subSize;
                        if (height != 1)
                        {
                            addSize = getKeyStrSize(pg, r);
                            subSize = getKeyStrSize(b, 0);
                        }
                        else
                        {
                            addSize = subSize = getKeyStrSize(b, 0);
                        }
                        i = 0;
                        int prevDelta = (an * strKeySize + size_a) - (bn * strKeySize + size_b);
                        while (true)
                        {
                            i += 1;
                            int delta = ((an + i) * strKeySize + size_a + addSize * 2) - ((bn - i) * strKeySize + size_b - subSize * 2);
                            if (delta >= 0)
                            {
                                if (delta >= -prevDelta)
                                    i -= 1;
                                break;
                            }
                            size_a += addSize * 2;
                            size_b -= subSize * 2;
                            prevDelta = delta;
                            if (height != 1)
                            {
                                addSize = subSize;
                                subSize = getKeyStrSize(b, i);
                            }
                            else
                            {
                                addSize = subSize = getKeyStrSize(b, i);
                            }
                        }
                        OldBtreeResult result = OldBtreeResult.Done;
                        if (i > 0)
                        {
                            k = i;
                            if (height != 1)
                            {
                                int len = getKeyStrSize(pg, r);
                                setSize(a, getSize(a) + len * 2);
                                setKeyStrOffs(a, an, keySpace - getSize(a));
                                setKeyStrSize(a, an, len);
                                memcpy(a, getKeyStrOffs(a, an), pg, getKeyStrOffs(pg, r), len * 2, 1);
                                k -= 1;
                                an += 1;
                                setKeyStrOid(a, an + k, getKeyStrOid(b, k));
                                setSize(b, getSize(b) - getKeyStrSize(b, k) * 2);
                            }
                            for (j = 0; j < k; j++)
                            {
                                int len = getKeyStrSize(b, j);
                                setSize(a, getSize(a) + len * 2);
                                setSize(b, getSize(b) - len * 2);
                                setKeyStrOffs(a, an, keySpace - getSize(a));
                                setKeyStrSize(a, an, len);
                                setKeyStrOid(a, an, getKeyStrOid(b, j));
                                memcpy(a, getKeyStrOffs(a, an), b, getKeyStrOffs(b, j), len * 2, 1);
                                an += 1;
                            }
                            rem.getStr(b, i - 1);
                            result = replaceStrKey(db, pg, r, rem, height);
                            setnItems(a, an);
                            setnItems(b, compactifyStrings(b, i));
                        }
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return result;
                    }
                    else
                    {
                        // merge page b to a
                        if (height != 1)
                        {
                            int r_len = getKeyStrSize(pg, r);
                            setKeyStrSize(a, an, r_len);
                            setSize(a, getSize(a) + r_len * 2);
                            setKeyStrOffs(a, an, keySpace - getSize(a));
                            memcpy(a, getKeyStrOffs(a, an), pg, getKeyStrOffs(pg, r), r_len * 2, 1);
                            an += 1;
                            setKeyStrOid(a, an + bn, getKeyStrOid(b, bn));
                        }
                        for (int i = 0; i < bn; i++, an++)
                        {
                            setKeyStrSize(a, an, getKeyStrSize(b, i));
                            setKeyStrOffs(a, an, getKeyStrOffs(b, i) - getSize(a));
                            setKeyStrOid(a, an, getKeyStrOid(b, i));
                        }
                        setSize(a, getSize(a) + getSize(b));
                        setnItems(a, an);
                        memcpy(a, keySpace - getSize(a), b, keySpace - getSize(b), getSize(b), 1);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        db.freePage(getKeyStrOid(pg, r + 1));
                        setKeyStrOid(pg, r + 1, getKeyStrOid(pg, r));
                        return removeStrKey(pg, r);
                    }
                }
                else
                {
                    // page b is before a
                    Page b = db.getPage(getKeyStrOid(pg, r - 1));
                    int bn = getnItems(b);
                    int merged_size = (an + bn) * strKeySize + getSize(a) + getSize(b);
                    if (height != 1)
                        merged_size += getKeyStrSize(pg, r - 1) * 2 + strKeySize * 2;

                    if (merged_size > keySpace)
                    {
                        // reallocation of nodes between pages a and b
                        int i, j, k, len;
                        db.pool.unfix(b);
                        b = db.putPage(getKeyStrOid(pg, r - 1));
                        int size_a = getSize(a);
                        int size_b = getSize(b);
                        int addSize, subSize;
                        if (height != 1)
                        {
                            addSize = getKeyStrSize(pg, r - 1);
                            subSize = getKeyStrSize(b, bn - 1);
                        }
                        else
                        {
                            addSize = subSize = getKeyStrSize(b, bn - 1);
                        }
                        i = 0;
                        int prevDelta = (an * strKeySize + size_a) - (bn * strKeySize + size_b);
                        while (true)
                        {
                            i += 1;
                            int delta = ((an + i) * strKeySize + size_a + addSize * 2) - ((bn - i) * strKeySize + size_b - subSize * 2);
                            if (delta >= 0)
                            {
                                if (delta >= -prevDelta)
                                    i -= 1;
                                break;
                            }
                            prevDelta = delta;
                            size_a += addSize * 2;
                            size_b -= subSize * 2;
                            if (height != 1)
                            {
                                addSize = subSize;
                                subSize = getKeyStrSize(b, bn - i - 1);
                            }
                            else
                            {
                                addSize = subSize = getKeyStrSize(b, bn - i - 1);
                            }
                        }
                        OldBtreeResult result = OldBtreeResult.Done;
                        if (i > 0)
                        {
                            k = i;
                            Debug.Assert(i < bn);
                            if (height != 1)
                            {
                                setSize(b, getSize(b) - getKeyStrSize(b, bn - k) * 2);
                                memcpy(a, i, a, 0, an + 1, strKeySize);
                                k -= 1;
                                setKeyStrOid(a, k, getKeyStrOid(b, bn));
                                len = getKeyStrSize(pg, r - 1);
                                setKeyStrSize(a, k, len);
                                setSize(a, getSize(a) + len * 2);
                                setKeyStrOffs(a, k, keySpace - getSize(a));
                                memcpy(a, getKeyStrOffs(a, k), pg, getKeyStrOffs(pg, r - 1), len * 2, 1);
                            }
                            else
                            {
                                memcpy(a, i, a, 0, an, strKeySize);
                            }
                            for (j = 0; j < k; j++)
                            {
                                len = getKeyStrSize(b, bn - k + j);
                                setSize(a, getSize(a) + len * 2);
                                setSize(b, getSize(b) - len * 2);
                                setKeyStrOffs(a, j, keySpace - getSize(a));
                                setKeyStrSize(a, j, len);
                                setKeyStrOid(a, j, getKeyStrOid(b, bn - k + j));
                                memcpy(a, getKeyStrOffs(a, j), b, getKeyStrOffs(b, bn - k + j), len * 2, 1);
                            }
                            an += i;
                            setnItems(a, an);
                            rem.getStr(b, bn - k - 1);
                            result = replaceStrKey(db, pg, r - 1, rem, height);
                            setnItems(b, compactifyStrings(b, -i));
                        }
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return result;
                    }
                    else
                    {
                        // merge page b to a
                        if (height != 1)
                        {
                            memcpy(a, bn + 1, a, 0, an + 1, strKeySize);
                            int len = getKeyStrSize(pg, r - 1);
                            setKeyStrSize(a, bn, len);
                            setSize(a, getSize(a) + len * 2);
                            setKeyStrOffs(a, bn, keySpace - getSize(a));
                            setKeyStrOid(a, bn, getKeyStrOid(b, bn));
                            memcpy(a, getKeyStrOffs(a, bn), pg, getKeyStrOffs(pg, r - 1), len * 2, 1);
                            an += 1;
                        }
                        else
                        {
                            memcpy(a, bn, a, 0, an, strKeySize);
                        }
                        for (int i = 0; i < bn; i++)
                        {
                            setKeyStrOid(a, i, getKeyStrOid(b, i));
                            setKeyStrSize(a, i, getKeyStrSize(b, i));
                            setKeyStrOffs(a, i, getKeyStrOffs(b, i) - getSize(a));
                        }
                        an += bn;
                        setnItems(a, an);
                        setSize(a, getSize(a) + getSize(b));
                        memcpy(a, keySpace - getSize(a), b, keySpace - getSize(b), getSize(b), 1);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        db.freePage(getKeyStrOid(pg, r - 1));
                        return removeStrKey(pg, r - 1);
                    }
                }
            }
            else if (type == ClassDescriptor.FieldType.tpArrayOfByte)
            {
                Page a = db.putPage(getKeyStrOid(pg, r));
                int an = getnItems(a);
                if (r < nItems)
                {
                    // exists greater page
                    Page b = db.getPage(getKeyStrOid(pg, r + 1));
                    int bn = getnItems(b);
                    int merged_size = (an + bn) * strKeySize + getSize(a) + getSize(b);
                    if (height != 1)
                    {
                        merged_size += getKeyStrSize(pg, r) + strKeySize * 2;
                    }
                    if (merged_size > keySpace)
                    {
                        // reallocation of nodes between pages a and b
                        int i, j, k;
                        db.pool.unfix(b);
                        b = db.putPage(getKeyStrOid(pg, r + 1));
                        int size_a = getSize(a);
                        int size_b = getSize(b);
                        int addSize, subSize;
                        if (height != 1)
                        {
                            addSize = getKeyStrSize(pg, r);
                            subSize = getKeyStrSize(b, 0);
                        }
                        else
                        {
                            addSize = subSize = getKeyStrSize(b, 0);
                        }
                        i = 0;
                        int prevDelta = (an * strKeySize + size_a) - (bn * strKeySize + size_b);
                        while (true)
                        {
                            i += 1;
                            int delta = ((an + i) * strKeySize + size_a + addSize) - ((bn - i) * strKeySize + size_b - subSize);
                            if (delta >= 0)
                            {
                                if (delta >= -prevDelta)
                                    i -= 1;

                                break;
                            }
                            size_a += addSize;
                            size_b -= subSize;
                            prevDelta = delta;
                            if (height != 1)
                            {
                                addSize = subSize;
                                subSize = getKeyStrSize(b, i);
                            }
                            else
                            {
                                addSize = subSize = getKeyStrSize(b, i);
                            }
                        }
                        OldBtreeResult result = OldBtreeResult.Done;
                        if (i > 0)
                        {
                            k = i;
                            if (height != 1)
                            {
                                int len = getKeyStrSize(pg, r);
                                setSize(a, getSize(a) + len);
                                setKeyStrOffs(a, an, keySpace - getSize(a));
                                setKeyStrSize(a, an, len);
                                memcpy(a, getKeyStrOffs(a, an), pg, getKeyStrOffs(pg, r), len, 1);
                                k -= 1;
                                an += 1;
                                setKeyStrOid(a, an + k, getKeyStrOid(b, k));
                                setSize(b, getSize(b) - getKeyStrSize(b, k));
                            }
                            for (j = 0; j < k; j++)
                            {
                                int len = getKeyStrSize(b, j);
                                setSize(a, getSize(a) + len);
                                setSize(b, getSize(b) - len);
                                setKeyStrOffs(a, an, keySpace - getSize(a));
                                setKeyStrSize(a, an, len);
                                setKeyStrOid(a, an, getKeyStrOid(b, j));
                                memcpy(a, getKeyStrOffs(a, an), b, getKeyStrOffs(b, j), len, 1);
                                an += 1;
                            }
                            rem.getByteArray(b, i - 1);
                            result = replaceByteArrayKey(db, pg, r, rem, height);
                            setnItems(a, an);
                            setnItems(b, compactifyByteArrays(b, i));
                        }
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return result;
                    }
                    else
                    {
                        // merge page b to a
                        if (height != 1)
                        {
                            int r_len = getKeyStrSize(pg, r);
                            setKeyStrSize(a, an, r_len);
                            setSize(a, getSize(a) + r_len);
                            setKeyStrOffs(a, an, keySpace - getSize(a));
                            memcpy(a, getKeyStrOffs(a, an), pg, getKeyStrOffs(pg, r), r_len, 1);
                            an += 1;
                            setKeyStrOid(a, an + bn, getKeyStrOid(b, bn));
                        }
                        for (int i = 0; i < bn; i++, an++)
                        {
                            setKeyStrSize(a, an, getKeyStrSize(b, i));
                            setKeyStrOffs(a, an, getKeyStrOffs(b, i) - getSize(a));
                            setKeyStrOid(a, an, getKeyStrOid(b, i));
                        }
                        setSize(a, getSize(a) + getSize(b));
                        setnItems(a, an);
                        memcpy(a, keySpace - getSize(a), b, keySpace - getSize(b), getSize(b), 1);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        db.freePage(getKeyStrOid(pg, r + 1));
                        setKeyStrOid(pg, r + 1, getKeyStrOid(pg, r));
                        return removeByteArrayKey(pg, r);
                    }
                }
                else
                {
                    // page b is before a
                    Page b = db.getPage(getKeyStrOid(pg, r - 1));
                    int bn = getnItems(b);
                    int merged_size = (an + bn) * strKeySize + getSize(a) + getSize(b);
                    if (height != 1)
                        merged_size += getKeyStrSize(pg, r - 1) + strKeySize * 2;

                    if (merged_size > keySpace)
                    {
                        // reallocation of nodes between pages a and b
                        int i, j, k, len;
                        db.pool.unfix(b);
                        b = db.putPage(getKeyStrOid(pg, r - 1));
                        int size_a = getSize(a);
                        int size_b = getSize(b);
                        int addSize, subSize;
                        if (height != 1)
                        {
                            addSize = getKeyStrSize(pg, r - 1);
                            subSize = getKeyStrSize(b, bn - 1);
                        }
                        else
                        {
                            addSize = subSize = getKeyStrSize(b, bn - 1);
                        }
                        i = 0;
                        int prevDelta = (an * strKeySize + size_a) - (bn * strKeySize + size_b);
                        while (true)
                        {
                            i += 1;
                            int delta = ((an + i) * strKeySize + size_a + addSize) - ((bn - i) * strKeySize + size_b - subSize);
                            if (delta >= 0)
                            {
                                if (delta >= -prevDelta)
                                    i -= 1;
                                break;
                            }
                            prevDelta = delta;
                            size_a += addSize;
                            size_b -= subSize;
                            if (height != 1)
                            {
                                addSize = subSize;
                                subSize = getKeyStrSize(b, bn - i - 1);
                            }
                            else
                            {
                                addSize = subSize = getKeyStrSize(b, bn - i - 1);
                            }
                        }
                        OldBtreeResult result = OldBtreeResult.Done;
                        if (i > 0)
                        {
                            k = i;
                            Debug.Assert(i < bn);
                            if (height != 1)
                            {
                                setSize(b, getSize(b) - getKeyStrSize(b, bn - k));
                                memcpy(a, i, a, 0, an + 1, strKeySize);
                                k -= 1;
                                setKeyStrOid(a, k, getKeyStrOid(b, bn));
                                len = getKeyStrSize(pg, r - 1);
                                setKeyStrSize(a, k, len);
                                setSize(a, getSize(a) + len);
                                setKeyStrOffs(a, k, keySpace - getSize(a));
                                memcpy(a, getKeyStrOffs(a, k), pg, getKeyStrOffs(pg, r - 1), len, 1);
                            }
                            else
                            {
                                memcpy(a, i, a, 0, an, strKeySize);
                            }
                            for (j = 0; j < k; j++)
                            {
                                len = getKeyStrSize(b, bn - k + j);
                                setSize(a, getSize(a) + len);
                                setSize(b, getSize(b) - len);
                                setKeyStrOffs(a, j, keySpace - getSize(a));
                                setKeyStrSize(a, j, len);
                                setKeyStrOid(a, j, getKeyStrOid(b, bn - k + j));
                                memcpy(a, getKeyStrOffs(a, j), b, getKeyStrOffs(b, bn - k + j), len, 1);
                            }
                            an += i;
                            setnItems(a, an);
                            rem.getByteArray(b, bn - k - 1);
                            result = replaceByteArrayKey(db, pg, r - 1, rem, height);
                            setnItems(b, compactifyByteArrays(b, -i));
                        }
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return result;
                    }
                    else
                    {
                        // merge page b to a
                        if (height != 1)
                        {
                            memcpy(a, bn + 1, a, 0, an + 1, strKeySize);
                            int len = getKeyStrSize(pg, r - 1);
                            setKeyStrSize(a, bn, len);
                            setSize(a, getSize(a) + len);
                            setKeyStrOffs(a, bn, keySpace - getSize(a));
                            setKeyStrOid(a, bn, getKeyStrOid(b, bn));
                            memcpy(a, getKeyStrOffs(a, bn), pg, getKeyStrOffs(pg, r - 1), len, 1);
                            an += 1;
                        }
                        else
                        {
                            memcpy(a, bn, a, 0, an, strKeySize);
                        }
                        for (int i = 0; i < bn; i++)
                        {
                            setKeyStrOid(a, i, getKeyStrOid(b, i));
                            setKeyStrSize(a, i, getKeyStrSize(b, i));
                            setKeyStrOffs(a, i, getKeyStrOffs(b, i) - getSize(a));
                        }
                        an += bn;
                        setnItems(a, an);
                        setSize(a, getSize(a) + getSize(b));
                        memcpy(a, keySpace - getSize(a), b, keySpace - getSize(b), getSize(b), 1);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        db.freePage(getKeyStrOid(pg, r - 1));
                        return removeByteArrayKey(pg, r - 1);
                    }
                }
            }
            else
            {
                Page a = db.putPage(getReference(pg, maxItems - r - 1));
                int an = getnItems(a);
                int itemSize = ClassDescriptor.Sizeof[(int)type];
                if (r < nItems)
                {
                    // exists greater page
                    Page b = db.getPage(getReference(pg, maxItems - r - 2));
                    int bn = getnItems(b);
                    Debug.Assert(bn >= an);
                    if (height != 1)
                    {
                        memcpy(a, an, pg, r, 1, itemSize);
                        an += 1;
                        bn += 1;
                    }
                    int merged_size = (an + bn) * (4 + itemSize);
                    if (merged_size > keySpace)
                    {
                        // reallocation of nodes between pages a and b
                        int i = bn - ((an + bn) >> 1);
                        db.pool.unfix(b);
                        b = db.putPage(getReference(pg, maxItems - r - 2));
                        memcpy(a, an, b, 0, i, itemSize);
                        memcpy(b, 0, b, i, bn - i, itemSize);
                        memcpy(a, maxItems - an - i, b, maxItems - i, i, 4);
                        memcpy(b, maxItems - bn + i, b, maxItems - bn, bn - i, 4);
                        memcpy(pg, r, a, an + i - 1, 1, itemSize);
                        setnItems(b, getnItems(b) - i);
                        setnItems(a, getnItems(a) + i);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return OldBtreeResult.Done;
                    }
                    else
                    {
                        // merge page b to a
                        memcpy(a, an, b, 0, bn, itemSize);
                        memcpy(a, maxItems - an - bn, b, maxItems - bn, bn, 4);
                        db.freePage(getReference(pg, maxItems - r - 2));
                        memcpy(pg, maxItems - nItems, pg, maxItems - nItems - 1, nItems - r - 1, 4);
                        memcpy(pg, r, pg, r + 1, nItems - r - 1, itemSize);
                        setnItems(a, getnItems(a) + bn);
                        setnItems(pg, nItems - 1);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return nItems * (itemSize + 4) < keySpace / 2 ? OldBtreeResult.Underflow : OldBtreeResult.Done;
                    }
                }
                else
                {
                    // page b is before a
                    Page b = db.getPage(getReference(pg, maxItems - r));
                    int bn = getnItems(b);
                    Debug.Assert(bn >= an);
                    if (height != 1)
                    {
                        an += 1;
                        bn += 1;
                    }
                    int merged_size = (an + bn) * (4 + itemSize);
                    if (merged_size > keySpace)
                    {
                        // reallocation of nodes between pages a and b
                        int i = bn - ((an + bn) >> 1);
                        db.pool.unfix(b);
                        b = db.putPage(getReference(pg, maxItems - r));
                        memcpy(a, i, a, 0, an, itemSize);
                        memcpy(a, 0, b, bn - i, i, itemSize);
                        memcpy(a, maxItems - an - i, a, maxItems - an, an, 4);
                        memcpy(a, maxItems - i, b, maxItems - bn, i, 4);
                        if (height != 1)
                        {
                            memcpy(a, i - 1, pg, r - 1, 1, itemSize);
                        }
                        memcpy(pg, r - 1, b, bn - i - 1, 1, itemSize);
                        setnItems(b, getnItems(b) - i);
                        setnItems(a, getnItems(a) + i);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return OldBtreeResult.Done;
                    }
                    else
                    {
                        // merge page b to a
                        memcpy(a, bn, a, 0, an, itemSize);
                        memcpy(a, 0, b, 0, bn, itemSize);
                        memcpy(a, maxItems - an - bn, a, maxItems - an, an, 4);
                        memcpy(a, maxItems - bn, b, maxItems - bn, bn, 4);
                        if (height != 1)
                            memcpy(a, bn - 1, pg, r - 1, 1, itemSize);

                        db.freePage(getReference(pg, maxItems - r));
                        setReference(pg, maxItems - r, getReference(pg, maxItems - r - 1));
                        setnItems(a, getnItems(a) + bn);
                        setnItems(pg, nItems - 1);
                        db.pool.unfix(a);
                        db.pool.unfix(b);
                        return nItems * (itemSize + 4) < keySpace / 2 ? OldBtreeResult.Underflow : OldBtreeResult.Done;
                    }
                }
            }
        }
Exemple #12
0
 internal static void exportPage(DatabaseImpl db, XmlExporter exporter, int pageId, ClassDescriptor.FieldType type, int height)
 {
     Page pg = db.getPage(pageId);
     try
     {
         int i, n = getnItems(pg);
         if (--height != 0)
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             {
                 // page of strings
                 for (i = 0; i <= n; i++)
                 {
                     exportPage(db, exporter, getKeyStrOid(pg, i), type, height);
                 }
             }
             else
             {
                 for (i = 0; i <= n; i++)
                 {
                     exportPage(db, exporter, getReference(pg, maxItems - i - 1), type, height);
                 }
             }
         }
         else
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             {
                 // page of strings
                 for (i = 0; i < n; i++)
                 {
                     exporter.exportAssoc(getKeyStrOid(pg, i), pg.data, OldBtreePage.firstKeyOffs + OldBtreePage.getKeyStrOffs(pg, i), OldBtreePage.getKeyStrSize(pg, i), type);
                 }
             }
             else
             {
                 // page of scalars
                 for (i = 0; i < n; i++)
                 {
                     exporter.exportAssoc(getReference(pg, maxItems - 1 - i), pg.data, OldBtreePage.firstKeyOffs + i * ClassDescriptor.Sizeof[(int)type], ClassDescriptor.Sizeof[(int)type], type);
                 }
             }
         }
     }
     finally
     {
         db.pool.unfix(pg);
     }
 }
Exemple #13
0
 internal static int traverseForward(DatabaseImpl db, int pageId, ClassDescriptor.FieldType type, int height, IPersistent[] result, int pos)
 {
     Page pg = db.getPage(pageId);
     int oid;
     try
     {
         int i, n = getnItems(pg);
         if (--height != 0)
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             {
                 // page of strings
                 for (i = 0; i <= n; i++)
                 {
                     pos = traverseForward(db, getKeyStrOid(pg, i), type, height, result, pos);
                 }
             }
             else
             {
                 for (i = 0; i <= n; i++)
                 {
                     pos = traverseForward(db, getReference(pg, maxItems - i - 1), type, height, result, pos);
                 }
             }
         }
         else
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             {
                 // page of strings
                 for (i = 0; i < n; i++)
                 {
                     oid = getKeyStrOid(pg, i);
                     result[pos++] = db.lookupObject(oid, null);
                 }
             }
             else
             {
                 // page of scalars
                 for (i = 0; i < n; i++)
                 {
                     oid = getReference(pg, maxItems - 1 - i);
                     result[pos++] = db.lookupObject(oid, null);
                 }
             }
         }
         return pos;
     }
     finally
     {
         db.pool.unfix(pg);
     }
 }
Exemple #14
0
 public bool equals(ClassDescriptor cd)
 {
     if (cd == null || allFields.Length != cd.allFields.Length)
     {
         return false;
     }
     for (int i = 0; i < allFields.Length; i++)
     {
         if (!allFields[i].equals(cd.allFields[i]))
         {
             return false;
         }
     }
     return true;
 }
Exemple #15
0
 void exportCompoundKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type)
 {
     Debug.Assert(type == ClassDescriptor.FieldType.tpArrayOfByte);
     int end = offs + size;
     for (int i = 0; i < compoundKeyTypes.Length; i++)
     {
         type = compoundKeyTypes[i];
         if (type == ClassDescriptor.FieldType.tpArrayOfByte || type == ClassDescriptor.FieldType.tpString)
         {
             size = Bytes.unpack4(body, offs);
             offs += 4;
         }
         writer.Write(" key" + i + "=\"");
         offs = exportKey(body, offs, size, type);
         writer.Write("\"");
     }
     Debug.Assert(offs == end);
 }
Exemple #16
0
        internal void resolve()
        {
            if (resolved)
                return;

            DatabaseImpl classStorage = (DatabaseImpl)Database;
            ClassDescriptor desc = new ClassDescriptor(classStorage, cls);
            resolved = true;
            if (!desc.equals(this))
            {
                classStorage.registerClassDescriptor(desc);
            }
        }
Exemple #17
0
        int exportKey(byte[] body, int offs, int size, ClassDescriptor.FieldType type)
        {
            switch (type)
            {
                case ClassDescriptor.FieldType.tpBoolean:
                    writer.Write(body[offs++] != 0 ? "1" : "0");
                    break;

                case ClassDescriptor.FieldType.tpByte:
                    writer.Write(System.Convert.ToString((byte)body[offs++]));
                    break;

                case ClassDescriptor.FieldType.tpSByte:
                    writer.Write(System.Convert.ToString((sbyte)body[offs++]));
                    break;

                case ClassDescriptor.FieldType.tpChar:
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpShort:
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpUShort:
                    writer.Write(System.Convert.ToString((ushort)Bytes.unpack2(body, offs)));
                    offs += 2;
                    break;

                case ClassDescriptor.FieldType.tpInt:
                    writer.Write(System.Convert.ToString(Bytes.unpack4(body, offs)));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpUInt:
                case ClassDescriptor.FieldType.tpObject:
                case ClassDescriptor.FieldType.tpOid:
                case ClassDescriptor.FieldType.tpEnum:
                    writer.Write(System.Convert.ToString((uint)Bytes.unpack4(body, offs)));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpLong:
                    writer.Write(System.Convert.ToString(Bytes.unpack8(body, offs)));
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpULong:
                    writer.Write(System.Convert.ToString((ulong)Bytes.unpack8(body, offs)));
                    offs += 8;
                    break;

                case ClassDescriptor.FieldType.tpFloat:
                    writer.Write(System.Convert.ToString(Bytes.unpackF4(body, offs)));
                    offs += 4;
                    break;

                case ClassDescriptor.FieldType.tpDouble:
                    writer.Write(System.Convert.ToString(Bytes.unpackF8(body, offs)));
                    offs += 8;
                    break;

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

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

                case ClassDescriptor.FieldType.tpString:

                    if (size < 0)
                    {
                        string s;
                        offs = Bytes.unpackString(body, offs - 4, out s);
                        for (int i = 0; i < s.Length; i++)
                        {
                            exportChar(s[i]);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < size; i++)
                        {
                            exportChar((char)Bytes.unpack2(body, offs));
                            offs += 2;
                        }
                    }
                    break;

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

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

                default:
                    Debug.Assert(false, "Invalid type");
                    break;
            }
            return offs;
        }
Exemple #18
0
 private void generateNewMethod(ClassDescriptor desc, MethodBuilder builder)
 {
     ILGenerator il = builder.GetILGenerator();
     il.Emit(OpCodes.Newobj, desc.defaultConstructor);
     il.Emit(OpCodes.Ret);
 }
        private void generateUnpackMethod(ClassDescriptor desc, MethodBuilder builder)
        {
            ILGenerator il = builder.GetILGenerator();

            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Castclass, desc.cls);
            LocalBuilder obj = il.DeclareLocal(desc.cls);

            il.Emit(OpCodes.Stloc_0, obj);
            il.Emit(OpCodes.Ldc_I4, ObjectHeader.Sizeof);
            LocalBuilder offs = il.DeclareLocal(typeof(int));

            il.Emit(OpCodes.Stloc_1, offs);
            LocalBuilder val = il.DeclareLocal(typeof(object));

            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;

            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                if (f == null)
                {
                    switch (fd.type)
                    {
                    case ClassDescriptor.FieldType.tpByte:
                    case ClassDescriptor.FieldType.tpSByte:
                    case ClassDescriptor.FieldType.tpBoolean:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpShort:
                    case ClassDescriptor.FieldType.tpUShort:
                    case ClassDescriptor.FieldType.tpChar:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_2);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpEnum:
                    case ClassDescriptor.FieldType.tpInt:
                    case ClassDescriptor.FieldType.tpUInt:
                    case ClassDescriptor.FieldType.tpFloat:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_4);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpLong:
                    case ClassDescriptor.FieldType.tpULong:
                    case ClassDescriptor.FieldType.tpDate:
                    case ClassDescriptor.FieldType.tpDouble:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_8);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpDecimal:
                    case ClassDescriptor.FieldType.tpGuid:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4, 16);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    default:
                        il.Emit(OpCodes.Ldarg_1);    // db
                        il.Emit(OpCodes.Ldarg_3);    // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldnull);     // fd
                        il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                        il.Emit(OpCodes.Call, skipField);
                        il.Emit(OpCodes.Stloc_1, offs);     // offs
                        continue;
                    }
                }
                else
                {
                    switch (fd.type)
                    {
                    case ClassDescriptor.FieldType.tpByte:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldelem_U1);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpSByte:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldelem_U1);
                        il.Emit(OpCodes.Conv_I1);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpBoolean:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldelem_U1);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpShort:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackI2);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_2);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpUShort:
                    case ClassDescriptor.FieldType.tpChar:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackI2);
                        il.Emit(OpCodes.Conv_U2);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_2);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpEnum:
                    case ClassDescriptor.FieldType.tpInt:
                    case ClassDescriptor.FieldType.tpUInt:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackI4);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_4);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpLong:
                    case ClassDescriptor.FieldType.tpULong:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackI8);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_8);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpFloat:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackF4);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_4);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpDouble:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackF8);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_8);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpDecimal:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackDecimal);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4, 16);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpGuid:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackGuid);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4, 16);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpDate:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackDate);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_8);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpString:
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldflda, f);
                        il.Emit(OpCodes.Call, unpackString);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    default:
                        il.Emit(OpCodes.Ldarg_1);    // db
                        il.Emit(OpCodes.Ldarg_3);    // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldarg_S, 4); // recursiveLoading
                        il.Emit(OpCodes.Ldloca, val);
                        il.Emit(OpCodes.Ldnull);     // fd
                        il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Call, unpackField);
                        il.Emit(OpCodes.Stloc_1, offs);     // offs
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldloc, val);
                        il.Emit(OpCodes.Castclass, f.FieldType);
                        il.Emit(OpCodes.Stfld, f);
                        continue;
                    }
                }
            }
            il.Emit(OpCodes.Ret);
        }
Exemple #20
0
        private void generateUnpackMethod(ClassDescriptor desc, MethodBuilder builder)
        {
            ILGenerator il = builder.GetILGenerator();
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Castclass, desc.cls);
            LocalBuilder obj = il.DeclareLocal(desc.cls);
            il.Emit(OpCodes.Stloc_0, obj);
            il.Emit(OpCodes.Ldc_I4, ObjectHeader.Sizeof);
            LocalBuilder offs = il.DeclareLocal(typeof(int));
            il.Emit(OpCodes.Stloc_1, offs);
            LocalBuilder val = il.DeclareLocal(typeof(object));

            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;

            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                if (f == null)
                {
                    switch (fd.type)
                    {
                        case ClassDescriptor.FieldType.tpByte:
                        case ClassDescriptor.FieldType.tpSByte:
                        case ClassDescriptor.FieldType.tpBoolean:
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_1);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpShort:
                        case ClassDescriptor.FieldType.tpUShort:
                        case ClassDescriptor.FieldType.tpChar:
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_2);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpEnum:
                        case ClassDescriptor.FieldType.tpInt:
                        case ClassDescriptor.FieldType.tpUInt:
                        case ClassDescriptor.FieldType.tpFloat:
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_4);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpLong:
                        case ClassDescriptor.FieldType.tpULong:
                        case ClassDescriptor.FieldType.tpDate:
                        case ClassDescriptor.FieldType.tpDouble:
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_8);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpDecimal:
                        case ClassDescriptor.FieldType.tpGuid:
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4, 16);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        default:
                            il.Emit(OpCodes.Ldarg_1); // db
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldnull); // fd
                            il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                            il.Emit(OpCodes.Call, skipField);
                            il.Emit(OpCodes.Stloc_1, offs); // offs
                            continue;
                    }
                }
                else
                {
                    switch (fd.type)
                    {
                        case ClassDescriptor.FieldType.tpByte:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldelem_U1);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_1);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpSByte:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldelem_U1);
                            il.Emit(OpCodes.Conv_I1);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_1);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpBoolean:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldelem_U1);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_1);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpShort:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackI2);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_2);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpUShort:
                        case ClassDescriptor.FieldType.tpChar:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackI2);
                            il.Emit(OpCodes.Conv_U2);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_2);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpEnum:
                        case ClassDescriptor.FieldType.tpInt:
                        case ClassDescriptor.FieldType.tpUInt:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackI4);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_4);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpLong:
                        case ClassDescriptor.FieldType.tpULong:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackI8);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_8);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpFloat:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackF4);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_4);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpDouble:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackF8);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_8);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpDecimal:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackDecimal);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4, 16);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpGuid:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackGuid);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4, 16);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpDate:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackDate);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_8);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpString:
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldflda, f);
                            il.Emit(OpCodes.Call, unpackString);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        default:
                            il.Emit(OpCodes.Ldarg_1); // db
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldarg_S, 4); // recursiveLoading
                            il.Emit(OpCodes.Ldloca, val);
                            il.Emit(OpCodes.Ldnull); // fd
                            il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Call, unpackField);
                            il.Emit(OpCodes.Stloc_1, offs); // offs
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldloc, val);
                            il.Emit(OpCodes.Castclass, f.FieldType);
                            il.Emit(OpCodes.Stfld, f);
                            continue;
                    }
                }
            }
            il.Emit(OpCodes.Ret);
        }
        private void generatePackMethod(ClassDescriptor desc, MethodBuilder builder)
        {
            ILGenerator il = builder.GetILGenerator();

            il.Emit(OpCodes.Ldarg_2); // obj
            il.Emit(OpCodes.Castclass, desc.cls);
            obj = il.DeclareLocal(desc.cls);
            il.Emit(OpCodes.Stloc_0, obj);
            il.Emit(OpCodes.Ldc_I4, ObjectHeader.Sizeof);
            offs = il.DeclareLocal(typeof(int));
            il.Emit(OpCodes.Stloc_1, offs);

            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;

            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                switch (fd.type)
                {
                case ClassDescriptor.FieldType.tpByte:
                case ClassDescriptor.FieldType.tpSByte:
                    generatePackField(il, f, packI1);
                    continue;

                case ClassDescriptor.FieldType.tpBoolean:
                    generatePackField(il, f, packBool);
                    continue;

                case ClassDescriptor.FieldType.tpShort:
                case ClassDescriptor.FieldType.tpUShort:
                case ClassDescriptor.FieldType.tpChar:
                    generatePackField(il, f, packI2);
                    continue;

                case ClassDescriptor.FieldType.tpEnum:
                case ClassDescriptor.FieldType.tpInt:
                case ClassDescriptor.FieldType.tpUInt:
                    generatePackField(il, f, packI4);
                    continue;

                case ClassDescriptor.FieldType.tpLong:
                case ClassDescriptor.FieldType.tpULong:
                    generatePackField(il, f, packI8);
                    continue;

                case ClassDescriptor.FieldType.tpFloat:
                    generatePackField(il, f, packF4);
                    continue;

                case ClassDescriptor.FieldType.tpDouble:
                    generatePackField(il, f, packF8);
                    continue;

                case ClassDescriptor.FieldType.tpDecimal:
                    generatePackField(il, f, packDecimal);
                    continue;

                case ClassDescriptor.FieldType.tpGuid:
                    generatePackField(il, f, packGuid);
                    continue;

                case ClassDescriptor.FieldType.tpDate:
                    generatePackField(il, f, packDate);
                    continue;

                case ClassDescriptor.FieldType.tpString:
                    generatePackField(il, f, packString);
                    continue;

                default:
                    il.Emit(OpCodes.Ldarg_1);     // db
                    il.Emit(OpCodes.Ldarg_3);     // buf
                    il.Emit(OpCodes.Ldloc_1, offs);
                    il.Emit(OpCodes.Ldloc_0, obj);
                    il.Emit(OpCodes.Ldfld, f);
                    il.Emit(OpCodes.Ldnull);     // fd
                    il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                    il.Emit(OpCodes.Ldloc_0, obj);
                    il.Emit(OpCodes.Call, packField);
                    il.Emit(OpCodes.Stloc_1, offs);
                    continue;
                }
            }
            il.Emit(OpCodes.Ldloc_1, offs);
            il.Emit(OpCodes.Ret);
        }
Exemple #22
0
        private Type EmitClass(ModuleBuilder module, ClassDescriptor desc)
        {
            counter += 1;
            String generatedClassName = "GeneratedSerializerClass" + counter;
            TypeBuilder serializerType = module.DefineType(generatedClassName, TypeAttributes.Public);

            Type serializerInterface = typeof(GeneratedSerializer);
            serializerType.AddInterfaceImplementation(serializerInterface);
            //Add a constructor
            //TODO: wasn't used, figure out if was needed
            //ConstructorBuilder constructor =
            //    serializerType.DefineDefaultConstructor(MethodAttributes.Public);

            MethodInfo packInterface = serializerInterface.GetMethod("pack");
            MethodBuilder packBuilder = GetBuilder(serializerType, packInterface);
            generatePackMethod(desc, packBuilder);
            serializerType.DefineMethodOverride(packBuilder, packInterface);

            MethodInfo unpackInterface = serializerInterface.GetMethod("unpack");
            MethodBuilder unpackBuilder = GetBuilder(serializerType, unpackInterface);
            generateUnpackMethod(desc, unpackBuilder);
            serializerType.DefineMethodOverride(unpackBuilder, unpackInterface);

            MethodInfo newInterface = serializerInterface.GetMethod("newInstance");
            MethodBuilder newBuilder = GetBuilder(serializerType, newInterface);
            generateNewMethod(desc, newBuilder);
            serializerType.DefineMethodOverride(newBuilder, newInterface);

            serializerType.CreateType();
            return serializerType;
        }
Exemple #23
0
 internal static int markPage(DatabaseImpl db, int pageId, ClassDescriptor.FieldType type, int height)
 {
     Page pg = db.getGCPage(pageId);
     int nPages = 1;
     try
     {
         int i, n = getnItems(pg);
         if (--height != 0)
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             { // page of strings
                 for (i = 0; i <= n; i++)
                 {
                     nPages += markPage(db, getKeyStrOid(pg, i), type, height);
                 }
             }
             else
             {
                 for (i = 0; i <= n; i++)
                 {
                     nPages += markPage(db, getReference(pg, maxItems - i - 1), type, height);
                 }
             }
         }
         else
         {
             if (type == ClassDescriptor.FieldType.tpString || type == ClassDescriptor.FieldType.tpArrayOfByte)
             { // page of strings
                 for (i = 0; i < n; i++)
                 {
                     db.markOid(getKeyStrOid(pg, i));
                 }
             }
             else
             { // page of scalars
                 for (i = 0; i < n; i++)
                 {
                     db.markOid(getReference(pg, maxItems - 1 - i));
                 }
             }
         }
     }
     finally
     {
         db.pool.unfix(pg);
     }
     return nPages;
 }