| 95 | } |
| 96 | |
| 97 | Result<std::vector<uint8_t>> EmbeddedScript::encode(bool includePrefix, std::string_view prefixStr) const { |
| 98 | qn::HeapByteWriter writer; |
| 99 | writer.writeBool(this->main); |
| 100 | MAP_UNWRAP(writer.writeStringU16(this->filename)); |
| 101 | MAP_UNWRAP(writer.writeStringU32(this->content)); |
| 102 | writer.writeBool(this->signature.has_value()); |
| 103 | |
| 104 | if (this->signature) { |
| 105 | writer.writeBytes(*signature); |
| 106 | } |
| 107 | |
| 108 | auto rawData = writer.written(); |
| 109 | size_t bound = qn::ZstdCompressor::compressBound(rawData.size()); |
| 110 | |
| 111 | qn::HeapByteWriter outWriter; |
| 112 | if (includePrefix) { |
| 113 | outWriter.writeBytes((uint8_t*) prefixStr.data(), prefixStr.size()); |
| 114 | outWriter.writeU8(0); |
| 115 | outWriter.writeBytes((uint8_t*) EMBEDDED_SCRIPT_MAGIC.data(), EMBEDDED_SCRIPT_MAGIC.size()); |
| 116 | } |
| 117 | |
| 118 | outWriter.writeU32(rawData.size()); // uncompressed size |
| 119 | |
| 120 | auto lastPos = outWriter.position(); |
| 121 | outWriter.writeZeroes(bound); |
| 122 | auto fullWritten = outWriter.written(); |
| 123 | |
| 124 | // rn fullWritten may or may not contain the null byte and magic, offset to get the actual compress destination |
| 125 | auto compressDest = fullWritten.subspan(lastPos); |
| 126 | |
| 127 | MAP_UNWRAP(qn::compressZstd( |
| 128 | rawData.data(), |
| 129 | rawData.size(), |
| 130 | const_cast<uint8_t*>(compressDest.data()), |
| 131 | bound, |
| 132 | 8 |
| 133 | )); |
| 134 | |
| 135 | auto outVector = std::move(outWriter).intoVector(); |
| 136 | |
| 137 | // truncate extra data |
| 138 | outVector.resize(lastPos + bound); |
| 139 | |
| 140 | return Ok(std::move(outVector)); |
| 141 | } |
| 142 | |
| 143 | } |
| 144 | |