/* Given a buffer and optionally a filename, make a best guess as to what sort of file this is */ libspectrum_error libspectrum_identify_file_with_class( libspectrum_id_t *type, libspectrum_class_t *libspectrum_class, const char *filename, const unsigned char *buffer, size_t length ) { libspectrum_error error; char *new_filename = NULL; unsigned char *new_buffer; size_t new_length; error = libspectrum_identify_file_raw( type, filename, buffer, length ); if( error ) return error; error = libspectrum_identify_class( libspectrum_class, *type ); if( error ) return error; if( *libspectrum_class != LIBSPECTRUM_CLASS_COMPRESSED ) return LIBSPECTRUM_ERROR_NONE; error = libspectrum_uncompress_file( &new_buffer, &new_length, &new_filename, *type, buffer, length, filename ); if( error ) return error; error = libspectrum_identify_file_with_class( type, libspectrum_class, new_filename, new_buffer, new_length ); if( error ) return error; free( new_filename ); free( new_buffer ); return LIBSPECTRUM_ERROR_NONE; }
libspectrum_error libspectrum_rzx_read( libspectrum_rzx *rzx, const libspectrum_byte *buffer, size_t length ) { libspectrum_error error; const libspectrum_byte *ptr, *end; int uncompressed; libspectrum_byte *new_buffer; libspectrum_id_t raw_type; libspectrum_class_t class; /* Find out if this file needs decompression */ uncompressed = 0; new_buffer = NULL; error = libspectrum_identify_file_raw( &raw_type, NULL, buffer, length ); if( error ) return error; error = libspectrum_identify_class( &class, raw_type ); if( error ) return error; if( class == LIBSPECTRUM_CLASS_COMPRESSED ) { size_t new_length; error = libspectrum_uncompress_file( &new_buffer, &new_length, NULL, raw_type, buffer, length, NULL ); buffer = new_buffer; length = new_length; uncompressed = 1; } ptr = buffer; end = buffer + length; error = rzx_read_header( &ptr, end ); if( error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( new_buffer ); return error; } rzx->signed_start = ptr; while( ptr < end ) { libspectrum_byte id; id = *ptr++; switch( id ) { case LIBSPECTRUM_RZX_CREATOR_BLOCK: error = rzx_read_creator( &ptr, end ); if( error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( new_buffer ); return error; } break; case LIBSPECTRUM_RZX_SNAPSHOT_BLOCK: error = rzx_read_snapshot( rzx, &ptr, end ); if( error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( new_buffer ); return error; } break; case LIBSPECTRUM_RZX_INPUT_BLOCK: error = rzx_read_input( rzx, &ptr, end ); if( error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( new_buffer ); return error; } break; case LIBSPECTRUM_RZX_SIGN_START_BLOCK: error = rzx_read_sign_start( rzx, &ptr, end ); if( error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( new_buffer ); return error; } break; case LIBSPECTRUM_RZX_SIGN_END_BLOCK: error = rzx_read_sign_end( rzx, &ptr, end ); if( error != LIBSPECTRUM_ERROR_NONE ) { libspectrum_free( new_buffer ); return error; } break; default: libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN, "libspectrum_rzx_read: unknown RZX block ID 0x%02x", id ); libspectrum_free( new_buffer ); return LIBSPECTRUM_ERROR_UNKNOWN; } } libspectrum_free( new_buffer ); return LIBSPECTRUM_ERROR_NONE; }
/* Read in a snapshot, optionally guessing what type it is */ libspectrum_error libspectrum_snap_read( libspectrum_snap *snap, const libspectrum_byte *buffer, size_t length, libspectrum_id_t type, const char *filename ) { libspectrum_id_t raw_type; libspectrum_class_t class; libspectrum_byte *new_buffer; libspectrum_error error; /* If we don't know what sort of file this is, make a best guess */ if( type == LIBSPECTRUM_ID_UNKNOWN ) { error = libspectrum_identify_file( &type, filename, buffer, length ); if( error ) return error; /* If we still can't identify it, give up */ if( type == LIBSPECTRUM_ID_UNKNOWN ) { libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN, "libspectrum_snap_read: couldn't identify file" ); return LIBSPECTRUM_ERROR_UNKNOWN; } } error = libspectrum_identify_class( &class, type ); if( error ) return error; if( class != LIBSPECTRUM_CLASS_SNAPSHOT ) { libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT, "libspectrum_snap_read: not a snapshot file" ); return LIBSPECTRUM_ERROR_CORRUPT; } /* Find out if this file needs decompression */ new_buffer = NULL; error = libspectrum_identify_file_raw( &raw_type, filename, buffer, length ); if( error ) return error; error = libspectrum_identify_class( &class, raw_type ); if( error ) return error; if( class == LIBSPECTRUM_CLASS_COMPRESSED ) { size_t new_length; error = libspectrum_uncompress_file( &new_buffer, &new_length, NULL, raw_type, buffer, length, NULL ); if( error ) return error; buffer = new_buffer; length = new_length; } switch( type ) { case LIBSPECTRUM_ID_SNAPSHOT_PLUSD: error = libspectrum_plusd_read( snap, buffer, length ); break; case LIBSPECTRUM_ID_SNAPSHOT_SNA: error = internal_sna_read( snap, buffer, length ); break; case LIBSPECTRUM_ID_SNAPSHOT_SNP: error = libspectrum_snp_read( snap, buffer, length ); break; case LIBSPECTRUM_ID_SNAPSHOT_SP: error = libspectrum_sp_read( snap, buffer, length ); break; case LIBSPECTRUM_ID_SNAPSHOT_SZX: error = libspectrum_szx_read( snap, buffer, length ); break; case LIBSPECTRUM_ID_SNAPSHOT_Z80: error = internal_z80_read( snap, buffer, length ); break; case LIBSPECTRUM_ID_SNAPSHOT_ZXS: error = libspectrum_zxs_read( snap, buffer, length ); break; default: libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "libspectrum_snap_read: unknown snapshot type %d", type ); libspectrum_free( new_buffer ); return LIBSPECTRUM_ERROR_LOGIC; } libspectrum_free( new_buffer ); return error; }
/* Read in a tape file, optionally guessing what sort of file it is */ libspectrum_error libspectrum_tape_read( libspectrum_tape *tape, const libspectrum_byte *buffer, size_t length, libspectrum_id_t type, const char *filename ) { libspectrum_id_t raw_type; libspectrum_class_t class; libspectrum_byte *new_buffer; libspectrum_error error; int uncompressed; /* If we don't know what sort of file this is, make a best guess */ if( type == LIBSPECTRUM_ID_UNKNOWN ) { error = libspectrum_identify_file( &type, filename, buffer, length ); if( error ) return error; /* If we still can't identify it, give up */ if( type == LIBSPECTRUM_ID_UNKNOWN ) { libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN, "libspectrum_tape_read: couldn't identify file" ); return LIBSPECTRUM_ERROR_UNKNOWN; } } /* Find out if this file needs decompression */ uncompressed = 0; new_buffer = NULL; error = libspectrum_identify_file_raw( &raw_type, filename, buffer, length ); if( error ) return error; error = libspectrum_identify_class( &class, raw_type ); if( error ) return error; if( class == LIBSPECTRUM_CLASS_COMPRESSED ) { size_t new_length; error = libspectrum_uncompress_file( &new_buffer, &new_length, NULL, raw_type, buffer, length, NULL ); buffer = new_buffer; length = new_length; uncompressed = 1; } switch( type ) { case LIBSPECTRUM_ID_TAPE_TAP: case LIBSPECTRUM_ID_TAPE_SPC: case LIBSPECTRUM_ID_TAPE_STA: case LIBSPECTRUM_ID_TAPE_LTP: error = internal_tap_read( tape, buffer, length, type ); break; case LIBSPECTRUM_ID_TAPE_TZX: error = internal_tzx_read( tape, buffer, length ); break; /* case LIBSPECTRUM_ID_TAPE_WARAJEVO: error = internal_warajevo_read( tape, buffer, length ); break; case LIBSPECTRUM_ID_TAPE_Z80EM: error = libspectrum_z80em_read( tape, buffer, length ); break; case LIBSPECTRUM_ID_TAPE_CSW: error = libspectrum_csw_read( tape, buffer, length ); break; */ case LIBSPECTRUM_ID_TAPE_WAV: #ifdef HAVE_LIB_AUDIOFILE error = libspectrum_wav_read( tape, filename ); break; #else /* #ifdef HAVE_LIB_AUDIOFILE */ error = LIBSPECTRUM_ERROR_LOGIC; libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC, "libspectrum_tape_read: format not supported without libaudiofile" ); break; #endif /* #ifdef HAVE_LIB_AUDIOFILE */ default: libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT, "libspectrum_tape_read: not a tape file" ); free( new_buffer ); return LIBSPECTRUM_ERROR_CORRUPT; } free( new_buffer ); return error; }