fix: update NlpCodec
This commit is contained in:
		| @ -13,6 +13,8 @@ | ||||
|  | ||||
| namespace NlpCodec { | ||||
|  | ||||
| #pragma region Help Structs and Functions | ||||
|  | ||||
|     /// @brief NlpCodec universal exception. | ||||
|     /// @details Once this exception was thrown, it means that somethings went wrong. | ||||
|     /// and main function should catch it, output error message and exit program immediately. | ||||
| @ -32,12 +34,29 @@ namespace NlpCodec { | ||||
|     static constexpr _TyTo SafeCast(_TyFrom value) { | ||||
|         if (!std::in_range<_TyTo>(value)) | ||||
|             throw NlpException( | ||||
|                     "Fail to cast integral number because given value is greater than container. " | ||||
|                     "Fail to cast integral number because given value is greater than the type can hold. " | ||||
|                     "This is usually caused by your input or output file is too long."); | ||||
|         return static_cast<_TyTo>(value); | ||||
|     } | ||||
|  | ||||
| #pragma region "Encryption Stuff" { | ||||
|     /// @brief The safe version of `std::ifstream::read`. | ||||
|     /// Throw exception if fail to read. | ||||
|     static void SafeRead(std::ifstream& fin, char* s, std::streamsize count) { | ||||
|         fin.read(s, count); | ||||
|         if (!fin.good() || fin.gcount() != count) | ||||
|             throw NlpException("Fail to read data from file."); | ||||
|     } | ||||
|     /// @brief The safe version of `std::ofstream::write`. | ||||
|     /// Throw exception if fail to write. | ||||
|     static void SafeWrite(std::ofstream& fout, const char* s, std::streamsize count) { | ||||
|         fout.write(s, count); | ||||
|         if (!fout.good()) | ||||
|             throw NlpException("Fail to write data into file."); | ||||
|     } | ||||
|  | ||||
| #pragma endregion | ||||
|  | ||||
| #pragma region Encryption Stuff | ||||
|  | ||||
|     /* | ||||
|  | ||||
| @ -155,7 +174,7 @@ namespace NlpCodec { | ||||
|         } | ||||
|     } | ||||
|  | ||||
| #pragma endregion } | ||||
| #pragma endregion | ||||
|  | ||||
|     /// @brief Get the length of given file stream. | ||||
|     static uint32_t GetFileLength(std::ifstream& fin) { | ||||
| @ -195,9 +214,7 @@ namespace NlpCodec { | ||||
|             throw NlpException("Fail to allocate memory."); | ||||
|  | ||||
|         // Read data from file to input buffer | ||||
|         fin.read(inbuf.get(), raw_size); | ||||
|         if (!fin.good() || fin.gcount() != raw_size) | ||||
|             throw NlpException("Fail to read file data into buffer."); | ||||
|         SafeRead(fin, inbuf.get(), raw_size); | ||||
|  | ||||
|         // Do XOR operation | ||||
|         CircularXorOperation(inbuf.get(), raw_size); | ||||
| @ -209,9 +226,9 @@ namespace NlpCodec { | ||||
|             reinterpret_cast<Bytef*>(inbuf.get()), static_cast<uLong>(raw_size), | ||||
|             Z_BEST_COMPRESSION | ||||
|         ); | ||||
|         // Check ZLib result. | ||||
|         // Check zlib result. | ||||
|         if (ret != Z_OK) | ||||
|             throw NlpException("Zlib compress() failed."); | ||||
|             throw NlpException("zlib compress() failed."); | ||||
|         // Fetch final compressed size. | ||||
|         uint32_t compressed_size = SafeCast<uint32_t>(dest_len); | ||||
|  | ||||
| @ -219,21 +236,15 @@ namespace NlpCodec { | ||||
|         uint32_t checksum = static_cast<uint32_t>(adler32(0u, reinterpret_cast<Bytef*>(outbuf.get()), SafeCast<uInt>(compressed_size))); | ||||
|  | ||||
|         // Write compressed data into file | ||||
|         fout.write(outbuf.get(), compressed_size); | ||||
|         if (!fout.good()) | ||||
|             throw NlpException("Fail to write data into file."); | ||||
|         SafeWrite(fout, outbuf.get(), compressed_size); | ||||
|  | ||||
|         // Raw size and checksum need some extra encryption before writting | ||||
|         raw_size = EncryptRawFileLength(raw_size); | ||||
|         checksum = EncryptChecksum(checksum); | ||||
|  | ||||
|         // Write raw size and checksum | ||||
|         fout.write(reinterpret_cast<char*>(&raw_size), sizeof(uint32_t)); | ||||
|         if (!fout.good()) | ||||
|             throw NlpException("Fail to write raw size into file."); | ||||
|         fout.write(reinterpret_cast<char*>(&checksum), sizeof(uint32_t)); | ||||
|         if (!fout.good()) | ||||
|             throw NlpException("Fail to write checksum into file."); | ||||
|         SafeWrite(fout, reinterpret_cast<char*>(&raw_size), sizeof(uint32_t)); | ||||
|         SafeWrite(fout, reinterpret_cast<char*>(&checksum), sizeof(uint32_t)); | ||||
|  | ||||
|     } | ||||
|  | ||||
| @ -247,8 +258,8 @@ namespace NlpCodec { | ||||
|         compressed_size -= TAIL_SIZE; | ||||
|         fin.seekg(compressed_size, std::ios_base::beg); | ||||
|         uint32_t expected_raw_size = 0u, expected_checksum = 0u; | ||||
|         fin.read(reinterpret_cast<char*>(&expected_raw_size), sizeof(uint32_t)); | ||||
|         fin.read(reinterpret_cast<char*>(&expected_checksum), sizeof(uint32_t)); | ||||
|         SafeRead(fin, reinterpret_cast<char*>(&expected_raw_size), sizeof(uint32_t)); | ||||
|         SafeRead(fin, reinterpret_cast<char*>(&expected_checksum), sizeof(uint32_t)); | ||||
|         fin.seekg(0, std::ios_base::beg); | ||||
|  | ||||
|         // Raw size and checksum data need to do some extra decryption. | ||||
| @ -262,9 +273,7 @@ namespace NlpCodec { | ||||
|             throw NlpException("Fail to allocate memory."); | ||||
|  | ||||
|         // Read file into buffer | ||||
|         fin.read(inbuf.get(), compressed_size); | ||||
|         if (!fin.good() || fin.gcount() != compressed_size) | ||||
|             throw NlpException("Fail to read data into buffer.\n"); | ||||
|         SafeRead(fin, inbuf.get(), compressed_size); | ||||
|  | ||||
|         // Test checksum | ||||
|         uint32_t checksum = static_cast<uint32_t>(adler32(0u, reinterpret_cast<Bytef*>(inbuf.get()), SafeCast<uInt>(compressed_size))); | ||||
| @ -281,15 +290,13 @@ namespace NlpCodec { | ||||
|         ); | ||||
|         // Check zlib result | ||||
|         if (ret != Z_OK) | ||||
|             throw NlpException("Zlib uncompress() failed."); | ||||
|             throw NlpException("zlib uncompress() failed."); | ||||
|  | ||||
|         // do xor operation | ||||
|         // Do XOR operation | ||||
|         CircularXorOperation(outbuf.get(), expected_raw_size); | ||||
|  | ||||
|         // Write result into file | ||||
|         fout.write(outbuf.get(), expected_raw_size); | ||||
|         if (!fout.good()) | ||||
|             throw NlpException("Fail to write data into file."); | ||||
|         SafeWrite(fout, outbuf.get(), expected_raw_size); | ||||
|  | ||||
|     } | ||||
|  | ||||
| @ -321,11 +328,11 @@ namespace NlpCodec::Runtime { | ||||
|                 << "encode  - encode text file into NLP file." << std::endl | ||||
|                 << "decode  - decode NLP file into text file." << std::endl | ||||
|                 << "<src>   - the source file." << std::endl | ||||
|                 << "        the path to text file in encode mode." << std::endl | ||||
|                 << "        the path to NLP file in decode mode." << std::endl | ||||
|                 << "          encode mode: the path to text file." << std::endl | ||||
|                 << "          decode mode: the path to NLP file." << std::endl | ||||
|                 << "<dest>  - the destination file." << std::endl | ||||
|                 << "         the path to NLP file in encode mode." << std::endl | ||||
|                 << "         the path to text file in decode mode." << std::endl | ||||
|                 << "          encode mode: the path to NLP file." << std::endl | ||||
|                 << "          decode mode: the path to text file." << std::endl | ||||
|                 << "" << std::endl; | ||||
|     } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user