Exemple #1
0
        /**
         * <summary>Remove a tag from the list.</summary>
         *
         * <param name="key">The key to remove.</param>
         * <returns>If the deletion was successfully done.</returns>
         */
        public bool Delete(string key)
        {
            if (!file.Exists)
            {
                return(false);
            }
            using (MemoryStream decompressedData = new MemoryStream())
            {
                using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (Stream stream = GetDecompressStream(fs))
                        stream.CopyTo(decompressedData);

                KeyScout counter = InternalUtils.ScoutObjectData(decompressedData.ToArray(), key, new KeyScout());
                if (counter == null)
                {
                    return(false);
                }
                byte[] recompressed = InternalUtils.deleteSubObjectData(decompressedData.ToArray(), counter);

                using (FileStream newFile = new FileStream(file.FullName, FileMode.Open, FileAccess.Write, FileShare.Write))
                {
                    newFile.SetLength(0);
                    using (Stream compressStream = GetCompressStream(newFile))
                        compressStream.Write(recompressed, 0, recompressed.Length);
                }
            }

            return(true);
        }
Exemple #2
0
        /**
         * <summary>Replace a key with another tag.</summary>
         * <param name="key">The key</param>
         * <param name="replacement">The data to replace the key</param>
         * <returns>If the replacement was successful.</returns>
         */
        public bool ReplaceData(string key, ITag replacement)
        {
            if (!file.Exists)
            {
                return(false);
            }
            using (MemoryStream decompressed = new MemoryStream())
            {
                using (FileStream fs = new FileStream(file.FullName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    using (Stream compStream = GetDecompressStream(fs))
                        compStream.CopyTo(decompressed);

                KeyScout counter = InternalUtils.ScoutObjectData(decompressed.ToArray(), key, new KeyScout());
                if (counter.GetEnd() == null)
                {
                    return(false);
                }

                MemoryStream    memStream = new MemoryStream();
                BigBinaryWriter bbw       = new BigBinaryWriter(memStream);
                replacement.WriteData(bbw);
                bbw.Close();

                byte[] replaceReturn = InternalUtils.ReplaceSubObjectData(decompressed.ToArray(), counter, memStream.ToArray());

                using (FileStream newFile = new FileStream(file.FullName, FileMode.Create, FileAccess.Write, FileShare.Write))
                {
                    newFile.SetLength(0);
                    using (Stream stream = GetCompressStream(newFile))
                        stream.Write(replaceReturn, 0, replaceReturn.Length);
                }
            }
            return(true);
        }
Exemple #3
0
        /**
         * <summary>Insert in a new tag.</summary>
         * <param name="data">The input array of bytes.</param>
         * <param name="counter">The KeyScout object containing information of the tag to set.</param>
         * <param name="dataToReplace">The bytes of the replacement data.</param>
         *
         * <returns>The output bytes.</returns>
         */
        public static byte[] SetSubObjectData(byte[] data, KeyScout counter, byte[] dataToReplace)
        {
            KeyScoutChild child = counter.GetChildren()[counter.GetChildren().Count - 1];


            byte[] array1 = new byte[data.Length + dataToReplace.Length];
            Array.Copy(data, 0, array1, 0, child.GetStartingIndex() + 4 + child.GetSize());
            Array.Copy(dataToReplace, 0, array1, child.GetStartingIndex() + 4 + child.GetSize(), dataToReplace.Length);
            Array.Copy(data, (child.GetStartingIndex() + 4 + child.GetSize()), array1, (child.GetStartingIndex() + 4 + child.GetSize()) + dataToReplace.Length,
                       data.Length - (child.GetStartingIndex() + 4 + child.GetSize()));

            counter.AddAmount(dataToReplace.Length);

            foreach (KeyScoutChild childs in counter.GetChildren())
            {
                int index = childs.GetStartingIndex();
                int size  = childs.GetSize();
                array1[index]     = (byte)(size >> 24);
                array1[index + 1] = (byte)(size >> 16);
                array1[index + 2] = (byte)(size >> 8);
                array1[index + 3] = (byte)(size);
            }

            return(array1);
        }
Exemple #4
0
        /**
         * <summary>
         * Replace a tag with another tag.
         * </summary>
         * <param name="data">The input array of bytes</param>
         * <param name="counter">The KeyScout object conatining the information of the tag to replace.</param>
         * <param name="dataToReplace">The bytes of the replacement data.</param>
         * <returns>The byte array after the replacement.</returns>
         */
        public static byte[] ReplaceSubObjectData(byte[] data, KeyScout counter, byte[] dataToReplace)
        {
            counter.RemoveAmount(counter.GetEnd().GetSize() + 5);
            counter.AddAmount(dataToReplace.Length);

            KeyScoutChild end = counter.GetEnd();


            byte[] array1 = new byte[data.Length - (5 + end.GetSize()) + dataToReplace.Length];
            //Copy all of the information before the removed data.
            Array.Copy(data, 0, array1, 0, (end.GetStartingIndex() - 1));
            Array.Copy(dataToReplace, 0, array1, end.GetStartingIndex() - 1, dataToReplace.Length);
            // copy all of the information after the removed data.
            Array.Copy(data, end.GetStartingIndex() + 4 + end.GetSize(),
                       array1, end.GetStartingIndex() - 1 + dataToReplace.Length,
                       data.Length - (end.GetStartingIndex() + 4 + end.GetSize()));

            foreach (KeyScoutChild child in counter.GetChildren())
            {
                int index = child.GetStartingIndex();
                int size  = child.GetSize();
                array1[index]     = (byte)(size >> 24);
                array1[index + 1] = (byte)(size >> 16);
                array1[index + 2] = (byte)(size >> 8);
                array1[index + 3] = (byte)(size);
            }

            return(array1);
        }
Exemple #5
0
        /**
         * <summary>
         * This object goes through the data and scouts out the information from the given key.
         * This method is recursive, which is why the parameter offset exists.
         * </summary>
         *
         * <param name="data">The input array of bytes</param>
         * <param name="key">The key</param>
         * <param name="counter">The Scout object</param>
         * <param name="startIndex">The starting index for the count.</param>
         * <returns>The key scout.</returns>
         */
        public static KeyScout ScoutObjectData(byte[] data, string key, KeyScout counter, int startIndex)
        {
            MemoryStream    stream         = new MemoryStream(data);
            BigBinaryReader binReader      = new BigBinaryReader(stream);
            TagBuilder      currentBuilder = new TagBuilder();

            binReader.BaseStream.Seek(0, SeekOrigin.Begin);

            string name     = key.Split('.')[0];
            string otherKey = getKey(key.Split('.'));

            while (binReader.BaseStream.Position != binReader.BaseStream.Length)
            {
                KeyScoutChild child = new KeyScoutChild();
                currentBuilder.setDataType(binReader.ReadByte());
                child.SetStartingIndex((int)binReader.BaseStream.Position + startIndex);
                currentBuilder.setDataSize(binReader.ReadInt32());
                currentBuilder.setStartingIndex(binReader.BaseStream.Position);
                currentBuilder.setNameSize(binReader.ReadInt16());

                if (currentBuilder.getNameSize() != Encoding.UTF8.GetByteCount(name))
                {
                    binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current);
                    currentBuilder = new TagBuilder();
                    continue;
                }

                byte[] nameBytes = binReader.ReadBytes(currentBuilder.getNameSize());
                string tagName   = Encoding.UTF8.GetString(nameBytes);
                currentBuilder.setName(tagName);
                if (tagName != name)
                {
                    binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current);
                    currentBuilder = new TagBuilder();
                    continue;
                }
                int    binPos = (int)binReader.BaseStream.Position;
                byte[] value  = binReader.ReadBytes((int)(currentBuilder.getStartingIndex() - stream.Position) + (int)currentBuilder.getDataSize());
                currentBuilder.setValueBytes(value);

                binReader.Close();


                if (otherKey != null)
                {
                    validateNotCompressed(currentBuilder);

                    child.SetSize(currentBuilder.getDataSize());
                    child.SetName(currentBuilder.getName());
                    counter.AddChild(child);
                    return(ScoutObjectData(currentBuilder.getValueBytes(), otherKey, counter, binPos + startIndex));
                }
                child.SetSize(currentBuilder.getDataSize());
                child.SetName(currentBuilder.getName());
                counter.SetEnd(child);
                return(counter);
            }
            return(null);
        }
Exemple #6
0
        /**
         * <summary>Remove a tag from the list.</summary>
         *
         * <param name="key">The key to remove.</param>
         * <returns>If the deletion was successfully done.</returns>
         */
        public bool Delete(string key)
        {
            KeyScout counter = InternalUtils.ScoutObjectData(memStream.ToArray(), key, new KeyScout());

            if (counter == null)
            {
                return(false);
            }
            byte[] recompressed = InternalUtils.deleteSubObjectData(memStream.ToArray(), counter);

            memStream.SetLength(0);
            memStream.Position = 0;
            memStream.Write(recompressed, 0, recompressed.Length);

            return(true);
        }
Exemple #7
0
        /**
         * <summary>Replace a key with another tag.</summary>
         * <param name="key">The key</param>
         * <param name="replacement">The data to replace the key</param>
         * <returns>If the replacement was successful.</returns>
         */
        public bool ReplaceData(string key, ITag replacement)
        {
            KeyScout counter = InternalUtils.ScoutObjectData(memStream.ToArray(), key, new KeyScout());

            if (counter.GetEnd() == null)
            {
                return(false);
            }

            MemoryStream    tempStream = new MemoryStream();
            BigBinaryWriter bbw        = new BigBinaryWriter(tempStream);

            replacement.WriteData(bbw);
            bbw.Close();

            byte[] replaceReturn = InternalUtils.ReplaceSubObjectData(memStream.ToArray(), counter, tempStream.ToArray());
            memStream.SetLength(0);
            memStream.Position = 0;
            memStream.Write(replaceReturn, 0, replaceReturn.Length);
            return(true);
        }
Exemple #8
0
        /**
         * <summary>Delete a tag from an array of bytes using the KeyScout.</summary>
         *
         * <param name="data">The byte array to remove data from.</param>
         * <param name="counter">The KeyScout that contains information about the tag to remove.</param>
         * <returns>The byte array after the deletion.</returns>
         */
        public static byte[] deleteSubObjectData(byte[] data, KeyScout counter)
        {
            counter.RemoveAmount(counter.GetEnd().GetSize() + 5);

            KeyScoutChild end = counter.GetEnd();

            byte[] array1 = new byte[data.Length - (5 + end.GetSize())];
            Array.Copy(data, 0, array1, 0, (end.GetStartingIndex() - 1));
            Array.Copy(data, end.GetStartingIndex() + 4 + end.GetSize(),
                       array1, end.GetStartingIndex() - 1,
                       data.Length - (end.GetStartingIndex() + 4 + end.GetSize()));

            foreach (KeyScoutChild child in counter.GetChildren())
            {
                int index = child.GetStartingIndex();
                int size  = child.GetSize();
                array1[index]     = (byte)(size >> 24);
                array1[index + 1] = (byte)(size >> 16);
                array1[index + 2] = (byte)(size >> 8);
                array1[index + 3] = (byte)size;
            }

            return(array1);
        }
Exemple #9
0
        /**
         * <summary>
         * This method can append, delete, and set tags.
         * <para>A note on keys when appending: <code>ObjectOne.ObjectTwo.tagName</code> When appending data <c>tagName</c> will not be the actual tag name.
         * The tag name written to the file is the name of the specified tag in the value parameter. Any parent objects that do not exist will be created. For example:
         * <code>ObjectOne.ObjectTwo.NewObject.tagName</code> If in the example above <c>NewObject</c> does not exist, than the object will be created with the value tag inside
         * of it. Please see the wiki for a more detailed explanation on this.</para>
         * <para>When value is null, the specified key is deleted. <c>The key MUST exist or an {@link ODSException} will be thrown.</c></para>
         * </summary>
         *
         * <param name="key">
         * The key of the tag to append, delete, or set.
         * <para>When appending the key does not need to exist. ObjectTags that don't exist will be created automatically.</para>
         * <para>When the key is set to "" (An empty string) than it is assumed you want to append to the parent file.</para>
         * <para>Valid Tags:</para>
         *  <code>
         *  <para>ObjectOne.tagToDelete</para>
         *  <para>ObjectOne.NewObject.tagToAppend</para>
         *  <para>ObjectOne.tagToSet</para>
         *  </code>
         * </param>
         *
         * <param name="value">The tag to append or replace the key with. <para>If this parameter is null than the key will be deleted.</para></param>
         *
         */
        public void Set(string key, ITag value)
        {
            if (value == null)
            {
                bool output = Delete(key);
                if (!output)
                {
                    throw new ODSException("The key " + key + " does not exist!");
                }
                return;
            }
            if (key == "")
            {
                Save(new List <ITag>()
                {
                    value
                });
                return;
            }
            byte[] uncompressed = memStream.ToArray();

            KeyScout counter = InternalUtils.ScoutObjectData(uncompressed, key, new KeyScout());

            if (counter.GetEnd() == null)
            {
                if (counter.GetChildren().Count < 1)
                {
                    Append(value);
                    return;
                }
                string existingKey = "";
                foreach (KeyScoutChild child in counter.GetChildren())
                {
                    if (existingKey.Length != 0)
                    {
                        existingKey += ".";
                    }
                    existingKey += child.GetName();
                }
                string newKey = key.Replace(existingKey + ".", "");
                ITag   currentData;
                if (newKey.Split('.').Length > 1)
                {
                    ObjectTag     output = null;
                    ObjectTag     curTag = null;
                    List <string> keys   = new List <string>(newKey.Split('.'));
                    int           i      = 0;
                    foreach (string s in keys)
                    {
                        if (i == 0)
                        {
                            output = new ObjectTag(s);
                            curTag = output;
                        }
                        else if (i == keys.Count - 1)
                        {
                            curTag.AddTag(value);
                        }
                        else
                        {
                            ObjectTag tag = new ObjectTag(s);
                            curTag.AddTag(tag);
                            curTag = tag;
                        }
                        i++;
                    }
                    currentData = output;
                }
                else
                {
                    currentData = value;
                }
                // Actually replace the data and write it to the file.
                MemoryStream    tempStream = new MemoryStream();
                BigBinaryWriter bbw        = new BigBinaryWriter(tempStream);
                currentData.WriteData(bbw);
                bbw.Close();
                byte[] outputArray = InternalUtils.SetSubObjectData(uncompressed, counter, tempStream.ToArray());

                memStream.SetLength(0);
                memStream.Position = 0;
                memStream.Write(outputArray, 0, outputArray.Length);
            }
            else
            {
                MemoryStream    tempStream = new MemoryStream();
                BigBinaryWriter bbw        = new BigBinaryWriter(tempStream);
                value.WriteData(bbw);
                bbw.Close();

                byte[] replaceReturn = InternalUtils.ReplaceSubObjectData(uncompressed, counter, tempStream.ToArray());

                memStream.SetLength(0);
                memStream.Position = 0;
                memStream.Write(replaceReturn, 0, replaceReturn.Length);
            }
        }
Exemple #10
0
 /**
  * <summary>
  * This object goes through the data and scouts out the information from the given key.
  * This method is recursive, which is why the parameter offset exists.
  * </summary>
  *
  * <param name="data">The input array of bytes</param>
  * <param name="key">The key</param>
  * <param name="counter">The Scout object</param>
  * <returns>The key scout.</returns>
  */
 public static KeyScout ScoutObjectData(byte[] data, string key, KeyScout counter)
 {
     return(ScoutObjectData(data, key, counter, 0));
 }