private async Task MarkFreeSpaceAsync(SqoTypeInfo ti) { ObjectSerializer serializer = SerializerFactory.GetSerializer(this.path, GetFileByType(ti), useElevatedTrust); int nrRecords = ti.Header.numberOfRecords; List <FieldSqoInfo> existingDynamicFields = new List <FieldSqoInfo>(); foreach (FieldSqoInfo ai in ti.Fields) { IByteTransformer byteTrans = ByteTransformerFactory.GetByteTransformer(null, null, ai, ti); if (byteTrans is ArrayByteTranformer || byteTrans is DictionaryByteTransformer) { existingDynamicFields.Add(ai); } } if (existingDynamicFields.Count > 0) { for (int i = 0; i < nrRecords; i++) { int oid = i + 1; foreach (FieldSqoInfo ai in existingDynamicFields) { ATuple <int, int> arrayInfo = await this.GetArrayMetaOfFieldAsync(ti, oid, ai).ConfigureAwait(false); if (arrayInfo.Name > 0) { await rawSerializer.MarkRawInfoAsFreeAsync(arrayInfo.Name).ConfigureAwait(false);//this helps Shrink method to detect unused rawdata blocks. } } } } }
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); }
private EditHexWindow(IconSource source, NbtTag tag, NbtContainerTag parent, bool set_name, EditPurpose purpose) { InitializeComponent(); TabView.Size = new Size(0, 0); WorkingTag = tag; TagParent = parent; NameBox.SetTags(tag, parent); SettingName = set_name; NameLabel.Visible = SettingName; NameBox.Visible = SettingName; Provider = ByteProviders.GetByteProvider(tag); HexBox.ByteProvider = Provider; HexBox.GroupSize = Provider.BytesPerValue; HexBox.GroupSeparatorVisible = Provider.BytesPerValue > 1; HexBox.SelectionBackColor = Constants.SelectionColor; HexBox.SelectionForeColor = HexBox.ForeColor; string tagname; if (tag is NbtList list) { tagname = NbtUtil.TagTypeName(list.ListType) + " List"; this.Icon = NbtUtil.TagTypeImage(source, list.ListType).Icon; } else { tagname = NbtUtil.TagTypeName(tag.TagType); this.Icon = NbtUtil.TagTypeImage(source, tag.TagType).Icon; } if (purpose == EditPurpose.Create) { this.Text = $"Create {tagname} Tag"; } else if (purpose == EditPurpose.EditValue || purpose == EditPurpose.Rename) { this.Text = $"Edit {tagname} Tag"; } if (SettingName && purpose != EditPurpose.EditValue) { NameBox.Select(); NameBox.SelectAll(); } else { HexBox.Select(); } }
private void MarkObjectAsDelete(ObjectSerializer serializer, int oid, SqoTypeInfo ti) { foreach (FieldSqoInfo ai in ti.Fields) { IByteTransformer byteTrans = ByteTransformerFactory.GetByteTransformer(null, null, ai, ti); if (byteTrans is ArrayByteTranformer || byteTrans is DictionaryByteTransformer) { ATuple <int, int> arrayInfo = this.GetArrayMetaOfField(ti, oid, ai); if (arrayInfo.Name > 0) { rawSerializer.MarkRawInfoAsFree(arrayInfo.Name);//this helps Shrink method to detect unused rawdata blocks. } } } serializer.MarkObjectAsDelete(oid, ti); }
private async Task MarkObjectAsDeleteAsync(ObjectSerializer serializer, int oid, SqoTypeInfo ti) { foreach (FieldSqoInfo ai in ti.Fields) { IByteTransformer byteTrans = ByteTransformerFactory.GetByteTransformer(null, null, ai, ti); if (byteTrans is ArrayByteTranformer || byteTrans is DictionaryByteTransformer) { ATuple <int, int> arrayInfo = await this.GetArrayMetaOfFieldAsync(ti, oid, ai).ConfigureAwait(false); if (arrayInfo.Name > 0) { await rawSerializer.MarkRawInfoAsFreeAsync(arrayInfo.Name).ConfigureAwait(false);//this helps Shrink method to detect unused rawdata blocks. } } } await serializer.MarkObjectAsDeleteAsync(oid, ti).ConfigureAwait(false); }
internal async Task <byte[]> GetObjectBytesAsync(ObjectInfo oi, RawdataSerializer rawSerializer) { byte[] oidBuff = ByteConverter.IntToByteArray(oi.Oid); byte[] buffer = new byte[oi.SqoTypeInfo.Header.lengthOfRecord]; int curentIndex = 0; Array.Copy(oidBuff, 0, buffer, curentIndex, oidBuff.Length); curentIndex += oidBuff.Length; bool oidToParentSet = false; foreach (FieldSqoInfo ai in oi.AtInfo.Keys) { byte[] by = null; if (ai.AttributeTypeId == MetaExtractor.complexID || ai.AttributeTypeId == (MetaExtractor.ArrayTypeIDExtra + MetaExtractor.complexID) || ai.AttributeTypeId == MetaExtractor.documentID) { //to be able to cache for circular reference, we need to asign OID to it if (!oidToParentSet) { //just set OID to parentObject, do not save anything ComplexObjectEventArgs args = new ComplexObjectEventArgs(true, oi); await this.OnNeedSaveComplexObjectAsync(args).ConfigureAwait(false); oidToParentSet = true; } } int parentOID = -1; if (!oi.Inserted) { parentOID = oi.Oid; } IByteTransformer byteTransformer = ByteTransformerFactory.GetByteTransformer(this, rawSerializer, ai, oi.SqoTypeInfo, parentOID); by = await byteTransformer.GetBytesAsync(oi.AtInfo[ai]).ConfigureAwait(false); Array.Copy(by, 0, buffer, curentIndex, by.Length); curentIndex += by.Length; } return(buffer); }
private string ConvertToText(IByteTransformer provider) { var bytes = provider.CurrentBytes.ToArray(); int size = provider.BytesPerValue; if (size == sizeof(byte)) { return(String.Join(" ", bytes.Select(x => (sbyte)x))); } if (size == sizeof(short)) { return(String.Join(" ", DataUtils.ToShortArray(bytes))); } if (size == sizeof(int)) { return(String.Join(" ", DataUtils.ToIntArray(bytes))); } if (size == sizeof(long)) { return(String.Join(" ", DataUtils.ToLongArray(bytes))); } throw new ArgumentException($"Can't convert bytes to a numeric type with size {size}"); }
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; } }
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 void ReadObject(object obj, SqoTypeInfo ti, int oid, RawdataSerializer rawSerializer) { //long position = (long)ti.Header.headerSize + (long)((long)(oid - 1) * (long)ti.Header.lengthOfRecord); long position = MetaHelper.GetSeekPosition(ti, oid); int recordLength = ti.Header.lengthOfRecord; byte[] b = new byte[recordLength]; if (oidEnd == 0 && oidStart == 0) { file.Read(position, b); } else { int recordPosition = (oid - oidStart) * recordLength; Array.Copy(preloadedBytes, recordPosition, b, 0, b.Length); } int fieldPosition = 0; byte[] oidBuff = GetFieldBytes(b, fieldPosition, 4); int oidFromFile = ByteConverter.ByteArrayToInt(oidBuff); //eventual make comparison foreach (FieldSqoInfo ai in ti.Fields) { byte[] field = GetFieldBytes(b, ai.Header.PositionInRecord, ai.Header.Length); IByteTransformer byteTransformer = ByteTransformerFactory.GetByteTransformer(this, rawSerializer, ai, ti); object fieldVal = null; try { fieldVal = byteTransformer.GetObject(field); } catch (Exception ex) { if (ti.Type != null && ti.Type.IsGenericType() && ti.Type.GetGenericTypeDefinition() == typeof(Indexes.BTreeNode <>)) { throw new IndexCorruptedException(); } // SiaqodbConfigurator.LogMessage("Field's" + ai.Name + " value of Type " + ti.TypeName + "cannot be loaded, will be set to default.", VerboseLevel.Info); //fieldVal = MetaHelper.GetDefault(ai.AttributeType); throw ex; } if (ai.AttributeTypeId == MetaExtractor.documentID) { DocumentInfo dinfo = fieldVal as DocumentInfo; if (dinfo != null) { if (SiaqodbConfigurator.DocumentSerializer == null) { throw new SiaqodbException("Document serializer is not set, use SiaqodbConfigurator.SetDocumentSerializer method to set it"); } fieldVal = SiaqodbConfigurator.DocumentSerializer.Deserialize(ai.AttributeType, dinfo.Document); //put in weak cache to be able to update the document DocumentEventArgs args = new DocumentEventArgs(); args.ParentObject = obj; args.DocumentInfoOID = dinfo.OID; args.FieldName = ai.Name; args.TypeInfo = ti; this.OnNeedCacheDocument(args); } } #if SILVERLIGHT try { //dobj.SetValue(ai.FInfo, ByteConverter.DeserializeValueType(ai.FInfo.FieldType, field)); MetaHelper.CallSetValue(ai.FInfo, fieldVal, obj, ti.Type); } catch (Exception ex) { throw new SiaqodbException("Override GetValue and SetValue methods of SqoDataObject-Silverlight limitation to private fields"); } #else ai.FInfo.SetValue(obj, fieldVal); #endif } }