示例#1
0
MPQFile::MPQFile(const char* filename):
    eof(false),
    buffer(0),
    pointer(0),
    size(0)
{
    for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
    {
        mpq_archive *mpq_a = (*i)->mpq_a;

        uint32 filenum;
        if (libmpq__file_number(mpq_a, filename, &filenum)) continue;
        libmpq__off_t transferred;
        libmpq__file_unpacked_size(mpq_a, filenum, &size);

        // HACK: in patch.mpq some files don't want to open and give 1 for filesize
        if (size<=1) {
            // printf("info: file %s has size %d; considered dummy file.\n", filename, size);
            eof = true;
            buffer = 0;
            return;
        }
        buffer = new char[size];

        //libmpq_file_getdata
        libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
        /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
        return;
    }
    eof = true;
    buffer = 0;
}
示例#2
0
FILE* MPQManager::GetFileFrom( std::string path, MPQArchive* file )
{
    ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL);
    mpq_archive* mpq_a = file->mpq_a;

    uint32_t filenum;
    if(libmpq__file_number(mpq_a, path.c_str(), &filenum))
        return NULL;

    libmpq__off_t transferred;
    libmpq__off_t size = 0;
    libmpq__file_unpacked_size(mpq_a, filenum, &size);

    // HACK: in patch.mpq some files don't want to open and give 1 for filesize
    if (size <= 1)
        return NULL;

    uint8* buffer = new uint8[size];

    //libmpq_file_getdata
    libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);

    // Pack the return into a FILE stream
    FILE* ret = tmpfile();
    fwrite(buffer, sizeof(uint8), size, ret);
    return ret;
}
示例#3
0
FILE* MPQManager::GetFileFrom(const std::string& path, MPQArchive* file )
{
    ACE_GUARD_RETURN(ACE_Thread_Mutex, g, mutex, NULL);
    mpq_archive* mpq_a = file->mpq_a;

    uint32_t filenum;
    if(libmpq__file_number(mpq_a, path.c_str(), &filenum))
        return NULL;

    libmpq__off_t transferred;
    libmpq__off_t size = 0;
    libmpq__file_unpacked_size(mpq_a, filenum, &size);

    // HACK: in patch.mpq some files don't want to open and give 1 for filesize
    if (size <= 1)
        return NULL;

    uint8* buffer = new uint8[size];

    //libmpq_file_getdata
    libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);

    // Pack the return into a FILE stream
    FILE* ret = tmpfile();
    if (!ret)
    {
        printf("Could not create temporary file. Please run as Administrator or root\n");
        exit(1);
    }
    fwrite(buffer, sizeof(uint8), size, ret);
    fseek(ret, 0, SEEK_SET);
    delete[] buffer;
    return ret;
}
示例#4
0
MPQFile::MPQFile(const char* filename):
    eof(false),
    buffer(0),
    pointer(0),
    size(0)
{
    for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
    {
        mpq_archive *mpq_a = (*i)->mpq_a;

        uint32 filenum;
        if(libmpq__file_number(mpq_a, filename, &filenum)) continue;
        libmpq__off_t transferred;
        libmpq__file_unpacked_size(mpq_a, filenum, &size);

        // file should not be loaded
        if (size<=1) {
            eof = true;
            buffer = 0;
            return;
        }
        
        buffer = new char[size];

        //libmpq_file_getdata
        libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
        /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
        return;
    }
    eof = true;
    buffer = 0;
}
示例#5
0
//------------------------------------------------------------------------------
bool MpqHandler::getFile( const std::string &filename, BufferS_t *buffer ) const {
  libmpq__off_t unpacked = 0;
  libmpq__off_t bytes = 0;
  uint32_t file_num = 0;
  int32_t err = 0;

  // convert filename to lower case string
  std::string fn_lc( filename );
  std::transform( fn_lc.begin(), fn_lc.end(), fn_lc.begin(), ::tolower );

  // search for filename in our map
  MpqArchiveMap_t::const_iterator f = _mpqArchiveMap.find( fn_lc );
  if ( f != _mpqArchiveMap.end() ) {
    mpq_archive_s *mpq_arc = f->second;
    // get file number from mpq archive
    err = libmpq__file_number( mpq_arc, filename.c_str(), &file_num );
    err = libmpq__file_unpacked_size( mpq_arc, file_num, &unpacked );

    // resize buffer and load file into that buffer
    buffer->resize( unpacked );
    uint8_t *buf_p = (uint8_t*)&(*buffer)[0];
    err = libmpq__file_read( mpq_arc, file_num, buf_p, unpacked, &bytes );
  }

  return bytes > 0;
}
示例#6
0
//------------------------------------------------------------------------------
libmpq__off_t MpqHandler::getListFile( const std::string &filename,
                                       mpq_archive_s **mpq_arc,
                                       uint8_t **buffer ) const {
  int32_t err = 0;
  std::string mpq_file = _dataDirectory + std::string( "/" ) + filename;

  try {
    // open mpq archive
    err = libmpq__archive_open( mpq_arc, mpq_file.c_str(), -1 );
    if ( err != LIBMPQ_SUCCESS ) {
      throw( std::string( "libmpq__archive_open failed" ) );
    }

    // get file number of the list file which contains all names in the archive
    uint32_t file_num = 0;
    err = libmpq__file_number( *mpq_arc, LIBMPQ_LISTFILE_NAME, &file_num );
    if ( err != LIBMPQ_SUCCESS ) {
      throw( std::string( "libmpq__file_number failed" ) );
    }

    // read file from archive...get file size and reserve space
    libmpq__off_t file_size;
    err = libmpq__file_unpacked_size( *mpq_arc, file_num, &file_size );
    if ( err != LIBMPQ_SUCCESS ) {
      throw( std::string( "libmpq__file_unpacked_size failed" ) );
    }

    // read file from archive to buffer
    *buffer = new uint8_t[file_size];
    err = libmpq__file_read( *mpq_arc, file_num, *buffer, file_size, NULL );
    if ( err != LIBMPQ_SUCCESS ) {
      throw( std::string( "libmpq__file_read failed" ) );
    }

    return file_size;
  } catch( std::string err_msg ) {
    // if an archive has been opened close it
    if ( *mpq_arc ) {
      libmpq__archive_close( *mpq_arc );
    }

    delete [] *buffer;

    // quit application
    std::stringstream ss;
    ss << "Cannot open " << mpq_file << " " << err_msg;
    quitApp( ss.str() );
  }

  return -1;
}
示例#7
0
MPQFile* MPQArchiveImpl::getFile( const MPQArchive* self, const std::string& filename ) const
{
  uint32_t number = 0;
  ::off_t size = 0, actualsize = 0;
  uint8_t* buffer = 0;
  
  libmpq__file_number( archive_, filename.c_str(), &number );
  libmpq__file_unpacked_size( archive_, number, &size );
  
  buffer = new uint8_t[size];
  
  libmpq__file_read( archive_, number, buffer, size, &actualsize );
  
  return new MPQFile( filename, buffer, actualsize );
}
示例#8
0
文件: mpq.c 项目: Declipe/AscEmu
/* this function read the given file from archive into a buffer. */
int32_t libmpq__file_read(mpq_archive_s *mpq_archive, uint32_t file_number, uint8_t *out_buf, libmpq__off_t out_size, libmpq__off_t *transferred) {

	/* some common variables. */
	uint32_t i;
	uint32_t blocks         = 0;
	int32_t result          = 0;
	libmpq__off_t file_offset       = 0;
	libmpq__off_t unpacked_size     = 0;
	libmpq__off_t transferred_block = 0;
	libmpq__off_t transferred_total = 0;

	/* check if given file number is not out of range. */
	if (file_number < 0 || file_number > mpq_archive->files - 1) {

		/* file number is out of range. */
		return LIBMPQ_ERROR_EXIST;
	}

	/* get target size of block. */
	libmpq__file_unpacked_size(mpq_archive, file_number, &unpacked_size);

	/* check if target buffer is to small. */
	if (unpacked_size > out_size) {

		/* output buffer size is to small or block size is unknown. */
		return LIBMPQ_ERROR_SIZE;
	}

	/* fetch file offset. */
	libmpq__file_offset(mpq_archive, file_number, &file_offset);

	/* get block count for file. */
	libmpq__file_blocks(mpq_archive, file_number, &blocks);

	/* open the packed block offset table. */
	if ((result = libmpq__block_open_offset(mpq_archive, file_number)) < 0) {

		/* something on opening packed block offset table failed. */
		return result;
	}

	/* loop through all blocks. */
	for (i = 0; i < blocks; i++) {

		/* cleanup size variable. */
		unpacked_size = 0;

		/* get unpacked block size. */
		libmpq__block_unpacked_size(mpq_archive, file_number, i, &unpacked_size);

		/* read block. */
		if ((result = libmpq__block_read(mpq_archive, file_number, i, out_buf + transferred_total, unpacked_size, &transferred_block)) < 0) {

			/* close the packed block offset table. */
			libmpq__block_close_offset(mpq_archive, file_number);

			/* something on reading block failed. */
			return result;
		}

		transferred_total += transferred_block;

	}

	/* close the packed block offset table. */
	libmpq__block_close_offset(mpq_archive, file_number);

	/* check for null pointer. */
	if (transferred != NULL) {

		/* store transferred bytes. */
		*transferred = transferred_total;
	}

	/* if no error was found, return zero. */
	return LIBMPQ_SUCCESS;
}