void Disposing() { if (RawData != null) { RawData.Dispose(); RawData = null; } }
public GMFileContent(byte[] data) { RawData = new UniquePtr(data); byte *hdr_b = RawData.BPtr; var basePtr = (SectionHeader *)hdr_b; Form = basePtr; if (Form->Identity != SectionHeaders.Form) { throw new InvalidDataException(ERR_NO_FORM); } SectionHeader * hdr = basePtr + 1, hdrEnd = (SectionHeader *)((IntPtr)basePtr + (int)Form->Size); int headersMet = 0; for (; hdr < hdrEnd; hdr = unchecked ((SectionHeader *)((IntPtr)hdr + (int)hdr->Size) + 1), ++headersMet) { Chunks.Add(hdr->Identity, (IntPtr)hdr); for (int i = 0; i < HeaderOffsets.Length; i++) { if (((SectionHeader *)((byte *)basePtr + HeaderOffsets[i]))->Identity == hdr->Identity) { Console.Error.WriteLine($"WARNING: chunk {hdr->MagicString()} encountered (at least) twice! Only the last occurrence will be exported! (If you see this message, consider reversing manually.)"); } } if (HeaderOffsets.Length >= headersMet) { var ho = HeaderOffsets; Array.Resize(ref ho, (headersMet == HeaderOffsets.Length) ? 1 : (headersMet + 2)); HeaderOffsets = ho; } HeaderOffsets[headersMet] = (byte *)hdr - (byte *)basePtr; } }
public static GMFile GetFile(byte[] data) { var ret = new GMFileContent(); var hdr_bp = new UniquePtr(data); byte *hdr_b = hdr_bp.BPtr; var basePtr = (SectionHeader *)hdr_b; ret.Form = basePtr; if (ret.Form->Identity != SectionHeaders.Form) { throw new InvalidDataException(ERR_NO_FORM); } SectionHeader * hdr = basePtr + 1, hdrEnd = (SectionHeader *)((IntPtr)basePtr + (int)ret.Form->Size); int headersMet = 0; while (hdr < hdrEnd) { switch (hdr->Identity) { case SectionHeaders.General: ret.General = (SectionGeneral *)hdr; break; case SectionHeaders.Options: ret.Options = (SectionOptions *)hdr; break; case SectionHeaders.Extensions: ret.Extensions = (SectionUnknown *)hdr; if (!ret.Extensions->IsEmpty()) { Console.WriteLine("Warning: EXTN chunk is not empty, its content will not be exported!"); } break; case SectionHeaders.Sounds: ret.Sounds = (SectionCountOffsets *)hdr; break; case SectionHeaders.Sprites: ret.Sprites = (SectionCountOffsets *)hdr; break; case SectionHeaders.Backgrounds: ret.Backgrounds = (SectionCountOffsets *)hdr; break; case SectionHeaders.Paths: ret.Paths = (SectionCountOffsets *)hdr; break; case SectionHeaders.Scripts: ret.Scripts = (SectionCountOffsets *)hdr; break; case SectionHeaders.Shaders: ret.Shaders = (SectionUnknown *)hdr; if (!ret.Shaders->IsEmpty()) { Console.WriteLine("Warning: SHDR chunk is not empty, its content will not be exported!"); } break; case SectionHeaders.Fonts: ret.Fonts = (SectionCountOffsets *)hdr; break; case SectionHeaders.Timelines: ret.Timelines = (SectionUnknown *)hdr; if (!ret.Timelines->IsEmpty()) { Console.WriteLine("Warning: TMLN chunk is not empty, its content will not be exported!"); } break; case SectionHeaders.Objects: ret.Objects = (SectionCountOffsets *)hdr; break; case SectionHeaders.Rooms: ret.Rooms = (SectionCountOffsets *)hdr; break; case SectionHeaders.DataFiles: ret.DataFiles = (SectionUnknown *)hdr; if (!ret.DataFiles->IsEmpty()) { Console.WriteLine("Warning: DAFL chunk is not empty, its content will not be exported!"); } break; case SectionHeaders.TexturePage: ret.TexturePages = (SectionCountOffsets *)hdr; break; case SectionHeaders.Code: ret.Code = (SectionCountOffsets *)hdr; break; case SectionHeaders.Variables: ret.Variables = (SectionRefDefs *)hdr; break; case SectionHeaders.Functions: ret.Functions = (SectionRefDefs *)hdr; break; case SectionHeaders.Strings: ret.Strings = (SectionCountOffsets *)hdr; break; case SectionHeaders.Textures: ret.Textures = (SectionCountOffsets *)hdr; break; case SectionHeaders.Audio: ret.Audio = (SectionCountOffsets *)hdr; break; case SectionHeaders.AudioGroup: ret.AudioGroup = (SectionUnknown *)hdr; if (!ret.AudioGroup->IsEmpty()) { Console.WriteLine("Warning: AGRP chunk is not empty, its content will not be exported!"); } break; case SectionHeaders.GNAL_Unk: ret.GNAL_Unk = (SectionUnknown *)hdr; if (!ret.GNAL_Unk->IsEmpty()) { Console.WriteLine("Warning: GNAL chunk is not empty, its content will not be exported!"); } break; default: var unk = (SectionUnknown *)hdr; if (!unk->IsEmpty()) { Console.WriteLine($"Warning: unknown chunk {hdr->Identity.ToChunkName()}, chunk is not empty, its content will not be exported!"); } ret.UnknownChunks.Add(hdr->Identity, (IntPtr)unk); break; } for (int i = 0; i < ret.HeaderOffsets.Length; i++) { if (((SectionHeader *)((byte *)basePtr + ret.HeaderOffsets[i]))->Identity == hdr->Identity) { Console.WriteLine($"WARNING: chunk {hdr->MagicString()} encountered (at least) twice! Only the last occurrence will be exported! (If you see this message, consider reversing manually.)"); } } if (ret.HeaderOffsets.Length >= headersMet) { var ho = ret.HeaderOffsets; Array.Resize(ref ho, (headersMet == ret.HeaderOffsets.Length) ? 1 : (headersMet + 2)); ret.HeaderOffsets = ho; } ret.HeaderOffsets[headersMet++] = (byte *)hdr - (byte *)basePtr; hdr = unchecked ((SectionHeader *)((IntPtr)hdr + (int)hdr->Size) + 1); } ret.RawData = hdr_bp; return(new GMFile(ret)); }
public static GMFile GetFile(byte[] data) { var ret = new GMFileContent(); var hdr_bp = new UniquePtr(data); byte *hdr_b = hdr_bp.BPtr; var basePtr = (SectionHeader *)hdr_b; ret.Form = basePtr; if (ret.Form->Identity != SectionHeaders.Form) { throw new InvalidDataException(ERR_NO_FORM); } SectionHeader * hdr = basePtr + 1, hdrEnd = (SectionHeader *)((IntPtr)basePtr + (int)ret.Form->Size); int headersMet = 0; while (hdr < hdrEnd) { switch (hdr->Identity) { case SectionHeaders.General: ret.General = (SectionGeneral *)hdr; break; case SectionHeaders.Options: ret.Options = (SectionOptions *)hdr; break; case SectionHeaders.Extensions: ret.Extensions = (SectionUnknown *)hdr; break; case SectionHeaders.Sounds: ret.Sounds = (SectionCountOffsets *)hdr; break; case SectionHeaders.Sprites: ret.Sprites = (SectionCountOffsets *)hdr; break; case SectionHeaders.Backgrounds: ret.Backgrounds = (SectionCountOffsets *)hdr; break; case SectionHeaders.Paths: ret.Paths = (SectionCountOffsets *)hdr; break; case SectionHeaders.Scripts: ret.Scripts = (SectionCountOffsets *)hdr; break; case SectionHeaders.Shaders: ret.Shaders = (SectionUnknown *)hdr; break; case SectionHeaders.Fonts: ret.Fonts = (SectionCountOffsets *)hdr; break; case SectionHeaders.Timelines: ret.Timelines = (SectionUnknown *)hdr; break; case SectionHeaders.Objects: ret.Objects = (SectionCountOffsets *)hdr; break; case SectionHeaders.Rooms: ret.Rooms = (SectionCountOffsets *)hdr; break; case SectionHeaders.DataFiles: ret.DataFiles = (SectionUnknown *)hdr; break; case SectionHeaders.TexturePage: ret.TexturePages = (SectionCountOffsets *)hdr; break; case SectionHeaders.Code: ret.Code = (SectionCountOffsets *)hdr; break; case SectionHeaders.Variables: ret.Variables = (SectionRefDefs *)hdr; break; case SectionHeaders.Functions: ret.Functions = (SectionRefDefs *)hdr; break; case SectionHeaders.Strings: ret.Strings = (SectionCountOffsets *)hdr; break; case SectionHeaders.Textures: ret.Textures = (SectionCountOffsets *)hdr; break; case SectionHeaders.Audio: ret.Audio = (SectionCountOffsets *)hdr; break; case SectionHeaders.AudioGroup: ret.AudioGroup = (SectionUnknown *)hdr; break; } ret.HeaderOffsets[headersMet++] = (byte *)hdr - (byte *)basePtr; hdr = unchecked ((SectionHeader *)((IntPtr)hdr + (int)hdr->Size) + 1); } ret.RawData = hdr_bp; return(new GMFile(ret)); }
public unsafe static GMFileContent GetFile(byte[] data) { var ret = new GMFileContent(); var hdr_bp = new UniquePtr(data); byte* hdr_b = hdr_bp.BPtr; var basePtr = (SectionHeader*)hdr_b; ret.Form = basePtr; if (ret.Form->Identity != SectionHeaders.Form) throw new InvalidDataException(ERR_NO_FORM); SectionHeader* hdr = basePtr + 1, hdrEnd = (SectionHeader*)((IntPtr)basePtr + (int)ret.Form->Size); int headersMet = 0; while (hdr < hdrEnd) { switch (hdr->Identity) { case SectionHeaders.General: ret.General = (SectionGeneral*)hdr; break; case SectionHeaders.Options: ret.Options = (SectionOptions*)hdr; break; case SectionHeaders.Extensions: ret.Extensions = (SectionUnknown*)hdr; break; case SectionHeaders.Sounds: ret.Sounds = (SectionCountOffsets*)hdr; break; case SectionHeaders.Sprites: ret.Sprites = (SectionCountOffsets*)hdr; break; case SectionHeaders.Backgrounds: ret.Backgrounds = (SectionCountOffsets*)hdr; break; case SectionHeaders.Paths: ret.Paths = (SectionCountOffsets*)hdr; break; case SectionHeaders.Scripts: ret.Scripts = (SectionCountOffsets*)hdr; break; case SectionHeaders.Shaders: ret.Shaders = (SectionUnknown*)hdr; break; case SectionHeaders.Fonts: ret.Fonts = (SectionCountOffsets*)hdr; break; case SectionHeaders.Timelines: ret.Timelines = (SectionUnknown*)hdr; break; case SectionHeaders.Objects: ret.Objects = (SectionCountOffsets*)hdr; break; case SectionHeaders.Rooms: ret.Rooms = (SectionCountOffsets*)hdr; break; case SectionHeaders.DataFiles: ret.DataFiles = (SectionUnknown*)hdr; break; case SectionHeaders.TexturePage: ret.TexturePages = (SectionCountOffsets*)hdr; break; case SectionHeaders.Code: ret.Code = (SectionCountOffsets*)hdr; break; case SectionHeaders.Variables: ret.Variables = (SectionRefDefs*)hdr; break; case SectionHeaders.Functions: ret.Functions = (SectionRefDefs*)hdr; break; case SectionHeaders.Strings: ret.Strings = (SectionCountOffsets*)hdr; break; case SectionHeaders.Textures: ret.Textures = (SectionCountOffsets*)hdr; break; case SectionHeaders.Audio: ret.Audio = (SectionCountOffsets*)hdr; break; case SectionHeaders.AudioGroup: ret.AudioGroup = (SectionUnknown*)hdr; break; } ret.HeaderOffsets[headersMet++] = (byte*)hdr - (byte*)basePtr; hdr = unchecked((SectionHeader*)((IntPtr)hdr + (int)hdr->Size) + 1); } ret.RawData = hdr_bp; return ret; }