⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jma.cpp

📁 linux下的任天堂模拟器代码。供大家参考。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      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 + -