1 Star 3 Fork 2

只要998/Onscripter-Official

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
NsaReader.cpp 7.65 KB
一键复制 编辑 原始数据 按行查看 历史
只要998 提交于 2020-04-20 20:31 . no commit message
/* -*- C++ -*-
*
* NsaReader.cpp - Reader from a NSA archive
*
* Copyright (c) 2001-2019 Ogapee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "NsaReader.h"
#include <string.h>
NsaReader::NsaReader( unsigned int nsa_offset, char *path, int archive_type, const unsigned char *key_table )
:SarReader( path, key_table )
{
sar_flag = true;
this->nsa_offset = nsa_offset;
this->archive_type = archive_type;
num_of_nsa_archives[0] = 0;
num_of_nsa_archives[1] = 0;
num_of_ns2_archives = 0;
if (key_table)
nsa_archive_ext = "___";
else
nsa_archive_ext = "nsa";
ns2_archive_ext = "ns2";
}
NsaReader::~NsaReader()
{
}
int NsaReader::open( const char *nsa_path )
{
bool archive_found = false;
char archive_name[256];
if (!SarReader::open("arc.sar")) return 0;
sar_flag = false;
if (archive_type & ARCHIVE_TYPE_NS2){
for (int i=0; i<MAX_NS2_ARCHIVE; i++){
sprintf(archive_name, "%s%02d.%s", nsa_path?nsa_path:"", i, ns2_archive_ext);
if ((archive_info_ns2[i].file_handle = fopen(archive_name, "rb")) == NULL) break;
ArchiveInfo *ai = &archive_info_ns2[i];
archive_found = true;
ai->file_name = new char[strlen(archive_name)+1];
memcpy(ai->file_name, archive_name, strlen(archive_name)+1);
readArchive(ai, ARCHIVE_TYPE_NS2, nsa_offset);
num_of_ns2_archives = i+1;
}
}
if (num_of_ns2_archives ==0 && archive_type & ARCHIVE_TYPE_NSA){
for (int k=0; k<2; k++){
for (int i=-1; i<MAX_EXTRA_ARCHIVE; i++){
ArchiveInfo *ai;
if (i == -1){
sprintf(archive_name, "%s%sarc.%s", nsa_path?nsa_path:"", k==0?"patch/":"", nsa_archive_ext);
ai = k==0?(&archive_info_patch):(&archive_info);
}
else{
sprintf(archive_name, "%s%sarc%d.%s", nsa_path?nsa_path:"", k==0?"patch/":"", i+1, nsa_archive_ext);
ai = &archive_info2[k][i];
}
if ((ai->file_handle = fopen(archive_name, "rb")) == NULL) break;
archive_found = true;
ai->file_name = new char[strlen(archive_name)+1];
memcpy(ai->file_name, archive_name, strlen(archive_name)+1);
readArchive(ai, ARCHIVE_TYPE_NSA, nsa_offset);
num_of_nsa_archives[k] = i+1;
}
}
}
if (!archive_found) return -1;
return 0;
}
int NsaReader::openForConvert( char *nsa_name, int archive_type, unsigned int nsa_offset )
{
sar_flag = false;
if ( ( archive_info.file_handle = ::fopen( nsa_name, "rb" ) ) == NULL ){
fprintf( stderr, "can't open file %s\n", nsa_name );
return -1;
}
readArchive( &archive_info, archive_type, nsa_offset );
return 0;
}
int NsaReader::writeHeader( FILE *fp, int archive_type, int nsa_offset )
{
ArchiveInfo *ai = &archive_info;
return writeHeaderSub( ai, fp, archive_type, nsa_offset );
}
size_t NsaReader::putFile( FILE *fp, int no, size_t offset, size_t length, size_t original_length, int compression_type, bool modified_flag, unsigned char *buffer )
{
ArchiveInfo *ai = &archive_info;
return putFileSub( ai, fp, no, offset, length, original_length , compression_type, modified_flag, buffer );
}
const char *NsaReader::getArchiveName() const
{
return "nsa";
}
int NsaReader::getNumFiles()
{
int total = 0;
ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info};
for (int k=0; k<2; k++){
total += ai[k]->num_of_files;
for (int i=0; i<num_of_nsa_archives[k]; i++)
total += archive_info2[k][i].num_of_files;
}
for (int i=0; i<num_of_ns2_archives; i++)
total += archive_info_ns2[i].num_of_files;
return total;
}
size_t NsaReader::getFileLengthSub( ArchiveInfo *ai, const char *file_name )
{
unsigned int i = getIndexFromFile( ai, file_name );
if ( i == ai->num_of_files ) return 0;
if ( ai->fi_list[i].original_length != 0 )
return ai->fi_list[i].original_length;
int type = ai->fi_list[i].compression_type;
if ( type == NO_COMPRESSION )
type = getRegisteredCompressionType( file_name );
if ( type == NBZ_COMPRESSION || type == SPB_COMPRESSION ) {
ai->fi_list[i].original_length = getDecompressedFileLength( type, ai->file_handle, ai->fi_list[i].offset );
}
return ai->fi_list[i].original_length;
}
size_t NsaReader::getFileLength(const char *file_name)
{
if (sar_flag) return SarReader::getFileLength(file_name);
size_t ret;
if ((ret = DirectReader::getFileLength(file_name))) return ret;
for (int i=0; i<num_of_ns2_archives; i++)
if ((ret = getFileLengthSub(&archive_info_ns2[i], file_name))) return ret;
ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info};
for (int k=0; k<2; k++){
if ((ret = getFileLengthSub(ai[k], file_name))) return ret;
for (int i=0; i<num_of_nsa_archives[k]; i++)
if ((ret = getFileLengthSub(&archive_info2[k][i], file_name))) return ret;
}
return 0;
}
size_t NsaReader::getFile(const char *file_name, unsigned char *buffer, int *location)
{
size_t ret;
if (sar_flag) return SarReader::getFile( file_name, buffer, location );
if ((ret = DirectReader::getFile(file_name, buffer, location))) return ret;
for (int i=0; i<num_of_ns2_archives; i++){
if ((ret = getFileSub(&archive_info_ns2[i], file_name, buffer))){
if (location) *location = ARCHIVE_TYPE_NS2;
return ret;
}
}
ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info};
for (int k=0; k<2; k++){
if ((ret = getFileSub(ai[k], file_name, buffer))){
if (location) *location = ARCHIVE_TYPE_NSA;
return ret;
}
for (int i=0; i<num_of_nsa_archives[k]; i++){
if ((ret = getFileSub(&archive_info2[k][i], file_name, buffer))){
if (location) *location = ARCHIVE_TYPE_NSA;
return ret;
}
}
}
return 0;
}
NsaReader::FileInfo NsaReader::getFileByIndex(unsigned int index)
{
for (int i=0; i<num_of_ns2_archives; i++){
if (index < archive_info_ns2[i].num_of_files) return archive_info_ns2[i].fi_list[index];
index -= archive_info_ns2[i].num_of_files;
}
ArchiveInfo* ai[2] = {&archive_info_patch, &archive_info};
for (int k=0; k<2; k++){
if (index < ai[k]->num_of_files) return archive_info.fi_list[index];
index -= ai[k]->num_of_files;
for (int i=0; i<num_of_nsa_archives[k]; i++){
if (index < archive_info2[k][i].num_of_files) return archive_info2[k][i].fi_list[index];
index -= archive_info2[k][i].num_of_files;
}
}
fprintf( stderr, "NsaReader::getFileByIndex Index %d is out of range\n", index );
return archive_info.fi_list[0];
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/only998/Onscripter-Official.git
[email protected]:only998/Onscripter-Official.git
only998
Onscripter-Official
Onscripter-Official
master

搜索帮助