/// <summary> /// Write FBQE /// </summary> /// <param name="f"></param> private void SerializeFBQE(FBQE f) { VSLib.CopyBytes(buffer, VSLib.ConvertStringToByte(DEFS.FBQE_SIGNATURE), f.address + SG_POS, SG_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_START), f.address + ADDRESS_START_POS, ADDRESS_START_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.ADDRESS_END), f.address + ADDRESS_END_POS, ADDRESS_END_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertLongToByte(f.LENGTH), f.address + LENGTH_POS, LENGTH_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.PREV), f.address + PREV_POS, PREV_LEN); VSLib.CopyBytes(buffer, VSLib.ConvertIntToByte(f.NEXT), f.address + NEXT_POS, NEXT_LEN); F_Object.Write(f.address, VSLib.GetByteArray(buffer, f.address, FBQE_LENGTH), FBQE_LENGTH); }
/// <summary> /// Delete reference /// </summary> /// <param name="rf"></param> /// <returns></returns> internal bool delete_ref(long rf) { int x = -1; List <long> refs = REFS.ToList <long>(); int count = refs.Count; for (int i = 0; i < count; i++) { int i2 = count - 1 - i; if (i > i2) { break; } if (refs[i] == rf) { x = i; } else if (refs[i2] == rf) { x = i2; } if (x > 0) { break; } } if (x < 0) { return(false); } else { refs.RemoveAt(x); } byte[] refs_new = new byte[refs.Count * 8]; for (int i = 0; i < refs.Count; i++) { VSLib.CopyBytes(refs_new, VSLib.ConvertLongToByte(refs[i]), (i * 8), 8); } ALLOCATION.Write(this.REF_POS, refs_new, refs_new.Length); // Write REF_COUNT = refs.Count; return(true); }
/// <summary> /// Serialize all fields to object fields space /// Free excessive chunks if needed /// </summary> private void serialize() { // If no fields if (FCache.Count == 0) { set_alloc(ALLOC_RESET); FIELDS_SIZE = 0; FreeSpace = -1; FCache = null; return; } byte[] b = null; int old_size = (int)(FIELDS_SIZE); // Current used size (number of fields + all fields size) // 1. Calculate new size int new_size = FIRST_FIELD_OFFSET_REL; for (int i = 0; i < FCache.Count; i++) { new_size += FCache[i].FULL_LENGTH; } // 2. Check if space is availabe, extend if required if (new_size > (old_size + FreeSpace)) { sp.Extend(this, (new_size - old_size)); } // 3. Check if only value update is required List <FieldCache> afc = FCache; FCache = new List <FieldCache>(32); int array_size = (new_size > old_size) ? new_size : old_size; byte[] data = new byte[array_size]; int data_pos = FIRST_FIELD_OFFSET_REL; VSLib.CopyBytes(data, VSLib.ConvertIntToByte(new_size), FIELDS_SIZE_POS, FIELDS_SIZE_LEN); // Size VSLib.CopyBytes(data, VSLib.ConvertShortToByte((short)afc.Count), FIELDS_NUMBER_POS, FIELDS_NUMBER_LEN); // Fields number FCache.Clear(); for (int i = 0; i < afc.Count; i++) { FieldCache fc_element = afc[i]; if (!fc_element.DELETED) { fc_element.OFFSET = data_pos; // Type data[data_pos] = fc_element.TYPE; data_pos++; // Name length data[data_pos] = (byte)(fc_element.NAME.Length); data_pos++; // Name b = VSLib.ConvertStringToByte(fc_element.NAME); VSLib.CopyBytes(data, b, data_pos, b.Length); data_pos += b.Length; // Value if (FIELD_COMPRESS[fc_element.TYPE]) // int/long/decimal { data[data_pos] = (byte)(fc_element.LENGTH); data_pos++; } else if ((fc_element.TYPE == FIELD_TYPE_BYTES) | (fc_element.TYPE == FIELD_TYPE_STRING)) { b = compress(VSLib.ConvertLongToByte(fc_element.LENGTH), FIELD_TYPE_LONG); data[data_pos] = (byte)b.Length; data_pos++; if (b.Length > 0) { VSLib.CopyBytes(data, b, data_pos, b.Length); data_pos += b.Length; } } // Write value if (fc_element.VALUE.Length > 0) { VSLib.CopyBytes(data, fc_element.VALUE, data_pos, fc_element.VALUE.Length); data_pos += afc[i].LENGTH; } // Shift offset and add to cache fc_element.OLDLENGTH = afc[i].LENGTH; fc_element.STATE = STATE_LOADED; FCacheTree.Insert(fc_element.NAME, FCache.Count); FCache.Add(fc_element); } } base.Write(base.FIXED, data, data.Length); set_alloc(ALLOC_RENEW); // Fill the rest by zeros if le length < old length if (new_size < old_size) { long full_used_size = base.FIXED + new_size; b = new byte[old_size - new_size]; base.Write(full_used_size, b, b.Length); // Fill be zeros unused space // Multiple chunks, chech if there are exessive if (base.Chunk > 0) { sp.ShrinkObject(this, full_used_size); } } FreeSpace = (int)(this.Size - base.FIXED - new_size); }