static void memory_pool_free_entry( gpointer data, gpointer user_data GCC_UNUSED ) { memory_pool_entry_t *entry = data; libspectrum_free( entry->memory ); libspectrum_free( entry ); }
/* Write the current in-memory tape file out to disk */ int tape_write( const char* filename ) { libspectrum_id_t type; libspectrum_class_t class; libspectrum_byte *buffer; size_t length; int error; /* Work out what sort of file we want from the filename; default to .tzx if we couldn't guess */ error = libspectrum_identify_file_with_class( &type, &class, filename, NULL, 0 ); if( error ) return error; if( class != LIBSPECTRUM_CLASS_TAPE || type == LIBSPECTRUM_ID_UNKNOWN ) type = LIBSPECTRUM_ID_TAPE_TZX; length = 0; error = libspectrum_tape_write( &buffer, &length, tape, type ); if( error != LIBSPECTRUM_ERROR_NONE ) return error; error = utils_write_file( filename, buffer, length ); if( error ) { libspectrum_free( buffer ); return error; } tape_modified = 0; ui_tape_browser_update( UI_TAPE_BROWSER_MODIFIED, NULL ); libspectrum_free( buffer ); return 0; }
int snapshot_write( const char *filename ) { libspectrum_id_t type; libspectrum_class_t class; libspectrum_snap *snap; unsigned char *buffer; size_t length; int flags; int error; /* Work out what sort of file we want from the filename; default to .szx if we couldn't guess */ error = libspectrum_identify_file_with_class( &type, &class, filename, NULL, 0 ); if( error ) return error; if( class != LIBSPECTRUM_CLASS_SNAPSHOT || type == LIBSPECTRUM_ID_UNKNOWN ) type = LIBSPECTRUM_ID_SNAPSHOT_SZX; snap = libspectrum_snap_alloc(); error = snapshot_copy_to( snap ); if( error ) { libspectrum_snap_free( snap ); return error; } flags = 0; length = 0; buffer = NULL; error = libspectrum_snap_write( &buffer, &length, &flags, snap, type, fuse_creator, 0 ); if( error ) { libspectrum_snap_free( snap ); return error; } if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS ) { ui_error( UI_ERROR_WARNING, "A large amount of information has been lost in conversion; the snapshot probably won't work" ); } else if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MINOR_INFO_LOSS ) { ui_error( UI_ERROR_WARNING, "Some information has been lost in conversion; the snapshot may not work" ); } error = libspectrum_snap_free( snap ); if( error ) { libspectrum_free( buffer ); return 1; } error = utils_write_file( filename, buffer, length ); if( error ) { libspectrum_free( buffer ); return error; } libspectrum_free( buffer ); return 0; }
int rzx_finalise_recording( const char *filename ) { libspectrum_byte *buffer; size_t length; libspectrum_error libspec_error; int error; utils_file file; if( rzx_recording || rzx_playback ) return 1; error = utils_read_file( filename, &file ); if( error ) return error; rzx = libspectrum_rzx_alloc(); libspec_error = libspectrum_rzx_read( rzx, file.buffer, file.length ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { utils_close_file( &file ); libspectrum_rzx_free( rzx ); return libspec_error; } utils_close_file( &file ); libspec_error = libspectrum_rzx_finalise( rzx ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_rzx_free( rzx ); return libspec_error; } /* Write the file */ length = 0; buffer = NULL; libspec_error = libspectrum_rzx_write( &buffer, &length, rzx, LIBSPECTRUM_ID_UNKNOWN, fuse_creator, settings_current.rzx_compression, rzx_competition_mode ? &rzx_key : NULL ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_rzx_free( rzx ); return libspec_error; } error = utils_write_file( filename, buffer, length ); if( error ) { libspectrum_free( buffer ); libspectrum_rzx_free( rzx ); return error; } libspectrum_free( buffer ); libspectrum_rzx_free( rzx ); return 0; }
static libspectrum_error rzx_read_frames( input_block_t *block, const libspectrum_byte **ptr, const libspectrum_byte *end ) { size_t i, j; /* And read in the frames */ for( i=0; i < block->count; i++ ) { /* Check the two length bytes exist */ if( end - (*ptr) < 4 ) { libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT, "rzx_read_frames: not enough data in buffer" ); for( j=0; j<i; j++ ) { if( !block->frames[i].repeat_last ) libspectrum_free( block->frames[j].in_bytes ); } return LIBSPECTRUM_ERROR_CORRUPT; } block->frames[i].instructions = libspectrum_read_word( ptr ); block->frames[i].count = libspectrum_read_word( ptr ); if( block->frames[i].count == libspectrum_rzx_repeat_frame ) { block->frames[i].repeat_last = 1; continue; } block->frames[i].repeat_last = 0; if( end - (*ptr) < (ptrdiff_t)block->frames[i].count ) { libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT, "rzx_read_frames: not enough data in buffer" ); for( j=0; j<i; j++ ) { if( !block->frames[i].repeat_last ) libspectrum_free( block->frames[j].in_bytes ); } return LIBSPECTRUM_ERROR_CORRUPT; } if( block->frames[i].count ) { block->frames[i].in_bytes = libspectrum_malloc( block->frames[i].count * sizeof( libspectrum_byte ) ); memcpy( block->frames[i].in_bytes, *ptr, block->frames[i].count ); } else { block->frames[i].in_bytes = NULL; } (*ptr) += block->frames[i].count; } return LIBSPECTRUM_ERROR_NONE; }
static void machine_end( void ) { int i; for( i=0; i<machine_count; i++ ) { if( machine_types[i]->shutdown ) machine_types[i]->shutdown(); libspectrum_free( machine_types[i] ); } libspectrum_free( machine_types ); }
static void free_symbol_table( libspectrum_tape_generalised_data_symbol_table *table ) { size_t i; if( table->symbols ) { for( i = 0; i < table->symbols_in_table; i++ ) libspectrum_free( table->symbols[ i ].lengths ); libspectrum_free( table->symbols ); } }
int rzx_stop_recording( void ) { libspectrum_byte *buffer; size_t length; libspectrum_error libspec_error; int error; if( !rzx_recording ) return 0; /* Stop recording data */ rzx_recording = 0; if( settings_current.movie_stop_after_rzx ) movie_stop(); /* Embed final snapshot */ if( !rzx_competition_mode ) rzx_add_snap( rzx, 0 ); libspectrum_free( rzx_in_bytes ); rzx_in_bytes = NULL; rzx_in_allocated = 0; ui_menu_activate( UI_MENU_ITEM_RECORDING, 0 ); ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 ); libspectrum_creator_set_competition_code( fuse_creator, settings_current.competition_code ); length = 0; buffer = NULL; libspec_error = libspectrum_rzx_write( &buffer, &length, rzx, LIBSPECTRUM_ID_UNKNOWN, fuse_creator, settings_current.rzx_compression, rzx_competition_mode ? &rzx_key : NULL ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( rzx_filename ); libspectrum_rzx_free( rzx ); return libspec_error; } error = utils_write_file( rzx_filename, buffer, length ); libspectrum_free( rzx_filename ); if( error ) { libspectrum_free( buffer ); libspectrum_rzx_free( rzx ); return error; } libspectrum_free( buffer ); libspec_error = libspectrum_rzx_free( rzx ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) return libspec_error; return 0; }
void g_hash_table_destroy (GHashTable *hash_table) { guint i; for (i = 0; i < HASH_TABLE_SIZE; i++) g_hash_nodes_destroy (hash_table->nodes[i], hash_table->key_destroy_func, hash_table->value_destroy_func); libspectrum_free (hash_table->nodes); libspectrum_free (hash_table); }
/* Free all non-persistent memory in the pool */ void memory_pool_free( void ) { GSList *ptr; while( ( ptr = g_slist_find_custom( pool, NULL, find_non_persistent ) ) != NULL ) { memory_pool_entry_t *entry = ptr->data; libspectrum_free( entry->memory ); pool = g_slist_remove( pool, entry ); libspectrum_free( entry ); } }
static libspectrum_error serialise_mpis( libspectrum_byte **signature, size_t *signature_length, gcry_mpi_t r, gcry_mpi_t s ) { gcry_error_t error; size_t length, length_s; unsigned char *ptr; error = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &length, r ); if( error ) { libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "serialise_mpis: length of r: %s", gcry_strerror( error ) ); return LIBSPECTRUM_ERROR_LOGIC; } error = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &length_s, s ); if( error ) { libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "serialise_mpis: length of s: %s", gcry_strerror( error ) ); return LIBSPECTRUM_ERROR_LOGIC; } length += length_s; *signature_length = length; *signature = libspectrum_malloc( length ); error = gcry_mpi_print( GCRYMPI_FMT_PGP, *signature, length, &length, r ); if( error ) { libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "serialise_mpis: printing r: %s", gcry_strerror( error ) ); libspectrum_free( *signature ); return LIBSPECTRUM_ERROR_LOGIC; } ptr = *signature + length; length = *signature_length - length; error = gcry_mpi_print( GCRYMPI_FMT_PGP, ptr, length, NULL, s ); if( error ) { libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "serialise_mpis: printing s: %s", gcry_strerror( error ) ); libspectrum_free( *signature ); return LIBSPECTRUM_ERROR_LOGIC; } return LIBSPECTRUM_ERROR_NONE; }
int ide_eject( libspectrum_ide_channel *chn, libspectrum_ide_unit unit, int (*commit_fn)( libspectrum_ide_unit unit ), char **setting, ui_menu_item item ) { int error; if( libspectrum_ide_dirty( chn, unit ) ) { ui_confirm_save_t confirm = ui_confirm_save( "Hard disk has been modified.\nDo you want to save it?" ); switch( confirm ) { case UI_CONFIRM_SAVE_SAVE: error = commit_fn( unit ); if( error ) return error; break; case UI_CONFIRM_SAVE_DONTSAVE: break; case UI_CONFIRM_SAVE_CANCEL: return 1; } } libspectrum_free( *setting ); *setting = NULL; error = libspectrum_ide_eject( chn, unit ); if( error ) return error; error = ui_menu_activate( item, 0 ); if( error ) return error; return 0; }
void sound_end( void ) { if( sound_enabled ) { delete_Blip_Synth( &left_beeper_synth ); delete_Blip_Synth( &right_beeper_synth ); delete_Blip_Synth( &ay_a_synth ); delete_Blip_Synth( &ay_b_synth ); delete_Blip_Synth( &ay_c_synth ); delete_Blip_Synth( &ay_a_synth_r ); delete_Blip_Synth( &ay_b_synth_r ); delete_Blip_Synth( &ay_c_synth_r ); delete_Blip_Synth( &left_specdrum_synth ); delete_Blip_Synth( &right_specdrum_synth ); delete_Blip_Buffer( &left_buf ); delete_Blip_Buffer( &right_buf ); if( settings_current.sound ) sound_lowlevel_end(); libspectrum_free( samples ); sound_enabled = 0; } }
int rzx_start_recording( const char *filename, int embed_snapshot ) { int error; if( rzx_playback ) return 1; rzx = libspectrum_rzx_alloc(); /* Store the filename */ rzx_filename = utils_safe_strdup( filename ); /* If we're embedding a snapshot, create it now */ if( embed_snapshot ) { error = rzx_add_snap( rzx, 0 ); if( error ) { libspectrum_free( rzx_filename ); libspectrum_rzx_free( rzx ); return error; } } start_recording( rzx, settings_current.competition_mode ); return 0; }
void libspectrum_hashtable_cleanup( void ) { libspectrum_free( node_allocated_list ); node_allocated_list = NULL; node_free_list = NULL; }
gchar* g_array_free( GArray *array, gboolean free_segment ) { gchar* segment; if( free_segment ) { libspectrum_free( array->data ); segment = NULL; } else segment = array->data; libspectrum_free( array ); return segment; }
static libspectrum_error rzx_write_signed_end( libspectrum_byte **buffer, libspectrum_byte **ptr, size_t *length, ptrdiff_t sign_offset, libspectrum_rzx_dsa_key *key ) { #ifdef HAVE_GCRYPT_H libspectrum_error error; libspectrum_byte *signature; size_t sig_length; /* Get the actual signature */ error = libspectrum_sign_data( &signature, &sig_length, ( *buffer + sign_offset ), (*ptr) - ( *buffer + sign_offset ), key ); if( error ) return error; libspectrum_make_room( buffer, sig_length + 5, ptr, length ); /* Block ID */ *(*ptr)++ = LIBSPECTRUM_RZX_SIGN_END_BLOCK; /* Block length */ libspectrum_write_dword( ptr, sig_length + 5 ); /* Write the signature */ memcpy( *ptr, signature, sig_length ); (*ptr) += sig_length; libspectrum_free( signature ); #endif /* #ifdef HAVE_GCRYPT_H */ return LIBSPECTRUM_ERROR_NONE; }
int ui_mdr_write( int which, int saveas ) { int err; char *filename = NULL, title[80]; fuse_emulation_pause(); snprintf( title, 80, "Fuse - Write Microdrive Cartridge %i", which + 1 ); if( saveas ) { filename = ui_get_save_filename( title ); if( !filename ) { fuse_emulation_unpause(); return 1; } } err = if1_mdr_write( which, filename ); if( saveas ) libspectrum_free( filename ); fuse_emulation_unpause(); return err; }
libspectrum_error libspectrum_rzx_free( libspectrum_rzx *rzx ) { g_slist_foreach( rzx->blocks, block_free_wrapper, NULL ); g_slist_free( rzx->blocks ); libspectrum_free( rzx ); return LIBSPECTRUM_ERROR_NONE; }
static libspectrum_error get_hash( gcry_sexp_t *hash, const libspectrum_byte *data, size_t data_length ) { gcry_error_t error; unsigned char *digest; size_t digest_length; gcry_mpi_t hash_mpi; digest_length = gcry_md_get_algo_dlen( HASH_ALGORITHM ); digest = libspectrum_malloc( digest_length ); gcry_md_hash_buffer( HASH_ALGORITHM, digest, data, data_length ); error = gcry_mpi_scan( &hash_mpi, GCRYMPI_FMT_USG, digest, digest_length, NULL ); if( error ) { libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "get_hash: error creating hash MPI: %s", gcry_strerror( error ) ); libspectrum_free( digest ); return LIBSPECTRUM_ERROR_LOGIC; } libspectrum_free( digest ); error = gcry_sexp_build( hash, NULL, hash_format, hash_mpi ); if( error ) { libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "get_hash: error creating hash sexp: %s", gcry_strerror( error ) ); gcry_mpi_release( hash_mpi ); return LIBSPECTRUM_ERROR_LOGIC; } gcry_mpi_release( hash_mpi ); return LIBSPECTRUM_ERROR_NONE; }
/* Request a snapshot file from the user and it */ int utils_open_snap( void ) { char *filename; int error; filename = ui_get_open_filename( "Fuse - Load Snapshot" ); if( !filename ) return -1; error = snapshot_read( filename ); libspectrum_free( filename ); return error; }
int display_init( int *argc, char ***argv ) { int i, j, k, x, y; int error; if(ui_init(argc, argv)) return 1; /* Set up the 'all pixels must be refreshed' marker */ display_all_dirty = 0; for( i = 0; i < DISPLAY_SCREEN_WIDTH_COLS; i++ ) display_all_dirty = ( display_all_dirty << 1 ) | 0x01; for(i=0;i<3;i++) for(j=0;j<8;j++) for(k=0;k<8;k++) display_line_start[ (64*i) + (8*j) + k ] = 32 * ( (64*i) + j + (k*8) ); for(y=0;y<DISPLAY_HEIGHT;y++) { display_attr_start[y]=6144 + (32*(y/8)); } for(y=0;y<DISPLAY_HEIGHT;y++) for(x=0;x<DISPLAY_WIDTH_COLS;x++) { display_dirty_ytable[ display_line_start[y]+x ] = y; display_dirty_xtable[ display_line_start[y]+x ] = x; } for(y=0;y<DISPLAY_HEIGHT_ROWS;y++) for(x=0;x<DISPLAY_WIDTH_COLS;x++) { display_dirty_ytable2[ (32*y) + x ] = y * 8; display_dirty_xtable2[ (32*y) + x ] = x; } display_frame_count=0; display_flash_reversed=0; display_refresh_all(); border_changes_last = 0; if( border_changes ) { libspectrum_free( border_changes ); } border_changes = NULL; error = add_border_sentinel(); if( error ) return error; display_last_border = scld_last_dec.name.hires ? display_hires_border : display_lores_border; return 0; }
int utils_read_fd( compat_fd fd, const char *filename, utils_file *file ) { file->length = compat_file_get_length( fd ); if( file->length == -1 ) return 1; file->buffer = libspectrum_new( unsigned char, file->length ); if( compat_file_read( fd, file ) ) { libspectrum_free( file->buffer ); compat_file_close( fd ); return 1; } if( compat_file_close( fd ) ) { ui_error( UI_ERROR_ERROR, "Couldn't close '%s': %s", filename, strerror( errno ) ); libspectrum_free( file->buffer ); return 1; } return 0; }
void dck_eject( void ) { if ( !( libspectrum_machine_capabilities( machine_current->machine ) & LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) { ui_error( UI_ERROR_ERROR, "This machine does not support the dock" ); return; } if( settings_current.dck_file ) libspectrum_free( settings_current.dck_file ); settings_current.dck_file = NULL; dck_active = 0; ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 ); machine_reset( 0 ); }
int rzx_continue_recording( const char *filename ) { utils_file file; libspectrum_error libspec_error; int error; libspectrum_snap* snap = NULL; libspectrum_rzx_iterator last_it = NULL; if( rzx_recording || rzx_playback ) return 1; /* Store the filename */ rzx_filename = utils_safe_strdup( filename ); error = utils_read_file( filename, &file ); if( error ) return error; rzx = libspectrum_rzx_alloc(); libspec_error = libspectrum_rzx_read( rzx, file.buffer, file.length ); if( libspec_error != LIBSPECTRUM_ERROR_NONE ) { utils_close_file( &file ); return libspec_error; } utils_close_file( &file ); /* Get final snapshot */ last_it = libspectrum_rzx_iterator_last( rzx ); if( last_it ) snap = libspectrum_rzx_iterator_get_snap( last_it ); if( snap ) { error = snapshot_copy_from( snap ); if( error ) return error; } else { ui_error( UI_ERROR_WARNING, "RZX file cannot be continued" ); libspectrum_free( rzx_filename ); libspectrum_rzx_free( rzx ); return 1; } start_recording( rzx, 0 ); return 0; }
int ui_tape_write( void ) { char *filename; fuse_emulation_pause(); filename = ui_get_save_filename( "Fuse - Write Tape" ); if( !filename ) { fuse_emulation_unpause(); return 1; } tape_write( filename ); libspectrum_free( filename ); fuse_emulation_unpause(); return 0; }
static libspectrum_error block_free( rzx_block_t *block ) { size_t i; input_block_t *input; #ifdef HAVE_GCRYPT_H signature_block_t *signature; #endif /* #ifdef HAVE_GCRYPT_H */ switch( block->type ) { case LIBSPECTRUM_RZX_INPUT_BLOCK: input = &( block->types.input ); for( i = 0; i < input->count; i++ ) if( !input->frames[i].repeat_last ) libspectrum_free( input->frames[i].in_bytes ); libspectrum_free( input->frames ); libspectrum_free( block ); return LIBSPECTRUM_ERROR_NONE; case LIBSPECTRUM_RZX_SNAPSHOT_BLOCK: libspectrum_snap_free( block->types.snap.snap ); libspectrum_free( block ); return LIBSPECTRUM_ERROR_NONE; case LIBSPECTRUM_RZX_SIGN_START_BLOCK: libspectrum_free( block ); return LIBSPECTRUM_ERROR_NONE; case LIBSPECTRUM_RZX_SIGN_END_BLOCK: #ifdef HAVE_GCRYPT_H signature = &( block->types.signature ); gcry_mpi_release( signature->r ); gcry_mpi_release( signature->s ); #endif /* #ifdef HAVE_GCRYPT_H */ libspectrum_free( block ); return LIBSPECTRUM_ERROR_NONE; case LIBSPECTRUM_RZX_CREATOR_BLOCK: break; } libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "unknown RZX block type %d at %s:%d", block->type, __FILE__, __LINE__ ); return LIBSPECTRUM_ERROR_LOGIC; }
void nic_w5100_free( nic_w5100_t *self ) { int i; if( self ) { self->stop_io_thread = 1; compat_socket_selfpipe_wake( self->selfpipe ); pthread_join( self->thread, NULL ); for( i = 0; i < 4; i++ ) nic_w5100_socket_end( &self->socket[i] ); compat_socket_selfpipe_free( self->selfpipe ); compat_socket_networking_end(); libspectrum_free( self ); } }
/* Tidy-up function called at end of emulation */ static void memory_end( void ) { int i; char *description; /* Free all the memory we've allocated for this machine */ if( pool ) { g_slist_foreach( pool, memory_pool_free_entry, NULL ); g_slist_free( pool ); pool = NULL; } /* Free memory source types */ if( memory_sources ) { for( i = 0; i < memory_sources->len; i++ ) { description = g_array_index( memory_sources, char *, i ); libspectrum_free( description ); } g_array_free( memory_sources, TRUE ); memory_sources = NULL; } }
static libspectrum_error inflate_block( libspectrum_byte **uncompressed, size_t *uncompressed_length, const libspectrum_byte **compressed, size_t compressed_length ) { #ifdef HAVE_ZLIB_H libspectrum_dword header_length, expected_crc32, actual_crc32; libspectrum_byte *zlib_buffer; unsigned long actual_length; int error; /* First, look at the compression header */ header_length = libspectrum_read_dword( compressed ); if( header_length != 12 ) { libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN, "zxs_inflate_block: unknown header length %lu", (unsigned long)header_length ); return LIBSPECTRUM_ERROR_UNKNOWN; } compressed_length -= 12; expected_crc32 = libspectrum_read_dword( compressed ); *uncompressed_length = libspectrum_read_dword( compressed ); /* Some space to put the zlib header for decompression */ zlib_buffer = libspectrum_malloc( ( compressed_length + 6 ) * sizeof( *zlib_buffer ) ); /* zlib's header */ zlib_buffer[0] = 0x78; zlib_buffer[1] = 0xda; memcpy( &zlib_buffer[2], *compressed, compressed_length ); *compressed += compressed_length; *uncompressed = libspectrum_malloc( *uncompressed_length * sizeof( **uncompressed ) ); actual_length = *uncompressed_length; error = uncompress( *uncompressed, &actual_length, zlib_buffer, compressed_length + 6 ); /* At this point, we expect to get a Z_DATA_ERROR, as we don't have the Adler-32 checksum of the data. There is a 1 in 65521 chance that the random bytes will match, so we might (very rarely) get Z_OK */ if( error != Z_DATA_ERROR && error != Z_OK ) { libspectrum_free( *uncompressed ); libspectrum_free( zlib_buffer ); libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT, "zxs_inflate_block: unexpected zlib error" ); return LIBSPECTRUM_ERROR_CORRUPT; } if( *uncompressed_length != actual_length ) { libspectrum_free( *uncompressed ); libspectrum_free( zlib_buffer ); libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT, "zxs_inflate_block: block expanded to 0x%04lx, not the expected 0x%04lx bytes", actual_length, (unsigned long)*uncompressed_length ); return LIBSPECTRUM_ERROR_CORRUPT; } libspectrum_free( zlib_buffer ); actual_crc32 = crc32( 0, Z_NULL, 0 ); actual_crc32 = crc32( actual_crc32, *uncompressed, *uncompressed_length ); if( actual_crc32 != expected_crc32 ) { libspectrum_free( *uncompressed ); libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT, "zxs_inflate_block: crc 0x%08x does not match expected 0x%08x", actual_crc32, expected_crc32 ); return LIBSPECTRUM_ERROR_CORRUPT; } return LIBSPECTRUM_ERROR_NONE; #else /* #ifdef HAVE_ZLIB_H */ /* No zlib, so can't inflate the block */ return LIBSPECTRUM_ERROR_UNKNOWN; #endif /* #ifdef HAVE_ZLIB_H */ }