private async Task CheckForConcurencyOnlyAsync(object oi, ObjectInfo objInfo, SqoTypeInfo ti, ObjectSerializer serializer) { if (SiaqodbConfigurator.OptimisticConcurrencyEnabled) { FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, "tickCount"); if (fi != null) { if (fi.AttributeType == typeof(ulong)) { ulong tickCount = 0; if (objInfo.Oid > 0 && objInfo.Oid <= ti.Header.numberOfRecords) //update or delete { tickCount = (ulong)(await serializer.ReadFieldValueAsync(ti, objInfo.Oid, fi).ConfigureAwait(false)); if (objInfo.TickCount != 0) { if (tickCount != objInfo.TickCount) { throw new OptimisticConcurrencyException("Another version of object with OID=" + objInfo.Oid.ToString() + " of Type:" + ti.TypeName + " is saved in database, refresh your object before save!"); } } } } } } }
internal async Task <bool> SaveFieldValueAsync(int oid, string field, SqoTypeInfo ti, object value, RawdataSerializer rawSerializer) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; FieldSqoInfo ai = FindField(ti.Fields, field); if (ai == null) { throw new SiaqodbException("Field:" + field + " not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } else if (value != null && ai.AttributeType != value.GetType()) { try { object valConvert = Convertor.ChangeType(value, ai.AttributeType); value = valConvert; } catch { string msg = "Type of value should be:" + ai.AttributeType.ToString(); SiaqodbConfigurator.LogMessage(msg, VerboseLevel.Error); throw new SiaqodbException(msg); } } byte[] by = null; IByteTransformer byteTransformer = ByteTransformerFactory.GetByteTransformer(this, rawSerializer, ai, ti, oid); by = await byteTransformer.GetBytesAsync(value).ConfigureAwait(false); await file.WriteAsync((long)(position + (long)ai.Header.PositionInRecord), by).ConfigureAwait(false); return(true); }
public ArrayByteTranformer(ObjectSerializer serializer, RawdataSerializer rawSerializer, SqoTypeInfo ti, FieldSqoInfo fi, int parentOID) { this.serializer = serializer; this.ti = ti; this.fi = fi; this.rawSerializer = rawSerializer; this.parentOID = parentOID; }
internal async Task <bool> UpdateObjectByAsync(string[] fieldNames, object obj, SqoTypeInfo ti, Transaction transact) { ObjectInfo objInfo = MetaExtractor.GetObjectInfo(obj, ti, metaCache); int i = 0; ICriteria wPrev = null; foreach (string fieldName in fieldNames) { FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, fieldName); if (fi == null) { throw new SiaqodbException("Field:" + fieldName + " was not found as member of Type:" + ti.TypeName); } Where w = new Where(fieldName, OperationType.Equal, objInfo.AtInfo[fi]); w.StorageEngine = this; w.ParentSqoTypeInfo = ti; w.ParentType.Add(w.ParentSqoTypeInfo.Type); if (i > 0) { And and = new And(); and.Add(w, wPrev); wPrev = and; } else { wPrev = w; } i++; } List <int> oids = await wPrev.GetOIDsAsync().ConfigureAwait(false); if (oids.Count > 1) { throw new SiaqodbException("In database exists more than one object with value of fields specified"); } else if (oids.Count == 1) { objInfo.Oid = oids[0]; if (transact == null) { await this.SaveObjectAsync(obj, ti, objInfo).ConfigureAwait(false); } else { await this.SaveObjectAsync(obj, ti, objInfo, transact).ConfigureAwait(false); } return(true); } else { return(false); } }
public object ReadFieldValue(SqoTypeInfo ti, int oid, string fieldName, RawdataSerializer rawSerializer) { FieldSqoInfo fi = FindField(ti.Fields, fieldName); if (fi == null) { throw new SiaqodbException("Field:" + fieldName + " not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } return(this.ReadFieldValue(ti, oid, fi, rawSerializer)); }
internal void SaveArrayOIDFieldContent(SqoTypeInfo ti, FieldSqoInfo fi, int objectOID, int newOID) { byte[] arrayOID = ByteConverter.IntToByteArray(newOID); long position = MetaHelper.GetSeekPosition(ti, objectOID); //an array field has size=9 (isNull(bool) + oid of array table(int)+ nrElements(int) //so write oid after first byte which is null/not null long writePosition = (long)(position + (long)fi.Header.PositionInRecord + 1L); file.Write(writePosition, arrayOID); }
public async Task <int> ReadOidOfComplexAsync(SqoTypeInfo ti, int oid, string fieldName, RawdataSerializer rawSerializer) { FieldSqoInfo fi = FindField(ti.Fields, fieldName); if (fi == null) { throw new SiaqodbException("Field:" + fieldName + " not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } return(await this.ReadOidOfComplexAsync(ti, oid, fi, rawSerializer).ConfigureAwait(false)); }
private Dictionary <FieldSqoInfo, FieldSqoInfo> JoinFieldsSqoInfo(SqoTypeInfo actualTypeinfo, SqoTypeInfo oldTypeinfo) { Dictionary <FieldSqoInfo, FieldSqoInfo> fields = new Dictionary <FieldSqoInfo, FieldSqoInfo>(); foreach (FieldSqoInfo fi in actualTypeinfo.Fields) { FieldSqoInfo oldFi = MetaHelper.FindField(oldTypeinfo.Fields, fi.Name); fields[fi] = oldFi; } return(fields); }
private IndexInfo2 BuildIndex(FieldSqoInfo finfo, SqoTypeInfo tinfo, IBTree index) { this.FillIndex(finfo, tinfo, index); IndexInfo2 ii = new IndexInfo2(); ii.IndexName = finfo.Name + tinfo.TypeName; ii.RootOID = index.GetRootOid(); siaqodb.StoreObject(ii); storedIndexes.Add(ii); return(ii); }
public IBTree GetIndex(SqoTypeInfo type, FieldSqoInfo fi) { if (cache.ContainsKey(type)) { if (cache[type].ContainsKey(fi)) { return(cache[type][fi]); } } return(null); }
public void SaveComplexFieldContent(KeyValuePair <int, int> oid_Tid, FieldSqoInfo fi, SqoTypeInfo ti, int oid) { byte[] by = new byte[MetaExtractor.GetAbsoluteSizeOfField(MetaExtractor.complexID)]; byte[] complexOID = ByteConverter.IntToByteArray(oid_Tid.Key); byte[] complexTID = ByteConverter.IntToByteArray(oid_Tid.Value); Array.Copy(complexOID, 0, by, 0, complexOID.Length); Array.Copy(complexTID, 0, by, 4, complexTID.Length); long position = MetaHelper.GetSeekPosition(ti, oid); file.Write((long)(position + (long)fi.Header.PositionInRecord), by); }
public IBTree GetIndex(SqoTypeInfo type, string fieldName) { if (cache.ContainsKey(type)) { FieldSqoInfo fi = MetaHelper.FindField(type.Fields, fieldName); if (fi != null) { return(this.GetIndex(type, fi)); } } return(null); }
private async Task <IndexInfo2> BuildIndexAsync(FieldSqoInfo finfo, SqoTypeInfo tinfo, IBTree index) { await this.FillIndexAsync(finfo, tinfo, index).ConfigureAwait(false); IndexInfo2 ii = new IndexInfo2(); ii.IndexName = finfo.Name + tinfo.TypeName; ii.RootOID = index.GetRootOid(); await siaqodb.StoreObjectAsync(ii).ConfigureAwait(false); storedIndexes.Add(ii); return(ii); }
internal int ReadFirstTID(int oid, FieldSqoInfo fi, SqoTypeInfo ti, RawdataSerializer rawdataSerializer) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; if (fi == null) { throw new SiaqodbException("Field not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } byte[] b = new byte[fi.Header.Length]; file.Read((long)(position + (long)fi.Header.PositionInRecord), b); return(rawdataSerializer.ReadComplexArrayFirstTID(b, ti.Header.version, this)); }
public async Task FillIndexAsync(FieldSqoInfo finfo, SqoTypeInfo ti, IBTree index) { int nrRecords = ti.Header.numberOfRecords; for (int i = 0; i < nrRecords; i++) { int oid = i + 1; if (await siaqodb.IsObjectDeletedAsync(oid, ti).ConfigureAwait(false)) { continue; } await index.AddItemAsync(await siaqodb.LoadValueAsync(oid, finfo.Name, ti.Type).ConfigureAwait(false), new int[] { oid }).ConfigureAwait(false); } }
public void FillIndex(FieldSqoInfo finfo, SqoTypeInfo ti, IBTree index) { int nrRecords = ti.Header.numberOfRecords; for (int i = 0; i < nrRecords; i++) { int oid = i + 1; if (siaqodb.IsObjectDeleted(oid, ti)) { continue; } index.AddItem(siaqodb.LoadValue(oid, finfo.Name, ti.Type), new int[] { oid }); } }
public KeyValuePair <int, int> ReadOIDAndTID(SqoTypeInfo ti, int oid, FieldSqoInfo fi) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; if (fi == null) { throw new SiaqodbException("Field not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } byte[] b = new byte[fi.Header.Length]; file.Read((long)(position + (long)fi.Header.PositionInRecord), b); return(ReadOIDAndTID(b)); }
internal List <int> DeleteObjectBy(SqoTypeInfo ti, Dictionary <string, object> criteria) { int i = 0; ICriteria wPrev = null; foreach (string fieldName in criteria.Keys) { FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, fieldName); if (fi == null) { throw new SiaqodbException("Field:" + fieldName + " was not found as member of Type:" + ti.TypeName); } Where w = new Where(fieldName, OperationType.Equal, criteria[fieldName]); w.StorageEngine = this; w.ParentSqoTypeInfo = ti; w.ParentType.Add(w.ParentSqoTypeInfo.Type); if (i > 0) { And and = new And(); and.Add(w, wPrev); wPrev = and; } else { wPrev = w; } i++; } List <int> oids = wPrev.GetOIDs(); ObjectSerializer serializer = SerializerFactory.GetSerializer(this.path, GetFileByType(ti), useElevatedTrust); lock (_syncRoot) { foreach (int oid in oids) { this.MarkObjectAsDelete(serializer, oid, ti); this.indexManager.UpdateIndexesAfterDelete(oid, ti); } } return(oids); }
public async Task <int> ReadOidOfComplexAsync(SqoTypeInfo ti, int oid, FieldSqoInfo fi, RawdataSerializer rawSerializer) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; if (fi == null) { throw new SiaqodbException("Field not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } byte[] b = new byte[fi.Header.Length]; await file.ReadAsync((long)(position + (long)fi.Header.PositionInRecord), b).ConfigureAwait(false); byte[] oidOfComplexObjBuff = GetFieldBytes(b, 0, 4); int oidOfComplexObj = ByteConverter.ByteArrayToInt(oidOfComplexObjBuff); return(oidOfComplexObj); }
private async Task <IBTree> RenewIndexAsync(SqoTypeInfo ti, string fieldName) { FieldSqoInfo finfo = MetaHelper.FindField(ti.Fields, fieldName); IndexInfo2 indexInfo = null; if (finfo != null) { string indexName = finfo.Name + ti.TypeName; IList <IndexInfo2> stIndexes = await this.GetStoredIndexesAsync().ConfigureAwait(false); foreach (IndexInfo2 ii in stIndexes) { if (indexName.StartsWith(ii.IndexName) || ii.IndexName.StartsWith(indexName)) { indexInfo = ii; break; } } if (indexInfo != null) { if (storedIndexes != null && storedIndexes.Contains(indexInfo)) { storedIndexes.Remove(indexInfo); } await siaqodb.DeleteAsync(indexInfo); } Type t = typeof(BTree <>).MakeGenericType(finfo.AttributeType); ConstructorInfo ctor = t.GetConstructor(new Type[] { typeof(Siaqodb) }); IBTree index = (IBTree)ctor.Invoke(new object[] { this.siaqodb }); indexInfo = await this.BuildIndexAsync(finfo, ti, index); index.SetIndexInfo(indexInfo); await index.PersistAsync(); cacheIndexes.Set(ti, finfo, index); return(index); } return(null); }
private async Task CheckForConcurencyAsync(object oi, ObjectInfo objInfo, SqoTypeInfo ti, ObjectSerializer serializer, bool updateTickCountInDB) { if (SiaqodbConfigurator.OptimisticConcurrencyEnabled) { FieldSqoInfo fi = MetaHelper.FindField(ti.Fields, "tickCount"); if (fi != null) { if (fi.AttributeType == typeof(ulong)) { ulong tickCount = 0; if (objInfo.Oid > 0 && objInfo.Oid <= ti.Header.numberOfRecords) //update or delete { tickCount = (ulong)(await serializer.ReadFieldValueAsync(ti, objInfo.Oid, fi).ConfigureAwait(false)); if (objInfo.TickCount != 0) { if (tickCount != objInfo.TickCount) { throw new OptimisticConcurrencyException("Another version of object with OID=" + objInfo.Oid.ToString() + " of Type:" + ti.TypeName + " is saved in database, refresh your object before save!"); } } } tickCount = tickCount + 1L; objInfo.AtInfo[fi] = tickCount; #if SILVERLIGHT MetaHelper.CallSetValue(fi.FInfo, tickCount, oi, ti.Type); #else fi.FInfo.SetValue(oi, tickCount); #endif if (updateTickCountInDB) { await serializer.SaveFieldValueAsync(objInfo.Oid, "tickCount", ti, tickCount, this.rawSerializer).ConfigureAwait(false); } } } } }
internal ATuple <int, int> GetArrayMetaOfField(SqoTypeInfo ti, int oid, FieldSqoInfo fi) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; if (fi == null) { throw new SiaqodbException("Field not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } byte[] bytes = new byte[fi.Header.Length]; file.Read((long)(position + (long)fi.Header.PositionInRecord), bytes); byte[] oidBytes = new byte[4]; Array.Copy(bytes, 1, oidBytes, 0, 4); int rawInfoOID = (int)ByteConverter.DeserializeValueType(typeof(int), oidBytes, ti.Header.version); byte[] nrElemeBytes = new byte[4]; Array.Copy(bytes, MetaExtractor.ExtraSizeForArray - 4, nrElemeBytes, 0, 4); int nrElem = (int)ByteConverter.DeserializeValueType(typeof(int), nrElemeBytes, ti.Header.version); return(new ATuple <int, int>(rawInfoOID, nrElem)); }
internal DictionaryInfo GetDictInfoOfField(SqoTypeInfo ti, int oid, FieldSqoInfo fi) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; if (fi == null) { throw new SiaqodbException("Field not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } byte[] bytes = new byte[fi.Header.Length]; file.Read((long)(position + (long)fi.Header.PositionInRecord), bytes); byte[] oidBytes = new byte[4]; Array.Copy(bytes, 1, oidBytes, 0, 4); int rawInfoOID = (int)ByteConverter.DeserializeValueType(typeof(int), oidBytes, ti.Header.version); byte[] nrElemeBytes = new byte[4]; Array.Copy(bytes, oidBytes.Length + 1, nrElemeBytes, 0, 4); int nrElem = (int)ByteConverter.DeserializeValueType(typeof(int), nrElemeBytes, ti.Header.version); byte[] keyTypeIdBytes = new byte[4]; Array.Copy(bytes, oidBytes.Length + nrElemeBytes.Length + 1, keyTypeIdBytes, 0, 4); int keyTypeId = (int)ByteConverter.DeserializeValueType(typeof(int), keyTypeIdBytes, ti.Header.version); byte[] valueTypeIdBytes = new byte[4]; Array.Copy(bytes, oidBytes.Length + nrElemeBytes.Length + keyTypeIdBytes.Length + 1, valueTypeIdBytes, 0, 4); int valueTypeId = (int)ByteConverter.DeserializeValueType(typeof(int), valueTypeIdBytes, ti.Header.version); DictionaryInfo di = new DictionaryInfo(); di.RawOID = rawInfoOID; di.NrElements = nrElem; di.KeyTypeId = keyTypeId; di.ValueTypeId = valueTypeId; return(di); }
public static ObjectList <T> CreateObjectsFromTable <T>(ObjectTable table, SqoTypeInfo actualType) { ObjectList <T> obList = new ObjectList <T>(); foreach (ObjectRow row in table.Rows) { T currentObj = default(T); currentObj = Activator.CreateInstance <T>(); //ISqoDataObject dObj = currentObj as ISqoDataObject; foreach (string column in table.Columns.Keys) { FieldSqoInfo fi = MetaHelper.FindField(actualType.Fields, column); if (fi != null) { #if SILVERLIGHT try { //dObj.SetValue(fi.FInfo, row[column]); MetaHelper.CallSetValue(fi.FInfo, row[column], currentObj, actualType.Type); } catch (Exception ex) { throw new SiaqodbException("Override GetValue and SetValue methods of SqoDataObject-Silverlight limitation to private fields"); } #else fi.FInfo.SetValue(currentObj, row[column]); #endif } } obList.Add(currentObj); } return(obList); }
public async Task <object> ReadFieldValueAsync(SqoTypeInfo ti, int oid, FieldSqoInfo fi, RawdataSerializer rawSerializer) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; if (fi == null) { throw new SiaqodbException("Field not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } byte[] b = new byte[fi.Header.Length]; if (oidEnd == 0 && oidStart == 0) { await file.ReadAsync((long)(position + (long)fi.Header.PositionInRecord), b).ConfigureAwait(false); } else { int fieldPosition = (oid - oidStart) * recordLength + fi.Header.PositionInRecord; Array.Copy(preloadedBytes, fieldPosition, b, 0, b.Length); } IByteTransformer byteTransformer = ByteTransformerFactory.GetByteTransformer(this, rawSerializer, fi, ti); try { return(await byteTransformer.GetObjectAsync(b).ConfigureAwait(false)); } catch (Exception ex) { if (ti.Type != null && ti.Type.IsGenericType() && ti.Type.GetGenericTypeDefinition() == typeof(Indexes.BTreeNode <>)) { throw new IndexCorruptedException(); } //SiaqodbConfigurator.LogMessage("Field's" + fi.Name + " value of Type " + ti.TypeName + "cannot be loaded,will be set to default.", VerboseLevel.Info); // return MetaHelper.GetDefault(fi.AttributeType); throw ex; } }
public object ReadFieldValue(SqoTypeInfo ti, int oid, FieldSqoInfo fi) { return(this.ReadFieldValue(ti, oid, fi, null)); }
internal async Task SaveObjectTableAsync(SqoTypeInfo actualTypeinfo, SqoTypeInfo oldSqoTypeInfo, ObjectTable table, RawdataSerializer rawSerializer) { Dictionary <FieldSqoInfo, FieldSqoInfo> joinedFields = JoinFieldsSqoInfo(actualTypeinfo, oldSqoTypeInfo); foreach (ObjectRow row in table.Rows) { int oid = (int)row["OID"]; if (oid < 0)//deleted { await this.MarkObjectAsDeleteAsync(-oid, actualTypeinfo).ConfigureAwait(false); continue; } byte[] oidBuff = ByteConverter.IntToByteArray(oid); byte[] buffer = new byte[actualTypeinfo.Header.lengthOfRecord]; int curentIndex = 0; Array.Copy(oidBuff, 0, buffer, curentIndex, oidBuff.Length); curentIndex += oidBuff.Length; foreach (FieldSqoInfo ai in actualTypeinfo.Fields) { byte[] by = null; object fieldVal = null; bool existed = false; if (table.Columns.ContainsKey(ai.Name)) { fieldVal = row[ai.Name]; existed = true; } else { if (ai.AttributeTypeId == MetaExtractor.complexID || ai.AttributeTypeId == MetaExtractor.documentID) { fieldVal = null; } else if (typeof(string) == ai.AttributeType) { fieldVal = string.Empty; } else if (ai.AttributeType.IsArray) { fieldVal = Array.CreateInstance(ai.AttributeType.GetElementType(), 0); } else { fieldVal = Activator.CreateInstance(ai.AttributeType); } } if (joinedFields[ai] != null) //existed in old Type { if (ai.AttributeTypeId != joinedFields[ai].AttributeTypeId) { if (typeof(IList).IsAssignableFrom(ai.AttributeType) || ai.AttributeTypeId == MetaExtractor.dictionaryID || joinedFields[ai].AttributeTypeId == MetaExtractor.dictionaryID) { throw new TypeChangedException("Change array or dictionary type it is not supported"); } else { fieldVal = Convertor.ChangeType(fieldVal, ai.AttributeType); } } } if (ai.AttributeTypeId == MetaExtractor.complexID || ai.AttributeTypeId == MetaExtractor.documentID) { if (existed) { by = (byte[])fieldVal; } else { by = await this.GetComplexObjectBytesAsync(fieldVal).ConfigureAwait(false); } } else if (typeof(IList).IsAssignableFrom(ai.AttributeType))//array { if (existed) { by = (byte[])fieldVal; } else { by = await rawSerializer.SerializeArrayAsync(fieldVal, ai.AttributeType, ai.Header.Length, ai.Header.RealLength, actualTypeinfo.Header.version, null, this, ai.IsText).ConfigureAwait(false); } } else if (ai.IsText) { if (existed) { FieldSqoInfo oldAi = joinedFields[ai]; if (oldAi != null && oldAi.IsText) { by = (byte[])fieldVal; } else { by = await rawSerializer.SerializeArrayAsync(fieldVal, ai.AttributeType, ai.Header.Length, ai.Header.RealLength, actualTypeinfo.Header.version, null, this, ai.IsText).ConfigureAwait(false); } } else { by = await rawSerializer.SerializeArrayAsync(fieldVal, ai.AttributeType, ai.Header.Length, ai.Header.RealLength, actualTypeinfo.Header.version, null, this, ai.IsText).ConfigureAwait(false); } } else if (ai.AttributeTypeId == MetaExtractor.dictionaryID) { if (existed) { by = (byte[])fieldVal; } else { IByteTransformer byteTransformer = ByteTransformerFactory.GetByteTransformer(this, rawSerializer, ai, actualTypeinfo, 0); by = await byteTransformer.GetBytesAsync(fieldVal).ConfigureAwait(false); } } else { by = ByteConverter.SerializeValueType(fieldVal, ai.AttributeType, ai.Header.Length, ai.Header.RealLength, actualTypeinfo.Header.version); } Array.Copy(by, 0, buffer, ai.Header.PositionInRecord, ai.Header.Length); //curentIndex += by.Length; } long position = MetaHelper.GetSeekPosition(actualTypeinfo, oid); await file.WriteAsync(position, buffer).ConfigureAwait(false); } }
public async Task <object> ReadFieldValueAsync(SqoTypeInfo ti, int oid, FieldSqoInfo fi) { return(await this.ReadFieldValueAsync(ti, oid, fi, null).ConfigureAwait(false)); }
public FixedArrayByteTransformer(ObjectSerializer serializer, SqoTypeInfo ti, FieldSqoInfo fi) { this.serializer = serializer; this.ti = ti; this.fi = fi; }
internal async Task <List <KeyValuePair <int, int> > > ReadComplexArrayOidsAsync(int oid, FieldSqoInfo fi, SqoTypeInfo ti, RawdataSerializer rawdataSerializer) { long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; if (fi == null) { throw new SiaqodbException("Field not exists in the Type Definition, if you use a Property you have to use UseVariable Attribute"); } byte[] b = new byte[fi.Header.Length]; await file.ReadAsync((long)(position + (long)fi.Header.PositionInRecord), b).ConfigureAwait(false); return(rawdataSerializer.ReadComplexArrayOids(b, ti.Header.version, this)); }