internal void CreateIndex(string indexType) { Btree btree = null; int tkn; int oid = 0; bool unique = false; string className = null; string fieldName = null; string[] fieldNames = null; long autoinc = 0; string type = null; while ((tkn = scanner.Scan()) == XMLScanner.XML_IDENT) { string attrName = scanner.Identifier; if (scanner.Scan() != XMLScanner.XML_EQ || scanner.Scan() != XMLScanner.XML_SCONST) { ThrowException("Attribute value expected"); } string attrValue = scanner.String; if (attrName.Equals("id")) { oid = MapId(ParseInt(attrValue)); } else if (attrName.Equals("unique")) { unique = ParseInt(attrValue) != 0; } else if (attrName.Equals("class")) { className = attrValue; } else if (attrName.Equals("type")) { type = attrValue; } else if (attrName.Equals("autoinc")) { autoinc = ParseInt(attrValue); } else if (attrName.StartsWith("field")) { int len = attrName.Length; if (len == 5) { fieldName = attrValue; } else { try { int fieldNo = Int32.Parse(attrName.Substring(5)); if (fieldNames == null || fieldNames.Length <= fieldNo) { string[] newFieldNames = new string[fieldNo + 1]; if (fieldNames != null) { Array.Copy(fieldNames, 0, newFieldNames, 0, fieldNames.Length); } fieldNames = newFieldNames; } fieldNames[fieldNo] = attrValue; } catch (FormatException) { ThrowException("Invalid field index"); } } } } if (tkn != XMLScanner.XML_GT) { ThrowException("Unclosed element tag"); } if (oid == 0) { ThrowException("ID is not specified or index"); } if (className != null) { Type cls = ClassDescriptor.LoadClass(storage, className); if (fieldName != null) { btree = new BtreeFieldIndex(cls, fieldName, unique, autoinc); } else if (fieldNames != null) { btree = new BtreeMultiFieldIndex(cls, fieldNames, unique); } else { ThrowException("Field name is not specified for field index"); } } else { if (type == null) { if (indexType.Equals("TenderBaseImpl.PersistentSet")) { btree = new PersistentSet(); } else { ThrowException("Key type is not specified for index"); } } else { if (indexType.Equals("TenderBaseImpl.BitIndexImpl")) { btree = new BitIndexImpl(); } else { btree = new Btree(MapType(type), unique); } } } storage.AssignOid(btree, oid); while ((tkn = scanner.Scan()) == XMLScanner.XML_LT) { if (scanner.Scan() != XMLScanner.XML_IDENT || !scanner.Identifier.Equals("ref")) { ThrowException("<ref> element expected"); } XMLElement ref_Renamed = ReadElement("ref"); Key key = null; int mask = 0; if (fieldNames != null) { string[] values = new string[fieldNames.Length]; int[] types = ((BtreeMultiFieldIndex) btree).types; for (int i = 0; i < values.Length; i++) { values[i] = GetAttribute(ref_Renamed, "key" + i); } key = CreateCompoundKey(types, values); } else { if (btree is BitIndex) { mask = GetIntAttribute(ref_Renamed, "key"); } else { key = CreateKey(btree.type, GetAttribute(ref_Renamed, "key")); } } IPersistent obj = new PersistentStub(storage, MapId(GetIntAttribute(ref_Renamed, "id"))); if (btree is BitIndex) { ((BitIndex) btree).Put(obj, mask); } else { btree.Insert(key, obj, false); } } if (tkn != XMLScanner.XML_LTS || scanner.Scan() != XMLScanner.XML_IDENT || !scanner.Identifier.Equals(indexType) || scanner.Scan() != XMLScanner.XML_GT) { ThrowException("Element is not closed"); } byte[] data = storage.PackObject(btree); int size = ObjectHeader.GetSize(data, 0); long pos = storage.Allocate(size, 0); storage.SetPos(oid, pos | StorageImpl.dbModifiedFlag); storage.pool.Put(pos & ~ StorageImpl.dbFlagsMask, data, size); }
internal int UnpackObject(object obj, ClassDescriptor desc, bool recursiveLoading, byte[] body, int offs, IPersistent po) { ClassDescriptor.FieldDescriptor[] all = desc.allFields; ReflectionProvider provider = ClassDescriptor.ReflectionProvider; int len; for (int i = 0, n = all.Length; i < n; i++) { ClassDescriptor.FieldDescriptor fd = all[i]; FieldInfo f = fd.field; if (f == null || obj == null) { switch (fd.type) { case ClassDescriptor.tpBoolean: case ClassDescriptor.tpByte: offs += 1; continue; case ClassDescriptor.tpChar: case ClassDescriptor.tpShort: offs += 2; continue; case ClassDescriptor.tpInt: case ClassDescriptor.tpFloat: case ClassDescriptor.tpObject: offs += 4; continue; case ClassDescriptor.tpLong: case ClassDescriptor.tpDouble: case ClassDescriptor.tpDate: offs += 8; continue; case ClassDescriptor.tpString: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { offs += len * 2; } else if (len < -1) { offs -= (len + 2); } continue; case ClassDescriptor.tpValue: offs = UnpackObject((object) null, fd.valueDesc, recursiveLoading, body, offs, po); continue; case ClassDescriptor.tpRaw: case ClassDescriptor.tpArrayOfByte: case ClassDescriptor.tpArrayOfBoolean: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { offs += len; } else if (len < -1) { offs += ClassDescriptor.Sizeof[-2 - len]; } continue; case ClassDescriptor.tpArrayOfShort: case ClassDescriptor.tpArrayOfChar: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { offs += len * 2; } continue; case ClassDescriptor.tpArrayOfInt: case ClassDescriptor.tpArrayOfFloat: case ClassDescriptor.tpArrayOfObject: case ClassDescriptor.tpLink: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { offs += len * 4; } continue; case ClassDescriptor.tpArrayOfLong: case ClassDescriptor.tpArrayOfDouble: case ClassDescriptor.tpArrayOfDate: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { offs += len * 8; } continue; case ClassDescriptor.tpArrayOfString: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { for (int j = 0; j < len; j++) { int strlen = Bytes.Unpack4(body, offs); offs += 4; if (strlen > 0) { offs += strlen * 2; } else if (strlen < -1) { offs -= (strlen + 2); } } } continue; case ClassDescriptor.tpArrayOfValue: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { ClassDescriptor valueDesc = fd.valueDesc; for (int j = 0; j < len; j++) { offs = UnpackObject((object) null, valueDesc, recursiveLoading, body, offs, po); } } continue; case ClassDescriptor.tpArrayOfRaw: len = Bytes.Unpack4(body, offs); offs += 4; if (len > 0) { for (int j = 0; j < len; j++) { int rawlen = Bytes.Unpack4(body, offs); offs += 4; if (rawlen > 0) { offs += rawlen; } else if (rawlen < -1) { offs += ClassDescriptor.Sizeof[-2 - rawlen]; } } } continue; } } else { switch (fd.type) { case ClassDescriptor.tpBoolean: provider.SetBoolean(f, obj, body[offs++] != 0); continue; case ClassDescriptor.tpByte: provider.SetByte(f, obj, body[offs++]); continue; case ClassDescriptor.tpChar: provider.SetChar(f, obj, (char) Bytes.Unpack2(body, offs)); offs += 2; continue; case ClassDescriptor.tpShort: provider.SetShort(f, obj, Bytes.Unpack2(body, offs)); offs += 2; continue; case ClassDescriptor.tpInt: provider.SetInt(f, obj, Bytes.Unpack4(body, offs)); offs += 4; continue; case ClassDescriptor.tpLong: provider.SetLong(f, obj, Bytes.Unpack8(body, offs)); offs += 8; continue; case ClassDescriptor.tpFloat: provider.SetFloat(f, obj, Bytes.UnpackF4(body, offs)); offs += 4; continue; case ClassDescriptor.tpDouble: provider.SetDouble(f, obj, Bytes.UnpackF8(body, offs)); offs += 8; continue; case ClassDescriptor.tpString: { len = Bytes.Unpack4(body, offs); offs += 4; string str = null; if (len >= 0) { char[] chars = new char[len]; for (int j = 0; j < len; j++) { chars[j] = (char) Bytes.Unpack2(body, offs); offs += 2; } str = new string(chars); } else if (len < -1) { if (encoding != null) { string tempStr; //UPGRADE_TODO: The differences in the Format of parameters for constructor 'java.lang.String.String' may cause compilation errors. tempStr = System.Text.Encoding.GetEncoding(encoding).GetString(body); str = new string(tempStr.ToCharArray(), offs, -2 - len); } else { str = new string(SupportClass.ToCharArray(body), offs, -2 - len); } offs -= (2 + len); } provider.Set(f, obj, str); continue; } case ClassDescriptor.tpDate: { long msec = Bytes.Unpack8(body, offs); offs += 8; //UPGRADE_TODO: The 'System.DateTime' structure does not have an equivalent to NULL. DateTime date; // = null; if (msec >= 0) { //UPGRADE_TODO: Constructor 'java.util.Date.Date' was converted to 'DateTime.DateTime' which has a different behavior. date = new DateTime(msec); } else date = new DateTime(); provider.Set(f, obj, date); continue; } case ClassDescriptor.tpObject: { provider.Set(f, obj, Unswizzle(Bytes.Unpack4(body, offs), f.FieldType, recursiveLoading)); offs += 4; continue; } case ClassDescriptor.tpValue: { object val = fd.valueDesc.NewInstance(); offs = UnpackObject(val, fd.valueDesc, recursiveLoading, body, offs, po); provider.Set(f, obj, val); continue; } case ClassDescriptor.tpRaw: len = Bytes.Unpack4(body, offs); offs += 4; if (len >= 0) { System.IO.MemoryStream streamIn = new System.IO.MemoryStream(body, offs, len); BinaryFormatter formatter = new BinaryFormatter(); object val = formatter.Deserialize(streamIn); provider.Set(f, obj, val); streamIn.Close(); offs += len; } else if (len < 0) { object val = null; switch (-2 - len) { case ClassDescriptor.tpBoolean: val = Convert.ToBoolean(body[offs++]); break; case ClassDescriptor.tpByte: val = (byte) body[offs++]; break; case ClassDescriptor.tpChar: val = (char) Bytes.Unpack2(body, offs); offs += 2; break; case ClassDescriptor.tpShort: val = (short) Bytes.Unpack2(body, offs); offs += 2; break; case ClassDescriptor.tpInt: val = (Int32) Bytes.Unpack4(body, offs); offs += 4; break; case ClassDescriptor.tpLong: val = (long) Bytes.Unpack8(body, offs); offs += 8; break; case ClassDescriptor.tpFloat: val = Bytes.UnpackF4(body, offs); break; case ClassDescriptor.tpDouble: val = Bytes.UnpackF8(body, offs); offs += 8; break; case ClassDescriptor.tpDate: //UPGRADE_TODO: Constructor 'java.util.Date.Date' was converted to 'DateTime.DateTime' which has a different behavior. val = new DateTime(Bytes.Unpack8(body, offs)); offs += 8; break; case ClassDescriptor.tpObject: val = Unswizzle(Bytes.Unpack4(body, offs), typeof(Persistent), recursiveLoading); offs += 4; break; } provider.Set(f, obj, val); } continue; case ClassDescriptor.tpArrayOfByte: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { byte[] arr = new byte[len]; Array.Copy(body, offs, arr, 0, len); offs += len; provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfBoolean: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { bool[] arr = new bool[len]; for (int j = 0; j < len; j++) { arr[j] = body[offs++] != 0; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfShort: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { short[] arr = new short[len]; for (int j = 0; j < len; j++) { arr[j] = Bytes.Unpack2(body, offs); offs += 2; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfChar: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { char[] arr = new char[len]; for (int j = 0; j < len; j++) { arr[j] = (char) Bytes.Unpack2(body, offs); offs += 2; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfInt: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { int[] arr = new int[len]; for (int j = 0; j < len; j++) { arr[j] = Bytes.Unpack4(body, offs); offs += 4; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfLong: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { long[] arr = new long[len]; for (int j = 0; j < len; j++) { arr[j] = Bytes.Unpack8(body, offs); offs += 8; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfFloat: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { float[] arr = new float[len]; for (int j = 0; j < len; j++) { arr[j] = Bytes.UnpackF4(body, offs); offs += 4; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfDouble: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { double[] arr = new double[len]; for (int j = 0; j < len; j++) { arr[j] = Bytes.UnpackF8(body, offs); offs += 8; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfDate: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { DateTime[] arr = new DateTime[len]; for (int j = 0; j < len; j++) { long msec = Bytes.Unpack8(body, offs); offs += 8; if (msec >= 0) { //UPGRADE_TODO: Constructor 'java.util.Date.Date' was converted to 'DateTime.DateTime' which has a different behavior. arr[j] = new DateTime(msec); } } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfString: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { string[] arr = new string[len]; for (int j = 0; j < len; j++) { int strlen = Bytes.Unpack4(body, offs); offs += 4; if (strlen >= 0) { char[] chars = new char[strlen]; for (int k = 0; k < strlen; k++) { chars[k] = (char) Bytes.Unpack2(body, offs); offs += 2; } arr[j] = new string(chars); } else if (strlen < -1) { if (encoding != null) { string tempStr2; //UPGRADE_TODO: The differences in the Format of parameters for constructor 'java.lang.String.String' may cause compilation errors. tempStr2 = System.Text.Encoding.GetEncoding(encoding).GetString(body); arr[j] = new string(tempStr2.ToCharArray(), offs, -2 - strlen); } else { arr[j] = new string(SupportClass.ToCharArray(body), offs, -2 - strlen); } offs -= (2 + strlen); } } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfObject: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { Type elemType = f.FieldType.GetElementType(); IPersistent[] arr = (IPersistent[]) System.Array.CreateInstance(elemType, len); for (int j = 0; j < len; j++) { arr[j] = Unswizzle(Bytes.Unpack4(body, offs), elemType, recursiveLoading); offs += 4; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfValue: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { Type elemType = f.FieldType.GetElementType(); object[] arr = (object[]) System.Array.CreateInstance(elemType, len); ClassDescriptor valueDesc = fd.valueDesc; for (int j = 0; j < len; j++) { object val = valueDesc.NewInstance(); offs = UnpackObject(val, valueDesc, recursiveLoading, body, offs, po); arr[j] = val; } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpArrayOfRaw: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { Type elemType = f.FieldType.GetElementType(); object[] arr = (object[]) System.Array.CreateInstance(elemType, len); for (int j = 0; j < len; j++) { int rawlen = Bytes.Unpack4(body, offs); offs += 4; if (rawlen >= 0) { // TODOPORT: System.IO.MemoryStream streamIn = new System.IO.MemoryStream(body, offs, rawlen); //UPGRADE_TODO: Class 'java.io.ObjectInputStream' was converted to 'System.IO.BinaryReader' which has a different behavior. //System.IO.BinaryReader streamIn = new PersistentObjectInputStream(this, bin); //UPGRADE_WARNING: Method 'java.io.ObjectInputStream.readObject' was converted to 'SupportClass.Deserialize' which may throw an exception. BinaryFormatter formatter = new BinaryFormatter(); object val = formatter.Deserialize(streamIn); arr[j] = val; streamIn.Close(); offs += rawlen; } else { object val = null; switch (-2 - rawlen) { case ClassDescriptor.tpBoolean: val = Convert.ToBoolean(body[offs++]); break; case ClassDescriptor.tpByte: val = (byte) body[offs++]; break; case ClassDescriptor.tpChar: val = (char) Bytes.Unpack2(body, offs); offs += 2; break; case ClassDescriptor.tpShort: val = (short) Bytes.Unpack2(body, offs); offs += 2; break; case ClassDescriptor.tpInt: val = (Int32) Bytes.Unpack4(body, offs); offs += 4; break; case ClassDescriptor.tpLong: val = (long) Bytes.Unpack8(body, offs); offs += 8; break; case ClassDescriptor.tpFloat: val = Bytes.UnpackF4(body, offs); offs += 4; break; case ClassDescriptor.tpDouble: val = Bytes.UnpackF8(body, offs); offs += 8; break; case ClassDescriptor.tpDate: //UPGRADE_TODO: Constructor 'java.util.Date.Date' was converted to 'DateTime.DateTime' which has a different behavior. val = new DateTime(Bytes.Unpack8(body, offs)); offs += 8; break; case ClassDescriptor.tpObject: val = Unswizzle(Bytes.Unpack4(body, offs), typeof(Persistent), recursiveLoading); offs += 4; break; } arr[j] = val; } } provider.Set(f, obj, arr); } continue; case ClassDescriptor.tpLink: len = Bytes.Unpack4(body, offs); offs += 4; if (len < 0) { provider.Set(f, obj, (object) null); } else { IPersistent[] arr = new IPersistent[len]; for (int j = 0; j < len; j++) { int elemOid = Bytes.Unpack4(body, offs); offs += 4; if (elemOid != 0) { arr[j] = new PersistentStub(this, elemOid); } } provider.Set(f, obj, new LinkImpl(arr, po)); } break; } } } return offs; }
public virtual void Unpin() { for (int i = 0, n = used; i < n; i++) { IPersistent elem = arr[i]; if (elem != null && !elem.IsRaw() && elem.IsPersistent()) { arr[i] = new PersistentStub(elem.Storage, elem.Oid); } } }