Пример #1
0
        public MCSResource(int version)
        {
            magicHeader = MCSConstants.MR_MAGIC_NUMBER;

            switch (version)
            {
            case 1:
                header = new M3DResourceHeaderV1();
                break;

            case 2:
                header = new M3DResourceHeaderV2();
                break;

            default:
                break;
            }
        }
Пример #2
0
        //Adds or replaces an entry in the resource file
        public bool Upsert(string key, byte[] bytes, bool writeToDisk = true)
        {
            int count    = header.Keys.Length;
            int oldCount = count;

            //how much should we resize our body buffer?
            int deltaBytes  = bytes.Length;
            int upsertIndex = -1;

            //are we replacing or adding?
            bool replace = false;

            for (int i = 0; i < count; i++)
            {
                //since we're replacing it, recalculate the correct body size
                if (header.Keys[i].Equals(key))
                {
                    replace     = true;
                    deltaBytes  = bytes.Length - header.Lengths[i];
                    upsertIndex = i;
                    break;
                }
            }
            if (!replace)
            {
                upsertIndex = count;
                count++;
            }

            M3DResourceHeaderV2 newHeader = new M3DResourceHeaderV2();

            newHeader.FilePath  = header.FilePath;
            newHeader.Keys      = new string[count];
            newHeader.Positions = new int[count];
            newHeader.Lengths   = new int[count];

            byte[] newBody = new byte[body.Length + deltaBytes];

            int bodyIndex = 0;

            //build a new header
            for (int i = 0; i < count; i++)
            {
                string currentKey = (i < oldCount ? header.Keys[i] : key);
                newHeader.Keys[i] = currentKey;

                newHeader.Positions[i] = bodyIndex;

                if (i != upsertIndex)
                {
                    //copy the old one into the body
                    Array.Copy(body, header.Positions[i], newBody, bodyIndex, header.Lengths[i]);
                    newHeader.Lengths[i] = header.Lengths[i];
                }
                else
                {
                    //copy the new one into the body
                    Array.Copy(bytes, 0, newBody, bodyIndex, bytes.Length);
                    newHeader.Lengths[i] = bytes.Length;
                }
                bodyIndex += newHeader.Lengths[i];
            }

            header = newHeader;
            body   = newBody;

            if (writeToDisk && !String.IsNullOrEmpty(header.FilePath))
            {
                Serialize(header.FilePath);
            }

            return(true);
        }
Пример #3
0
        //Add file(s) to an existing resource (or new one)
        public bool Add(string key, List <string> paths)
        {
            int oldCount = header.Keys.Length;

            //we're adding a file...
            int count = oldCount + paths.Count;

            M3DResourceHeaderV1 newHeader = new M3DResourceHeaderV1();

            newHeader.FilePath  = header.FilePath;
            newHeader.Keys      = new string[count];
            newHeader.Positions = new int[count];
            newHeader.Lengths   = new int[count];

            //copy the old one into the new if applicable
            if (oldCount > 0)
            {
                Array.Copy(header.Keys, newHeader.Keys, oldCount);
                Array.Copy(header.Positions, newHeader.Positions, oldCount);
                Array.Copy(header.Lengths, newHeader.Lengths, oldCount);
            }

            int index = 0;

            if (oldCount > 0)
            {
                //advance the index to the end of the file
                index = body.Length;
            }

            //re-index the header positions and lengths
            int totalLen = 0;

            for (int i = 0; i < count; i++)
            {
                int    slot = i + oldCount;
                string path = paths[i];

                newHeader.Keys[slot]      = path;
                newHeader.Positions[slot] = totalLen;
                newHeader.Lengths[slot]   = (int)new FileInfo(paths[i]).Length;
                totalLen += newHeader.Lengths[slot];
            }

            //create a new body and copy the old one if we need to
            byte[] newBody = new byte[totalLen];
            if (oldCount > 0)
            {
                Array.Copy(body, newBody, body.Length);
            }

            for (int i = 0; i < count; i++)
            {
                int    slot = i + oldCount;
                string path = paths[i];

                byte[] buffer  = File.ReadAllBytes(paths[i]);
                int    fileLen = buffer.Length;

                Array.Copy(buffer, 0, newBody, index, fileLen);
                index += fileLen;
            }

            header = newHeader;
            body   = newBody;

            //if we have a current file path to save, save it
            if (header.FilePath != null)
            {
                Serialize(header.FilePath);
            }

            return(true); //success
        }
Пример #4
0
        protected void DeserializeHeader(byte[] buffer)
        {
            int pos = 0;

            //magic bytes
            int magicHeaderIn = System.BitConverter.ToInt32(buffer, pos);

            pos += MCSConstants.SIZE_OF_INT;

            if (magicHeader != magicHeaderIn)
            {
                throw new Exception("Magic header not found, invalid M3DResource file");
            }

            //version
            int version = System.BitConverter.ToInt32(buffer, pos);

            pos += MCSConstants.SIZE_OF_INT;

            switch (version)
            {
            case 1:                     //Version 1

                header = new M3DResourceHeaderV1();
                break;

            case 2:
                header = new M3DResourceHeaderV2();
                break;

            default:
                UnityEngine.Debug.LogError("Version: " + version + " is not supported, please verify you have the most up-to-date version of MCS");
                throw new Exception("Unknown M3DResource file version");
                break;
            }


            byte[] tmpBuf;

            //header size
            int headerBufferSize = System.BitConverter.ToInt32(buffer, pos);

            pos += MCSConstants.SIZE_OF_INT;

            positionBody = headerBufferSize;


            //body size
            int bodyBufferSize = System.BitConverter.ToInt32(buffer, pos);

            pos += MCSConstants.SIZE_OF_INT;

            //Utility Flag
            if (version > 1 && version <= MCSConstants.LATEST_MAJOR_VERSION)
            {
                header.UtilityFlag = System.BitConverter.ToInt32(buffer, pos);
                pos += MCSConstants.SIZE_OF_INT;
            }

            //Filepath
            int filePathLen = System.BitConverter.ToInt32(buffer, pos);

            pos += MCSConstants.SIZE_OF_INT;
            byte[] filePathBytes = new byte[filePathLen];
            System.Buffer.BlockCopy(buffer, pos, filePathBytes, 0, filePathLen);
            pos            += filePathLen;
            header.FilePath = System.Text.Encoding.UTF8.GetString(filePathBytes);
            //UnityEngine.Debug.Log("filePath: " + header.filePath);

            //Total Entries
            int totalEntries = System.BitConverter.ToInt32(buffer, pos);

            pos += MCSConstants.SIZE_OF_INT;
            //UnityEngine.Debug.Log("total entries: " + totalEntries);

            header.Keys      = new string[totalEntries];
            header.Positions = new int[totalEntries];
            header.Lengths   = new int[totalEntries];

            int totalKeysAsBytesLen = System.BitConverter.ToInt32(buffer, pos);

            pos += MCSConstants.SIZE_OF_INT;
            //UnityEngine.Debug.Log("totalKeysAsBytesLen : " + totalKeysAsBytesLen);

            //read each variable length key name until we're done
            for (int i = 0; i < totalEntries; i++)
            {
                int keyLen = System.BitConverter.ToInt32(buffer, pos);
                pos += MCSConstants.SIZE_OF_INT;

                tmpBuf = new byte[keyLen];

                //UnityEngine.Debug.Log("KeyLen: " + i + " | " + keyLen + " | " + buffer.Length);

                System.Buffer.BlockCopy(buffer, pos, tmpBuf, 0, keyLen);
                pos += keyLen;

                header.Keys[i] = System.Text.Encoding.UTF8.GetString(tmpBuf);
            }

            //read the positions
            for (int i = 0; i < totalEntries; i++)
            {
                header.Positions[i] = System.BitConverter.ToInt32(buffer, pos);
                pos += MCSConstants.SIZE_OF_INT;
            }

            //read the lengths
            for (int i = 0; i < totalEntries; i++)
            {
                header.Lengths[i] = System.BitConverter.ToInt32(buffer, pos);
                pos += MCSConstants.SIZE_OF_INT;
            }

            /*
             * BinaryFormatter serializer = new BinaryFormatter();
             * MemoryStream stream = new MemoryStream(buffer);
             * header = (M3DResourceHeader)serializer.Deserialize(stream);
             */
        }