Provides utility functions for working with big-endian numbers.
예제 #1
0
파일: Quetzal.cs 프로젝트: DESYS21/FyreVM
        /// <summary>
        /// Reconstitutes a changed block of memory by applying a compressed
        /// set of differences to the original block from the game file.
        /// </summary>
        /// <param name="original">The original block of memory.</param>
        /// <param name="delta">The RLE-compressed set of differences,
        /// prefixed with a 4-byte length. This length may be larger than
        /// the original block, but not smaller.</param>
        /// <returns>The changed block of memory. The length of this array is
        /// specified at the beginning of <paramref name="delta"/>.</returns>
        public static byte[] DecompressMemory(byte[] original, byte[] delta)
        {
            MemoryStream mstr   = new MemoryStream(delta);
            uint         length = BigEndian.ReadInt32(mstr);

            if (length < original.Length)
            {
                throw new ArgumentException("Compressed block's length tag must be no less than original block's size");
            }

            byte[] result = new byte[length];
            int    rp     = 0;

            for (int i = 4; i < delta.Length; i++)
            {
                byte b = delta[i];
                if (b == 0)
                {
                    int repeats = delta[++i] + 1;
                    Array.Copy(original, rp, result, rp, repeats);
                    rp += repeats;
                }
                else
                {
                    result[rp] = (byte)(original[rp] ^ b);
                    rp++;
                }
            }

            while (rp < original.Length)
            {
                result[rp] = original[rp];
                rp++;
            }

            return(result);
        }
예제 #2
0
        /// <summary>
        /// Initializes a new allocator from a previous saved heap state.
        /// </summary>
        /// <param name="savedHeap">A byte array describing the heap state,
        /// as returned by the <see cref="Save"/> method.</param>
        /// <param name="requester">A delegate to request more memory.</param>
        public HeapAllocator(byte[] savedHeap, MemoryRequester requester)
        {
            this.heapAddress = BigEndian.ReadInt32(savedHeap, 0);
            this.setEndMem   = requester;
            this.blocks      = new List <HeapEntry>();
            this.freeList    = new List <HeapEntry>();

            uint numBlocks = BigEndian.ReadInt32(savedHeap, 4);

            blocks.Capacity = (int)numBlocks;
            uint nextAddress = heapAddress;

            for (uint i = 0; i < numBlocks; i++)
            {
                uint start  = BigEndian.ReadInt32(savedHeap, 8 * i + 8);
                uint length = BigEndian.ReadInt32(savedHeap, 8 * i + 12);
                blocks.Add(new HeapEntry(start, length));

                if (nextAddress < start)
                {
                    freeList.Add(new HeapEntry(nextAddress, start - nextAddress));
                }

                nextAddress = start + length;
            }

            endMem     = nextAddress;
            heapExtent = nextAddress - heapAddress;

            if (setEndMem(endMem) == false)
            {
                throw new ArgumentException("Can't allocate VM memory to fit saved heap");
            }

            blocks.Sort(entryComparer);
            freeList.Sort(entryComparer);
        }
예제 #3
0
파일: Quetzal.cs 프로젝트: DESYS21/FyreVM
        /// <summary>
        /// Writes the chunks to a Quetzal file.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        public void WriteToStream(Stream stream)
        {
            BigEndian.WriteInt32(stream, FORM); // IFF tag
            BigEndian.WriteInt32(stream, 0);    // file length (filled in later)
            BigEndian.WriteInt32(stream, IFZS); // FORM sub-ID for Quetzal

            uint totalSize = 4;                 // includes sub-ID

            foreach (KeyValuePair <uint, byte[]> pair in chunks)
            {
                BigEndian.WriteInt32(stream, pair.Key);                 // chunk type
                BigEndian.WriteInt32(stream, (uint)pair.Value.Length);  // chunk length
                stream.Write(pair.Value, 0, pair.Value.Length);         // chunk data
                totalSize += 8 + (uint)(pair.Value.Length);
            }

            if (totalSize % 2 == 1)
            {
                stream.WriteByte(0);    // padding (not counted in file length)
            }
            stream.Seek(4, SeekOrigin.Begin);
            BigEndian.WriteInt32(stream, totalSize);
            //stream.SetLength(totalSize);
        }
예제 #4
0
 /// <summary>
 /// Reads a big-endian double word from memory.
 /// </summary>
 /// <param name="offset">The address to read from.</param>
 /// <returns>The 32-bit value at the specified address.</returns>
 public uint ReadInt32(uint offset)
 {
     return(BigEndian.ReadInt32(memory, offset));
 }
예제 #5
0
 /// <summary>
 /// Reads a big-endian word from memory.
 /// </summary>
 /// <param name="offset">The address to read from</param>
 /// <returns>The word at the specified address.</returns>
 public ushort ReadInt16(uint offset)
 {
     return(BigEndian.ReadInt16(memory, offset));
 }