コード例 #1
0
        /// <summary>
        /// Pack all files in folder to a CAMFile Object
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static CAMFile Pack(string source)
        {
            var camFile     = new CAMFile();
            var extSections = Directory.GetFiles(source).GroupBy(p => Path.GetExtension(p)).Reverse().ToArray();
            var sections    = new CAMSection[extSections.Length];

            var totalFileCount = 0;
            var fileShift      = 0;

            for (int i = 0; i < extSections.Length; ++i)
            {
                var ext     = extSections[i];
                var section = new CAMSection();
                var list    = ext.ToArray();
                section.IndexOffset = 12 + 4 + 4 + extSections.Length * 8 + i * 8 + fileShift * (20 + 4 + 4);
                section.Extension   = ext.Key.TrimStart('.');
                section.FilesData   = new CAMData[list.Length];
                for (int j = 0; j < section.FilesData.Length; ++j)
                {
                    var fs   = new FileStream(list[j], FileMode.Open);
                    var data = new CAMData();
                    data.FileName = Path.GetFileNameWithoutExtension(list[j]);
                    data.Size     = (int)fs.Length;
                    data.Data     = new byte[fs.Length];
                    fs.Read(data.Data, 0, data.Size);
                    section.FilesData[j] = data;
                    ++totalFileCount;
                }
                sections[i] = section;
                fileShift  += totalFileCount;
            }

            camFile.Sections      = sections;
            camFile.SectionCount  = extSections.Length;
            camFile.ContentOffset = extSections.Length * 8 + totalFileCount * (20 + 4 + 4); // SectionCount * 8(FileCount) + TotalFileCount * ( 20(text) + 4(offset) + 4(size) )

            var fileSizeShift = 0;

            foreach (var section in sections)
            {
                foreach (var fileData in section.FilesData)
                {
                    fileData.Offset = camFile.ContentOffset + fileSizeShift;
                    fileSizeShift  += fileData.Size;
                }
            }

            return(camFile);
        }
コード例 #2
0
        /// <summary>
        /// Generate CAMFile object from a cam File
        /// </summary>
        /// <param name="fs"></param>
        /// <returns></returns>
        public static CAMFile Read(Stream fs)
        {
            using var reader = new BinaryReader(fs);

            //Skip file header
            reader.BaseStream.Seek(12, SeekOrigin.Begin);
            var camFile = new CAMFile();

            camFile.SectionCount  = reader.ReadInt32(); // How many types.
            camFile.ContentOffset = reader.ReadInt32(); // First file offset = 0x12(FileHeader) + 0x04(SectionCount) + 0x04(ContentOffset) + 0x04 * SectionCount + ContentOffset
            camFile.Sections      = new CAMSection[camFile.SectionCount];

            for (int i = 0; i < camFile.Sections.Length; ++i)
            {
                var item = new CAMSection();
                var code = reader.ReadBytes(4);
                item.Extension      = Encoding.ASCII.GetString(code);
                item.IndexOffset    = reader.ReadInt32();
                camFile.Sections[i] = item;
            }

            for (int i = 0; i < camFile.Sections.Length; ++i)
            {
                var length = reader.ReadInt64(); // How many files with this Ext
                camFile.Sections[i].FilesData = new CAMData[length];
                for (int j = 0; j < length; ++j)
                {
                    var item = new CAMData();
                    var code = reader.ReadBytes(20);// voodoo
                    item.FileName = Encoding.ASCII.GetString(code);
                    item.Offset   = reader.ReadInt32();
                    item.Size     = reader.ReadInt32();

                    var current = fs.Position;// save position

                    item.Data = new byte[item.Size];
                    fs.Seek(item.Offset, SeekOrigin.Begin);
                    fs.Read(item.Data, 0, item.Size);

                    fs.Seek(current, SeekOrigin.Begin);

                    camFile.Sections[i].FilesData[j] = item;
                }
            }

            return(camFile);
        }