📄 jma.cpp
字号:
unsigned char int4_buffer[UINT_SIZE]; size_t size = get_total_size(files); //For each chunk in the file... for (size_t remaining_size = size; remaining_size; remaining_size -= chunk_size) { //Read the compressed size stream.read((char *)int4_buffer, UINT_SIZE); size_t compressed_size = charp_to_uint(int4_buffer); //Allocate memory of the correct size to hold the compressed data in the JMA //Throw error on failure as that is unrecoverable from try { compressed_buffer = new unsigned char[compressed_size]; } catch (bad_alloc xa) { throw(JMA_NO_MEM_ALLOC); } //Read all the compressed data in stream.read((char *)compressed_buffer, compressed_size); //Read the expected CRC of compressed data from the file stream.read((char *)int4_buffer, UINT_SIZE); //If it doesn't match, throw error and cleanup memory if (CRC32lib::CRC32(compressed_buffer, compressed_size) != charp_to_uint(int4_buffer)) { delete[] compressed_buffer; throw(JMA_BAD_FILE); } //Decompress the data, cleanup memory on failure if (!decompress_lzma_7z(compressed_buffer, compressed_size, decompressed_buffer+size-remaining_size, (remaining_size > chunk_size) ? chunk_size : remaining_size)) { delete[] compressed_buffer; throw(JMA_DECOMPRESS_FAILED); } delete[] compressed_buffer; if (remaining_size <= chunk_size) //If we just decompressed the remainder { break; } } } else //Solidly compressed JMA { unsigned char int4_buffer[UINT_SIZE]; //Read the size of the compressed data stream.read((char *)int4_buffer, UINT_SIZE); size_t compressed_size = charp_to_uint(int4_buffer); //Get decompressed size size_t size = get_total_size(files); //Setup access methods for decompression ISequentialInStream_Istream compressed_data(stream); ISequentialOutStream_Array decompressed_data(reinterpret_cast<char*>(decompressed_buffer), size); //Decompress the data if (!decompress_lzma_7z(compressed_data, compressed_size, decompressed_data, size)) { throw(JMA_DECOMPRESS_FAILED); } /* //Allocate memory of the right size to hold the compressed data in the JMA try { compressed_buffer = new unsigned char[compressed_size]; } catch (bad_alloc xa) { throw(JMA_NO_MEM_ALLOC); } //Copy the compressed data into memory stream.read((char *)compressed_buffer, compressed_size); size_t size = get_total_size(files); //Read the CRC of the compressed data stream.read((char *)int4_buffer, UINT_SIZE); //If it doesn't match, complain if (CRC32lib::CRC32(compressed_buffer, compressed_size) != charp_to_uint(int4_buffer)) { delete[] compressed_buffer; throw(JMA_BAD_FILE); } //Decompress the data if (!decompress_lzma_7z(compressed_buffer, compressed_size, decompressed_buffer, size)) { delete[] compressed_buffer; throw(JMA_DECOMPRESS_FAILED); } delete[] compressed_buffer; */ } vector<unsigned char *> file_pointers; size_t size = 0; //For each file, add it's pointer to the vector, size is pointer offset in the buffer for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++) { i->buffer = decompressed_buffer+size; file_pointers.push_back(decompressed_buffer+size); size += i->size; } //Return the vector of pointers return(file_pointers); } //Extracts the file with a given name found in the archive to the given buffer void jma_open::extract_file(string& name, unsigned char *buffer) throw(jma_errors) { if (!stream.is_open()) { throw(JMA_NO_OPEN); } size_t size_to_skip = 0; size_t our_file_size = 0; //Search through the vector of file information for (vector<jma_file_info>::iterator i = files.begin(); i != files.end(); i++) { if (i->name == name) { //Set the variable so we can tell we found it our_file_size = i->size; break; } //Keep a running total of size size_to_skip += i->size; } if (!our_file_size) //File with the specified name was not found in the archive { throw(JMA_FILE_NOT_FOUND); } //If the JMA only contains one file, we can skip a lot of overhead if (files.size() == 1) { get_all_files(buffer); return; } if (chunk_size) //we are using non-solid archive.. { unsigned int chunks_to_skip = size_to_skip / chunk_size; //skip over requisite number of chunks chunk_seek(chunks_to_skip); //Allocate memory for compressed and decompressed data unsigned char *comp_buffer = 0, *decomp_buffer = 0; try { //Compressed data size is <= non compressed size unsigned char *combined_buffer = new unsigned char[chunk_size*2]; comp_buffer = combined_buffer; decomp_buffer = combined_buffer+chunk_size; } catch (bad_alloc xa) { throw(JMA_NO_MEM_ALLOC); } size_t first_chunk_offset = size_to_skip % chunk_size; unsigned char int4_buffer[UINT_SIZE]; for (size_t i = 0; i < our_file_size;) { //Get size stream.read((char *)int4_buffer, UINT_SIZE); size_t compressed_size = charp_to_uint(int4_buffer); //Read all the compressed data in stream.read((char *)comp_buffer, compressed_size); //Read the CRC of the compressed data stream.read((char *)int4_buffer, UINT_SIZE); //If it doesn't match, complain if (CRC32lib::CRC32(comp_buffer, compressed_size) != charp_to_uint(int4_buffer)) { delete[] comp_buffer; throw(JMA_BAD_FILE); } //Decompress chunk if (!decompress_lzma_7z(comp_buffer, compressed_size, decomp_buffer, chunk_size)) { delete[] comp_buffer; throw(JMA_DECOMPRESS_FAILED); } size_t copy_amount = our_file_size-i > chunk_size-first_chunk_offset ? chunk_size-first_chunk_offset : our_file_size-i; memcpy(buffer+i, decomp_buffer+first_chunk_offset, copy_amount); first_chunk_offset = 0; //Set to zero since this is only for the first iteration i += copy_amount; } delete[] comp_buffer; } else //Solid JMA { unsigned char *decomp_buffer = 0; try { decomp_buffer = new unsigned char[get_total_size(files)]; } catch (bad_alloc xa) { throw(JMA_NO_MEM_ALLOC); } get_all_files(decomp_buffer); memcpy(buffer, decomp_buffer+size_to_skip, our_file_size); delete[] decomp_buffer; } } bool jma_open::is_solid() { return(chunk_size ? false : true); } const char *jma_error_text(jma_errors error) { switch (error) { case JMA_NO_CREATE: return("JMA could not be created"); case JMA_NO_MEM_ALLOC: return("Memory for JMA could be allocated"); case JMA_NO_OPEN: return("JMA could not be opened"); case JMA_BAD_FILE: return("Invalid/Corrupt JMA"); case JMA_UNSUPPORTED_VERSION: return("JMA version not supported"); case JMA_COMPRESS_FAILED: return("JMA compression failed"); case JMA_DECOMPRESS_FAILED: return("JMA decompression failed"); case JMA_FILE_NOT_FOUND: return("File not found in JMA"); } return("Unknown error"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -