Exemple #1
0
 /// <summary>
 /// Load/renew cache if versions doesnt match
 /// </summary>
 private void sync_cache()
 {
     if ((CURRENT_ALLOC == base.ALLOC) & (FCache != null))
     {
         return;
     }
     else
     {
         if (base.ALLOC == ALLOC_TYPE_RAW)
         {
             if (FreeSpace >= 0)
             {
                 FCache.Clear();
                 FCache     = null;
                 FCacheTree = null;
                 FreeSpace  = -1;
                 set_alloc(ALLOC_RESET);
             }
         }
         else
         {
             deserialize();          // Load and cache new version of the fields
         }
     }
 }
        /// <summary>
        ///  Build binary trees for FBQE
        /// </summary>
        internal void BuildBTrees()
        {
            BT_FBQE_Address = new VSBBTree("ADDR", 0, true);
            BT_FBQE_Size    = new VSBBTree("SIZE", 0, false);

            int i = this.FIRST;

            while (i >= 0)
            {
                FBQE f = GetFBQE(i);
                BT_FBQE_Address.Insert(f.ADDRESS_START, (long)f.index);
                BT_FBQE_Size.Insert(f.LENGTH, (long)f.index);
                i = f.NEXT;
            }
        }
Exemple #3
0
        /// <summary>
        /// Load cahce fields
        /// </summary>
        private void deserialize()
        {
            CURRENT_ALLOC = base.ALLOC;

            // Create/cleanup fields cache
            if (FCache == null)
            {
                FCache = new List <FieldCache>(32);
            }
            else
            {
                FCache.Clear();
            }

            // Create cache binary tree
            FCacheTree = new VSBBTree(FCT_NAME, 32, true);

            // Read variable data into the buffer
            byte[] data = base.ReadBytes(base.FIXED, (long)FIELDS_SIZE);

            int offset = FIRST_FIELD_OFFSET_REL;                                    // Offset inside buffer (relative, doesn't include fixed part)

            int n = (int)FIELDS_NUMBER;                                             // Number of fields

            // Load fields
            for (int i = 0; i < n; i++)
            {
                // Create field
                FieldCache f = new FieldCache();
                f.OFFSET = offset;                                                                                              // Field offset in object
                f.TYPE   = data[offset + FIELD_TYPE_POS];                                                                       // Field type

                byte name_length = data[offset + FIELD_NAME_LENGTH_POS];                                                        // Name length
                f.NAME = VSLib.ConvertByteToString(VSLib.GetByteArray(data, (int)(offset + FIELD_NAME_POS), (int)name_length)); // Name

                int value_offset = FIELD_FIXED_LENGTH + name_length;                                                            // Value offset

                // Get value depending on type
                if ((f.TYPE == FIELD_TYPE_BYTE) | (f.TYPE == FIELD_TYPE_SHORT) | (f.TYPE == FIELD_TYPE_DATETIME))
                {
                    f.DATA_OFFSET = value_offset;                                   // Shift to value offset
                    f.LENGTH      = FIELD_LENGTHS[f.TYPE];
                }
                else if ((f.TYPE == FIELD_TYPE_INT) | (f.TYPE == FIELD_TYPE_LONG))
                {
                    f.DATA_OFFSET = value_offset + 1;                               // Shift to value offset (+ 1 byte length)
                    f.LENGTH      = (int)data[offset + value_offset];
                }
                else if ((f.TYPE == FIELD_TYPE_BYTES) | (f.TYPE == FIELD_TYPE_STRING))
                {
                    int l = (int)data[offset + value_offset];                       // Read number of length bytes
                    if (l > 0)
                    {
                        byte[] ba = VSLib.GetByteArray(data, (int)(offset + value_offset + 1), (int)l);      // Read length
                        f.LENGTH = VSLib.ConvertByteToInt(decompress(ba, FIELD_TYPE_LONG));
                    }
                    else
                    {
                        f.LENGTH = 0;
                    }

                    f.DATA_OFFSET = value_offset + 1 + l;
                }
                else
                {
                    throw new VSException(DEFS.E0029_INVALID_FIELD_TYPE_CODE, "- " + f.TYPE.ToString());
                }

                f.OLDLENGTH   = f.LENGTH;
                f.STATE       = STATE_LOADED;
                f.FULL_LENGTH = f.DATA_OFFSET + f.LENGTH;

                if (f.LENGTH > 0)
                {
                    f.VALUE = VSLib.GetByteArray(data, (int)(offset + f.DATA_OFFSET), (int)f.LENGTH);
                }
                else
                {
                    f.VALUE = new byte[0];
                }

                offset += f.FULL_LENGTH;

                f.DELETED = false;

                // Add to cache
                FCache.Add(f);

                // Add to the tree
                FCacheTree.Insert(f.NAME, i);
            }
            FreeSpace = (int)(this.Size - base.FIXED - offset);
        }
Exemple #4
0
        /// <summary>
        /// Generic Set
        /// </summary>
        /// <param name="serialize">false = do not write (for multiple values at once)</param>
        /// <returns></returns>
        private void set_field(string name, byte type, byte[] data, bool serialize = true)
        {
            string nm = name.Trim();

            if ((nm.Length < 1) | (nm.Length > 255))
            {
                throw new VSException(DEFS.E0027_FIELD_WRITE_ERROR_CODE, "- " + name + " : name length shall be between 1 and 255");
            }

            FieldCache fc;
            int        index;

            byte[] compressed_length = null;                           // Compressed length

            // Initialize fields structure
            if (base.ALLOC == ALLOC_TYPE_RAW)
            {
                index = -1;

                set_alloc(ALLOC_INIT);

                FreeSpace     = (int)(this.Size - FIRST_FIELD_OFFSET_ABS);
                FIELDS_NUMBER = (short)0;
                FIELDS_SIZE   = FIRST_FIELD_OFFSET_REL;

                // Create cache
                FCache = new List <FieldCache>(32);
                // Create cache binary tree
                FCacheTree = new VSBBTree(FCT_NAME, 32, true);
            }
            else
            {
                index = find_field(nm, type);
            }


            // Field is not found in cache, add new field
            if (index < 0)
            {
                fc             = new FieldCache();
                fc.STATE       = STATE_NEW;                             // New field
                fc.OFFSET      = -1;
                fc.NAME        = nm;
                fc.VALUE       = compress(data, type);
                fc.LENGTH      = fc.VALUE.Length;
                fc.OLDLENGTH   = fc.VALUE.Length;
                fc.TYPE        = type;
                fc.DATA_OFFSET = FIELD_NAME_POS + fc.NAME.Length;

                if ((fc.TYPE == FIELD_TYPE_INT) | (fc.TYPE == FIELD_TYPE_LONG))
                {
                    fc.DATA_OFFSET += 1;
                }
                else if ((fc.TYPE == FIELD_TYPE_BYTES) | (fc.TYPE == FIELD_TYPE_STRING))
                {
                    compressed_length = compress(VSLib.ConvertLongToByte(fc.LENGTH), FIELD_TYPE_LONG);
                    fc.DATA_OFFSET   += (compressed_length.Length + 1);
                }

                fc.FULL_LENGTH = fc.DATA_OFFSET + fc.LENGTH;

                // Add to the tree
                FCacheTree.Insert(fc.NAME, (long)FCache.Count);

                // Add to the cache
                FCache.Add(fc);
            }
            else
            { // Field found in cache, update
                fc = FCache[index];

                byte[] b = compress(data, type);

                if (b.Length == fc.LENGTH)
                {
                    if (b.Length == 0)
                    {
                        return;
                    }

                    bool eq = true;
                    for (int i = 0; i < b.Length; i++)
                    {
                        if (b[i] != fc.VALUE[i])
                        {
                            eq = false;
                            break;
                        }
                    }

                    if (eq)
                    {
                        return;             // Value not changed
                    }
                    for (int i = 0; i < b.Length; i++)
                    {
                        fc.VALUE[i] = b[i];
                    }

                    base.Write(base.FIXED + fc.OFFSET + fc.DATA_OFFSET, b, fc.LENGTH);
                    fc.STATE = STATE_LOADED;

                    FCache.RemoveAt(index);
                    FCache.Insert(index, fc);

                    set_alloc(ALLOC_RENEW);

                    return;
                }

                fc.VALUE       = b;
                fc.LENGTH      = fc.VALUE.Length;
                fc.DATA_OFFSET = FIELD_NAME_POS + fc.NAME.Length;

                if ((fc.TYPE == FIELD_TYPE_INT) | (fc.TYPE == FIELD_TYPE_LONG))
                {
                    fc.DATA_OFFSET += 1;
                }
                else if ((fc.TYPE == FIELD_TYPE_BYTES) | (fc.TYPE == FIELD_TYPE_STRING))
                {
                    compressed_length = compress(VSLib.ConvertLongToByte(fc.LENGTH), FIELD_TYPE_LONG);
                    fc.DATA_OFFSET   += (compressed_length.Length + 1);
                }

                fc.FULL_LENGTH = fc.DATA_OFFSET + fc.LENGTH;       // Update full length
                fc.STATE       = STATE_UPDATED;

                FCache.RemoveAt(index);
                FCache.Insert(index, fc);
            }
            if (serialize)
            {
                this.serialize();
            }
        }