1 /++ 2 A module for creating chunks. You can put any data in it, and compress, 3 and extract the very chunks from files. It will be useful for storing 4 some kind of data about maps, textures or the like. 5 6 --- 7 Chunk chunk = Chunk("Simple chunk", "Hello, World! It's Chunk!"); 8 std.file.write("binary",chunk.save()); 9 --- 10 11 Authors: TodNaz 12 License: MIT 13 +/ 14 module chunkd.chunk; 15 16 import std.zlib; 17 18 private ubyte[4] toByte(T)(T value) @trusted 19 { 20 ubyte[4] ab; 21 for (int i = 0; i < 4; i++) 22 ab[3 - i] = cast(ubyte) (value >> (i * 8)); 23 24 return ab; 25 } 26 27 private T byteTo(T)(ubyte[] bytes) @trusted 28 { 29 T data = T.init; 30 foreach(i; 0 .. bytes.length) data |= cast(T) ((data << 8) + bytes[i]); 31 32 return data; 33 } 34 35 /++ 36 Chunk structure. Has a title and information. The size of the chunk, the size 37 of the name, then the name itself and the data are written to the file, and 38 so on in order. 39 +/ 40 struct Chunk 41 { 42 public 43 { 44 string name; /// Chunk name 45 ubyte[] data; /// Chunk data 46 } 47 48 /++ 49 Creates a chunk. 50 51 Params: 52 name = Chunk name. 53 data = Chunk data. 54 +/ 55 this(string name,ubyte[] data) @safe 56 { 57 this.name = name; 58 this.data = data; 59 } 60 61 /// ditto 62 this(string name,string data) @trusted 63 { 64 this.name = name; 65 this.data = cast(ubyte[]) data; 66 } 67 68 /// 69 public string toString() @trusted 70 { 71 return "Chunk(\""~name~"\",\""~(cast(string) data)~"\")"; 72 } 73 74 /++ 75 Compresses data. They are extremely effective only in large quantities. 76 +/ 77 public Chunk compress() @trusted 78 { 79 data = std.zlib.compress(cast(void[]) data); 80 81 return this; 82 } 83 84 /++ 85 Decompress data if it has been compressed. 86 +/ 87 public Chunk uncompress() @trusted 88 { 89 data = cast(ubyte[]) std.zlib.uncompress(cast(void[]) data, 0u, HeaderFormat.deflate); 90 91 return this; 92 } 93 94 /++ 95 Gives the size of the data. 96 +/ 97 public size_t size() @safe 98 { 99 return data.length * ubyte.sizeof; 100 } 101 102 /++ 103 Gives exhaust in the form of bytes, where you can write to a file, 104 from where, in the future, you can parse chunks. 105 +/ 106 public ubyte[] save() @trusted 107 { 108 return size().toByte ~ (name.length * ubyte.sizeof).toByte ~ (cast(ubyte[]) name) ~ data; 109 } 110 111 /++ 112 Retrieves chunks from file data or other information storage location 113 114 Params: 115 data = Data. 116 +/ 117 public static Chunk[] parse(ubyte[] data) @trusted 118 { 119 Chunk[] chunks; 120 121 size_t i = 0; 122 size_t lenName; 123 size_t lenData; 124 string _name; 125 ubyte[] _data; 126 127 while(i < data.length) { 128 lenData = byteTo!size_t(data[i .. i + 4]) / ubyte.sizeof; 129 lenName = byteTo!size_t(data[i + 4 .. i + 8]) / ubyte.sizeof; 130 131 _name = cast(string) data[i + 8 .. i + 8 + lenName]; 132 _data = data[i + 8 + lenName .. i + 8 + lenName + lenData]; 133 134 chunks ~= Chunk(_name,_data); 135 136 i = i + 8 + lenName + lenData; 137 } 138 139 return chunks; 140 } 141 } 142 143 @("Chunk test") @safe 144 unittest 145 { 146 Chunk chunk = Chunk("Simple", "Hello, World!"); 147 148 ubyte[] data = chunk.save(); 149 150 assert(Chunk.parse(data)[0] == chunk); 151 } 152 153 @("Chunk compress") @safe 154 unittest 155 { 156 Chunk chunk = Chunk("Test"," 157 MIT License 158 159 Permission is hereby granted, free of charge, to any person obtaining a copy of 160 this software and associated documentation files (the \"Software\"), to deal in the 161 Software without restriction, including without limitation the rights to use, copy, 162 modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 163 and to permit persons to whom the Software is furnished to do so, subject to the 164 following conditions: 165 166 The above copyright notice and this permission notice shall be included in all copies 167 or substantial portions of the Software. 168 169 THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 170 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 171 PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 172 FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 173 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 174 OTHER DEALINGS IN THE SOFTWARE. 175 176 ..."); 177 178 chunk.compress(); 179 180 ubyte[] data = chunk.save(); 181 182 chunk.uncompress(); 183 184 assert(Chunk.parse(data)[0].uncompress() == chunk); 185 }