NPK_PACKAGE npk_package_open( NPK_CSTR filename, NPK_TEAKEY teakey[4] ) { NPK_PACKAGEBODY* pb = NULL; NPK_RESULT res; res = npk_package_alloc( (NPK_PACKAGE*)&pb, teakey ); if( res != NPK_SUCCESS ) return NULL; if( npk_package_init( pb ) != NPK_SUCCESS ) goto npk_package_open_return_null_with_free; if( npk_open( &pb->handle_, filename, false, false ) != NPK_SUCCESS ) goto npk_package_open_return_null_with_free; res = __npk_package_open( pb, filename, 0, teakey ); if( res != NPK_SUCCESS ) goto npk_package_open_return_null_with_free; return (NPK_PACKAGE*)pb; npk_package_open_return_null_with_free: if( pb ) npk_package_close( pb ); return NULL; }
void MPackageManagerNPK::cleanup() { if(m_fileOpenHook) { if(M_getFileOpenHook() == m_fileOpenHook) M_registerFileOpenHook(0); SAFE_DELETE(m_fileOpenHook); } if(m_packages) { for(int i = 0; i < M_MAX_PACKAGES; ++i) { if(m_packages[i] != 0) { MPackageNPK* pack = (MPackageNPK*)m_packages[i]; npk_package_close(pack->package); delete pack; m_packages[i] = 0; } } SAFE_DELETE_ARRAY(m_packages); } }
NPK_PACKAGE npk_package_open_with_fd( NPK_CSTR name, int fd, long offset, long size, NPK_TEAKEY teakey[4] ) { NPK_PACKAGEBODY* pb = NULL; NPK_RESULT res; res = npk_package_alloc( (NPK_PACKAGE*)&pb, teakey ); if( res != NPK_SUCCESS ) return NULL; if( npk_package_init( pb ) != NPK_SUCCESS ) goto npk_package_open_return_null_with_free; pb->handle_ = fd; pb->usingFdopen_ = true; pb->offsetJump_ = offset; npk_seek( fd, offset, SEEK_CUR ); res = __npk_package_open( pb, name, size, teakey ); if( res != NPK_SUCCESS ) goto npk_package_open_return_null_with_free; return (NPK_PACKAGE*)pb; npk_package_open_return_null_with_free: if( pb ) npk_package_close( pb ); return NULL; }
int npk_close(lua_State* L) { npkg* pkg = _npkg::_pkgs[lua_tointeger(L, -3)]; if(!pkg) return 0; npk_package_save(pkg->pkg, pkg->path, true); npk_package_close(pkg->pkg); delete pkg; return 0; }
void MPackageManagerNPK::closePackage(MPackage package) { #ifdef M_PACKAGE_WRITABLE if(package) { if(m_writable == package) m_writable = 0; MPackageNPK* pack = (MPackageNPK*)package; npk_package_save(pack->package, pack->filename.getData(), true); npk_package_close(pack->package); delete pack; } #endif }
void MPackageManagerNPK::unloadPackage(MPackage package) { for(int i = 0; i < M_MAX_PACKAGES; ++i) { if(m_packages[i] == package) { m_packages[i] = 0; MPackageNPK* pack = (MPackageNPK*)package; npk_package_close(pack->package); delete pack; break; } } }
MPackage MPackageManagerNPK::loadPackage(const char* packageName) { MPackageNPK* pack = new MPackageNPK; if(!(pack->package = npk_package_open(packageName, teakey))) { delete pack; return 0; } pack->filename = packageName; if(!mountPackage(pack)) { npk_package_close(pack->package); delete pack; pack = 0; } return pack; }
int libnpk_read_entity_partial( int argc, char * argv [] ) { int teakey[4] = {98521,16322,7163,992}; NPK_PACKAGE pack = npk_package_open( "sample.npk", teakey ); CHECK( pack != NULL ); std::string entityNames[2] = { "sample.txt", "tea.txt" }; for( int i = 0; i < 2; ++i ) { NPK_ENTITY entity = npk_package_get_entity( pack, entityNames[i].c_str() ); CHECK( entity != NULL ); NPK_SIZE size = npk_entity_get_size( entity ); void* buf = malloc( size ); NPK_FLAG flag; npk_entity_get_current_flag( entity, &flag ); if( flag & ( NPK_ENTITY_ENCRYPT_TEA | NPK_ENTITY_ENCRYPT_XXTEA ) ) { // offset must be aligned by 8 bytes CHECK( (!npk_entity_read_partial( entity, buf, 9, 32 )) ); // Size can be not aligned by 8 bytes when read end of file NPK_SIZE offset = size - (size % 8) - 32; CHECK( npk_entity_read_partial( entity, buf, offset, size - offset ) ); CHECK_EQUAL_STR_WITH_FILE_PARTIAL( (const char*)buf, "sample.txt", offset, size - offset ); } CHECK( npk_entity_read_partial( entity, buf, 8, 32 ) ); CHECK_EQUAL_STR_WITH_FILE_PARTIAL( (const char*)buf, "sample.txt", 8, 32 ); free( buf ); } npk_package_close( pack ); return 0; }
int libnpk_streamable( int argc, char * argv [] ) { int teakey[4] = {1,2,3,4}; NPK_PACKAGE pack; NPK_ENTITY entity; // create a pack CHECK( NPK_SUCCESS == npk_package_alloc( &pack, teakey ) ); CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "sample.txt", &entity ) ); CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "tea.txt", &entity ) ); CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_ENCRYPT_TEA ) ); CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "xxtea.txt", &entity ) ); CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_ENCRYPT_XXTEA ) ); CHECK( NPK_SUCCESS == npk_package_add_file( pack, "sample.txt", "zip.txt", &entity ) ); CHECK( NPK_SUCCESS == npk_entity_set_flag( entity, NPK_ENTITY_COMPRESS_ZLIB ) ); CHECK( NPK_SUCCESS == npk_package_save( pack, "foo.npk", true ) ); npk_package_close( pack ); // simulate download int rh = open( "foo.npk", O_RDONLY | O_BINARY ); size_t filesize = npk_seek( rh, 0, SEEK_END ); npk_seek( rh, 0, SEEK_SET ); int wh = open( "foo_2.npk", O_CREAT | O_RDWR | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE ); // validation std::string entityNames[4] = { "sample.txt", "tea.txt", "xxtea.txt", "zip.txt" }; pack = 0; int i = 0; size_t offset = 0; char buf[255]; while( offset < filesize ) { size_t r = rand()%16; if( r + offset > filesize ) r = filesize - offset; read( rh, &buf, sizeof(char)*r ); write( wh, buf, sizeof(char)*r ); printf( "offset %ld, reading %ld byte(s).\n", offset, r ); offset += r; if( pack == 0 ) { pack = npk_package_open( "foo_2.npk", teakey ); if( pack != 0 ) printf( " package loaded.\n" ); } else { NPK_ENTITY entity = npk_package_get_entity( pack, entityNames[i].c_str() ); CHECK( entity != NULL ); NPK_SIZE size = npk_entity_get_size( entity ); if( npk_entity_is_ready( entity ) ) { printf( " entity %s ready.\n", entityNames[i].c_str() ); void* buf = malloc( size ); CHECK( npk_entity_read( entity, buf ) ); CHECK_EQUAL_STR_WITH_FILE( (const char*)buf, "sample.txt" ); free( buf ); ++i; } } } npk_package_close( pack ); close( wh ); close( rh ); return 0; }