1 module zthor.types;
2 
3 import zthor.constants;
4 
5 /// Holds information that is present in all THOR files.
6 struct THORHeader
7 {
8     /// "ASSF (C) 2007 Aeomin DEV"
9     ubyte[24] signature;
10 
11     /**
12      * Version, will always be 0x01 because the THOR format
13      * doesn't actually store any versioning
14      */
15     uint ver;
16 
17     /**
18      * Defines where the files from the THOR container should
19      * be saved to/merged with.
20      */
21     MergeMode mergeMode;
22 
23     /// The number of files in the THOR container.
24     uint filecount;
25 
26     /**
27      * Defines the way files are stored inside the THOR container.
28      * Important: This also defines the header size!
29      */
30     ContainerMode containerMode;
31 
32     /**
33      * Contains the name of the grf file to write to/merge with
34      * if the mergeMode is `MergeMode.grf`
35     */
36     string grfTargetName;
37 
38     /**
39      * The offset of the filetable. Value is 0 if `containerMode`
40      * is `ContainerMode.single`.
41      */
42     int filetableOffset;
43 
44     /**
45      * The compressed size of the filetable. Value is 0 if `containerMode`
46      * is `ContainerMode.single`.
47      */
48     int filetableCompressedSize;
49 }
50 
51 /// Holds information about a single file inside a THOR container
52 struct THORFile
53 {
54     /// Compressed filesize using zlib
55     uint compressed_size;
56 
57     /// Uncompressed size
58     uint size;
59 
60     /// Absolute offset of the file
61     uint offset;
62 
63     /// Hash of the filename
64     uint hash;
65 
66     /// File specific flags
67     FileFlags flags;
68 
69     /// Filename
70     wstring name;
71 
72     /// The raw filename as it is stored inside the file
73     ubyte[] rawName;
74 
75     /// Data content
76     ubyte[] data;
77 
78     /// The THOR container this file is saved in
79     THOR* thor;
80 }
81 
82 /// Hashmap of files inside a THOR container
83 alias THORFiletable = THORFile[uint];
84 
85 /**
86  * Holds information about a THOR file.
87  *
88  *  Examples:
89  * ------
90  * import zthor.types;
91  *
92  * THOR thor = THOR("my-patch.thor");
93  * ------
94  */
95 struct THOR
96 {
97     import std.stdio : File;
98 
99     /// Filehandle that is used to read any data from
100     File filehandle;
101 
102     /// Filename of the THOR file
103     string filename;
104 
105     /// Filesize of the THOR file
106     size_t filesize;
107 
108     /// THOR header. Will be filled once [zthor.thor.readHeader] is called.
109     THORHeader header;
110 
111     /// Associative array of the files.
112     /// Will be filled once [zthor.thor.readFiletable] is called.
113     THORFiletable files;
114 
115     /**
116      * Opens the filehandle and stores the filesize
117      *
118      * Params:
119      *  name = Filename of the THOR file
120      *
121      * Throws:
122      *   Exception if name is null or ErrnoException in case of
123      *   file operation failure.
124      */
125     this(string name)
126     {
127         filename = name;
128         filehandle = File(filename, "rb");
129         import core.stdc.stdio : SEEK_SET, SEEK_END;
130 
131         filehandle.seek(0, SEEK_END);
132         filesize = filehandle.tell();
133         filehandle.seek(0, SEEK_SET);
134     }
135 }
136