1 /** 2 INP 1 Format Writer 3 4 Copyright: 5 Copyright © 2020-2026, Inochi2D Project 6 7 License: 8 $(LINK2 https://github.com/Inochi2D/inochi2d/blob/main/LICENSE, BSD 2-clause License) 9 10 Authors: 11 Luna Nielsen 12 */ 13 module inp.format.inp1.writer; 14 import inp.format.json.writer; 15 import inp.format.node; 16 import inp.format.inp1; 17 import nulib.io.stream; 18 import nulib.io.stream.rw; 19 import nulib.math; 20 import numem; 21 22 import inp.format : 23 INP_TAG_PAYLOAD, 24 INP_TAG_TEXTURES, 25 INP_TAG_VENDOR; 26 27 @nogc: 28 29 /** 30 Write the contents of a $(D DataNode) into the INP1 File. 31 32 Params: 33 stream = The stream to write to. 34 node = A DataNode object following the INP structure. 35 */ 36 void writeINP1(Stream stream, ref DataNode node) { 37 scope StreamWriter writer = new StreamWriter(stream); 38 39 if (INP_TAG_PAYLOAD in node) { 40 writer.writeUTF8(INP1_MAGIC); 41 42 ubyte[] payload = node[INP_TAG_PAYLOAD].makeJsonPayload(); 43 writer.writeBE!uint(cast(uint)payload.length); 44 stream.write(payload); 45 46 nu_freea(payload); 47 } 48 49 if (INP_TAG_TEXTURES in node) { 50 writer.writeUTF8(INP_TAG_TEXTURES); 51 writer.writeBE!uint(cast(uint)node[INP_TAG_TEXTURES].length); 52 foreach(ref value; node[INP_TAG_TEXTURES].array) { 53 writer.writeBE!uint(cast(uint)value["data"].blob.length); 54 writer.writeBE!ubyte(value["encoding"].tryCoerce!ubyte); 55 stream.write(value["data"].blob); 56 } 57 } 58 59 if (INP_TAG_VENDOR in node) { 60 writer.writeUTF8(INP_TAG_VENDOR); 61 writer.writeBE!uint(cast(uint)node[INP_TAG_VENDOR].length); 62 foreach(key, ref value; node[INP_TAG_VENDOR].object) { 63 writer.writeBE!uint(cast(uint)key.length); 64 writer.writeUTF8(key); 65 writer.writeBE!uint(cast(uint)value.blob.length); 66 stream.write(value.blob); 67 } 68 } 69 } 70 71 72 73 74 // 75 // IMPLEMENTATION DETAILS 76 // 77 private: 78 79 ubyte[] makeJsonPayload(ref DataNode node) { 80 scope MemoryStream stream = new MemoryStream(1); 81 stream.writeJson(node); 82 return stream.take(); 83 }