virtual void archive_list(const char *path, const service_ptr_t<file> &p_reader, archive_callback &p_out, bool p_want_readers) { if (!_extract_native_path_ptr(path)) throw exception_io_data(); AATR *aatr = pfc::new_ptr_check_t(AATR_New()); if (!AATR_Open(aatr, path)) { AATR_Delete(aatr); throw exception_io_data(); } pfc::string8_fastalloc url; for (;;) { const char *fn = AATR_NextFile(aatr); if (fn == NULL) break; t_filestats stats = { filesize_invalid, filetimestamp_invalid }; service_ptr_t<file> p_file; if (p_want_readers) { BYTE module[ASAPInfo_MAX_MODULE_LENGTH]; int module_len = AATR_ReadCurrentFile(aatr, module, sizeof(module)); p_file = new service_impl_t<reader_membuffer_simple>(module, module_len); } archive_impl::g_make_unpack_path(url, path, fn, "atr"); if (!p_out.on_entry(this, url, stats, p_file)) break; } AATR_Delete(aatr); }
void SpotifySession::takeDecoder(void *owner) { if (!hasDecoder(NULL)) throw exception_io_data("Someone else is already decoding"); InterlockedCompareExchangePointer(&decoderOwner, owner, NULL); if (!hasDecoder(owner)) throw exception_io_data("Someone else beat us to the decoder"); }
void open(service_ptr_t<file> p_filehint,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort) { if ( p_reason == input_open_info_write ) { throw exception_io_unsupported_format(); // our input does not support retagging. } m_file = p_filehint; // p_filehint may be null, hence next line input_open_file_helper(m_file,p_path,p_reason,p_abort); // if m_file is null, opens file with appropriate privileges for our operation (read/write for writing tags, read-only otherwise). if ( m_file->get_size( p_abort ) >= (std::numeric_limits<std::size_t>::max)() ) { throw exception_io_unsupported_format(); } std::vector<char> data( static_cast<std::size_t>( m_file->get_size( p_abort ) ) ); m_file->read( data.data(), data.size(), p_abort ); try { std::map< std::string, std::string > ctls; ctls["seek.sync_samples"] = "1"; mod = new openmpt::module( data, std::clog, ctls ); } catch ( std::exception & /*e*/ ) { throw exception_io_data(); } settings = foo_openmpt_settings(); mod->set_repeat_count( settings.repeatcount ); mod->set_render_param( openmpt::module::RENDER_MASTERGAIN_MILLIBEL, settings.mastergain_millibel ); mod->set_render_param( openmpt::module::RENDER_STEREOSEPARATION_PERCENT, settings.stereoseparation ); mod->set_render_param( openmpt::module::RENDER_INTERPOLATIONFILTER_LENGTH, settings.interpolationfilterlength ); mod->set_render_param( openmpt::module::RENDER_VOLUMERAMPING_STRENGTH, settings.ramping ); mod->ctl_set( "render.resampler.emulate_amiga", settings.use_amiga_resampler ? "1" : "0" ); }
service_ptr input_entry::g_open_from_list(input_entry_list_t const & p_list, const GUID & whatFor, service_ptr_t<file> p_filehint, const char * p_path, abort_callback & p_abort, GUID * outGUID) { const t_size count = p_list.get_count(); if ( count == 0 ) { // sanity throw exception_io_unsupported_format(); } else if (count == 1) { auto ret = p_list[0]->open(whatFor, p_filehint, p_path, p_abort); if ( outGUID != nullptr ) * outGUID = input_get_guid( p_list[0] ); return ret; } else { unsigned bad_data_count = 0; pfc::string8 bad_data_message; for (t_size n = 0; n < count; n++) { try { auto ret = p_list[n]->open(whatFor, p_filehint, p_path, p_abort); if (outGUID != nullptr) * outGUID = input_get_guid(p_list[n]); return ret; } catch (exception_io_no_handler_for_path) { //do nothing, skip over } catch (exception_io_unsupported_format) { //do nothing, skip over } catch (exception_io_data const & e) { if (bad_data_count++ == 0) bad_data_message = e.what(); } } if (bad_data_count > 1) throw exception_io_data(); else if (bad_data_count == 0) pfc::throw_exception_with_message<exception_io_data>(bad_data_message); else throw exception_io_unsupported_format(); } }
void playlist_loader::g_save_playlist(const char * p_filename,const pfc::list_base_const_t<metadb_handle_ptr> & data,abort_callback & p_abort) { TRACK_CALL_TEXT("playlist_loader::g_save_playlist"); pfc::string8 filename; filesystem::g_get_canonical_path(p_filename,filename); try { service_ptr_t<file> r; filesystem::g_open(r,filename,filesystem::open_mode_write_new,p_abort); pfc::string_extension ext(filename); service_enum_t<playlist_loader> e; service_ptr_t<playlist_loader> l; if (e.first(l)) do { if (l->can_write() && !stricmp_utf8(ext,l->get_extension())) { try { TRACK_CODE("playlist_loader::write",l->write(filename,r,data,p_abort)); return; } catch(exception_io_data) {} } } while(e.next(l)); throw exception_io_data(); } catch(...) { try {filesystem::g_remove(filename,p_abort);} catch(...) {} throw; } }
void open(service_ptr_t<file> m_file, const char * p_path, t_input_open_reason p_reason, abort_callback & p_abort) { if (p_reason == input_open_info_write) { throw exception_io_data(); } input_open_file_helper(m_file, p_path, p_reason, p_abort); m_stats = m_file->get_stats(p_abort); m_decoder = new dts_decode(); if (!m_decoder->load( m_file, p_abort)) { throw exception_io_data(); } }
static void g_write_tags_ex(tag_write_callback & p_callback,unsigned p_flags,const service_ptr_t<file> & p_file,const file_info * p_info,abort_callback & p_abort) { PFC_ASSERT( p_flags == 0 || p_info != 0 ); if (p_flags & (g_flag_id3v1 | g_flag_apev2)) { switch(p_flags & (g_flag_id3v1 | g_flag_apev2)) { case g_flag_id3v1 | g_flag_apev2: static_api_ptr_t<tag_processor_trailing>()->write_apev2_id3v1(p_file,*p_info,p_abort); break; case g_flag_id3v1: static_api_ptr_t<tag_processor_trailing>()->write_id3v1(p_file,*p_info,p_abort); break; case g_flag_apev2: static_api_ptr_t<tag_processor_trailing>()->write_apev2(p_file,*p_info,p_abort); break; default: throw exception_io_data(); } } else { static_api_ptr_t<tag_processor_trailing>()->remove(p_file,p_abort); } if (p_flags & g_flag_id3v2) { static_api_ptr_t<tag_processor_id3v2>()->write_ex(p_callback,p_file,*p_info,p_abort); } else { t_uint64 dummy; tag_processor_id3v2::g_remove_ex(p_callback,p_file,dummy,p_abort); } }
void open( service_ptr_t<file> m_file, const char * p_path, t_input_open_reason p_reason, abort_callback & p_abort ) { if ( p_reason == input_open_info_write ) throw exception_io_data(); input_open_file_helper( m_file, p_path, p_reason, p_abort ); m_stats = m_file->get_stats( p_abort ); t_uint8 * ptr; unsigned size; t_filesize size64 = m_file->get_size_ex( p_abort ); if ( size64 > ( 1 << 24 ) ) throw exception_io_data(); size = (unsigned) size64; file_buffer.set_size( size ); ptr = file_buffer.get_ptr(); m_file->read_object( ptr, size, p_abort ); m_player = ModPlug_Load(ptr, size); if ( !m_player ) throw exception_io_data(); }
void dsp_preset::g_contents_from_stream_skip(stream_reader * p_stream,abort_callback & p_abort) { t_uint32 size; GUID guid; p_stream->read_lendian_t(guid,p_abort); p_stream->read_lendian_t(size,p_abort); if (size > 1024*1024*32) throw exception_io_data(); p_stream->skip_object(size,p_abort); }
void dsp_preset::contents_from_stream(stream_reader * p_stream,abort_callback & p_abort) { t_uint32 size; GUID guid; p_stream->read_lendian_t(guid,p_abort); set_owner(guid); p_stream->read_lendian_t(size,p_abort); if (size > 1024*1024*32) throw exception_io_data(); set_data_from_stream(p_stream,size,p_abort); }
void unpacker::g_open(service_ptr_t<file> & p_out,const service_ptr_t<file> & p,abort_callback & p_abort) { service_enum_t<unpacker> e; service_ptr_t<unpacker> ptr; if (e.first(ptr)) do { p->reopen(p_abort); try { ptr->open(p_out,p,p_abort); return; } catch(exception_io_data const &) {} } while(e.next(ptr)); throw exception_io_data(); }
void file::seek_ex(t_sfilesize p_position, file::t_seek_mode p_mode, abort_callback &p_abort) { switch(p_mode) { case seek_from_beginning: seek(p_position,p_abort); break; case seek_from_current: seek(p_position + get_position(p_abort),p_abort); break; case seek_from_eof: seek(p_position + get_size_ex(p_abort),p_abort); break; default: throw exception_io_data(); } }
void write(const service_ptr_t<file> & p_file,abort_callback & p_abort,const char * p_string,bool is_utf8) { p_file->seek(0,p_abort); p_file->set_eof(p_abort); if (is_utf8) { p_file->write_object(utf8_header,sizeof(utf8_header),p_abort); p_file->write_object(p_string,strlen(p_string),p_abort); } else { #ifdef _WIN32 pfc::stringcvt::string_ansi_from_utf8 bah(p_string); p_file->write_object(bah,bah.length(),p_abort); #else throw exception_io_data(); #endif } }
unsigned audio_chunk::g_guess_channel_config_xiph(unsigned count) { if (count == 0 || count >= PFC_TABSIZE(g_audio_channel_config_table_xiph)) throw exception_io_data(); return g_audio_channel_config_table_xiph[count]; }
/* @param msg "logging in" */ void assertSucceeds(pfc::string8 msg, sp_error err) { if (SP_ERROR_OK == err) return; throw exception_io_data(doctor(msg, err)); }
void SpotifySession::ensureDecoder(void *owner) { if (!hasDecoder(owner)) throw exception_io_data("bugcheck: we should own the decoder..."); }
void read_v2(const service_ptr_t<file> & p_file,abort_callback & p_abort,pfc::string_base & p_out,bool & is_utf8, bool forceUTF8) { p_out.reset(); p_file->reopen( p_abort ); pfc::array_t<char> mem; t_filesize size64; size64 = p_file->get_size(p_abort); if (size64 == filesize_invalid)//typically HTTP { pfc::string8 ansitemp; t_size done; enum { delta = 1024 * 64, max = 1024 * 512 }; if ( forceUTF8 ) { is_utf8 = true; } else { is_utf8 = false; char temp[3]; done = p_file->read(temp, 3, p_abort); if (done != 3) { if (done > 0) p_out = pfc::stringcvt::string_utf8_from_ansi(temp, done); return; } if (!memcmp(utf8_header, temp, 3)) is_utf8 = true; else ansitemp.add_string(temp, 3); } mem.set_size(delta); for(;;) { done = p_file->read(mem.get_ptr(),delta,p_abort); if (done > 0) { if (is_utf8) p_out.add_string(mem.get_ptr(),done); else ansitemp.add_string(mem.get_ptr(),done); } if (done < delta) break; } if (!is_utf8) { p_out = pfc::stringcvt::string_utf8_from_ansi(ansitemp); } return; } else { if (size64>1024*1024*128) throw exception_io_data();//hard limit t_size size = pfc::downcast_guarded<t_size>(size64); mem.set_size(size+1); char * asdf = mem.get_ptr(); p_file->read_object(asdf,size,p_abort); asdf[size]=0; if ( forceUTF8 ) { is_utf8 = true; p_out = asdf; } else if (size>3 && !memcmp(utf8_header,asdf,3)) { is_utf8 = true; p_out.add_string(asdf+3); } else { is_utf8 = false; p_out = pfc::stringcvt::string_utf8_from_ansi(asdf); } return; } }
void retag(const file_info & p_info, abort_callback & p_abort) { throw exception_io_data(); }
virtual bool open_path_internal(file::ptr p_filehint,const char * path,t_input_open_reason p_reason,abort_callback & p_abort,bool p_from_redirect,bool p_skip_hints) { if (p_filehint.is_empty()) { try { filesystem::g_open_read(p_filehint,path,p_abort); } catch (exception_io_not_found) { return false; } } if (!p_filehint->can_seek()) { console::formatter() << "loop sampler: file must be seekable, ignores: \"" << file_path_display(path) << "\""; return false; } pfc::string8 buf; t_uint32 size; p_filehint->seek(0, p_abort); p_filehint->read_string_ex(buf, 4, p_abort); // chunkname: RIFF if (!!pfc::strcmp_ex(buf, 4, "RIFF", 4)) return false; p_filehint->read_lendian_t(size, p_abort); // chunksize p_filehint->read_string_ex(buf, 4, p_abort); // filetype: WAVE while (!p_filehint->is_eof(p_abort)) { p_filehint->read_string_ex(buf, 4, p_abort); // chunkname p_filehint->read_lendian_t(size, p_abort); // chunksize if (!!pfc::strcmp_ex(buf, 4, "smpl", 4)) { p_filehint->skip(size, p_abort); continue; } stream_reader_limited_ref chunk_reader(p_filehint.get_ptr(), size); // chunk found; /* UnsignedInt('manufacturer'), UnsignedInt('product'), UnsignedInt('sample_period'), UnsignedInt('midi_unity_note'), UnsignedInt('midi_pitch_fraction'), UnsignedInt('smpte_format'), UnsignedInt('smpte_offset'), UnsignedInt('num_sample_loops'), UnsignedInt('sampler_data'), */ t_uint32 i; chunk_reader.skip(4 * 7, p_abort); chunk_reader.read_lendian_t(i, p_abort); chunk_reader.skip(4, p_abort); // sampler_data for (; i>0; i--) { /* UnsignedInt('cue_point_id'), UnsignedInt('type'), UnsignedInt('start'), UnsignedInt('end'), UnsignedInt('fraction'), UnsignedInt('playcount'), */ loop_event_point_simple * point = new service_impl_t<loop_event_point_simple>(); t_uint32 temp; chunk_reader.read_lendian_t(temp, p_abort); // cue_point_id: ignore chunk_reader.read_lendian_t(temp, p_abort); // type: currently known: 0 only if (temp != 0) { pfc::string8 errmsg; errmsg << "Unknown sampleloop type: " << temp; throw exception_io_data(errmsg); } chunk_reader.read_lendian_t(temp, p_abort); // start point->to = temp; chunk_reader.read_lendian_t(temp, p_abort); // end point->from = temp; chunk_reader.read_lendian_t(temp, p_abort); // fraction if (temp != 0) { pfc::string8 errmsg; errmsg << "Unknown sampleloop fraction: " << temp; throw exception_io_data(errmsg); } chunk_reader.read_lendian_t(temp, p_abort); // playcount point->maxrepeats = temp; m_points.add_item(point); } } if (m_points.get_count() == 0) return false; try { open_path_helper(m_input, p_filehint, path, p_abort, p_from_redirect,p_skip_hints); } catch (exception_io_not_found) { return false; } switch_input(m_input, path); switch_points(m_points); return true; }
static void parse_id666( service_ptr_t< file > & p_file, LPID666TAG lpTag, bool aligned, abort_callback & p_abort ) { while ( ! p_file->is_eof( p_abort ) ) { t_uint8 id, type; t_uint16 data; p_file->read_object_t( id, p_abort ); p_file->read_object_t( type, p_abort ); p_file->read_lendian_t( data, p_abort ); switch ( type ) { case XTYPE_STR: { if ( data < 1 || data > 256 ) throw exception_io_data(); switch ( id ) { case XID_SONG: p_file->read_object( lpTag->szTitle, data, p_abort ); break; case XID_GAME: p_file->read_object( lpTag->szGame, data, p_abort ); break; case XID_ARTIST: p_file->read_object( lpTag->szArtist, data, p_abort ); break; case XID_PUB: p_file->read_object( lpTag->szPublisher, data, p_abort ); break; case XID_OST: p_file->read_object( lpTag->szOST, data, p_abort ); break; case XID_DUMPER: p_file->read_object( lpTag->szDumper, data, p_abort ); break; case XID_CMNTS: p_file->read_object( lpTag->szComment, data, p_abort ); break; default: p_file->skip( data, p_abort ); break; } if ( aligned && ( data & 3 ) ) p_file->skip( 4 - ( data & 3 ), p_abort ); } break; case XTYPE_INT: { if ( data != 4 ) throw exception_io_data(); t_uint32 value; p_file->read_lendian_t( value, p_abort ); switch ( id ) { case XID_DATE: SetDate( lpTag->szDate, ( value >> 16 ) & 255, ( value >> 8 ) & 255, value & 255 ); break; case XID_INTRO: if ( value > 383999999 ) value = 383999999; lpTag->uSong_ms = value / 64; break; case XID_LOOP: if ( value > 383999999 ) value = 383999999; lpTag->uLoop_ms = value / 64; break; case XID_END: if ( value > 383999999 ) value = 383999999; lpTag->uEnd_ms = value / 64; break; case XID_FADE: if ( value > 3839999 ) value = 3839999; lpTag->uFade_ms = value / 64; break; case XID_AMP: if ( value < 32768 ) value = 32768; else if ( value > 524288 ) value = 524288; lpTag->uAmplification = value; break; } } break; case XTYPE_DATA: { switch ( id ) { case XID_EMU: lpTag->bEmulator = t_uint8( data ); break; case XID_DISC: lpTag->bDisc = t_uint8( data ); if ( lpTag->bDisc > 9 ) lpTag->bDisc = 9; break; case XID_TRACK: if ( data > ( ( 100 << 8 ) - 1 ) ) data = 0; lpTag->wTrack = data; break; case XID_COPY: lpTag->wCopyright = data; break; case XID_MUTE: lpTag->bMute = t_uint8( data ); break; case XID_LOOPX: if ( data < 1 ) data = 1; else if ( data > 9 ) data = 9; lpTag->uLoopCount = data; break; case XID_AMP: lpTag->uAmplification = data; lpTag->uAmplification <<= 12; if ( lpTag->uAmplification < 32768 ) lpTag->uAmplification = 32768; else if ( lpTag->uAmplification > 524288 ) lpTag->uAmplification = 524288; break; } } break; } } }
write_xid6( service_ptr_t<file> & p_file, const file_info & p_info, abort_callback & p_abort ) : m_file( p_file ), m_abort( p_abort ) { pfc::stringcvt::string_ansi_from_utf8 converter; t_filesize offset_tag_start; const char * value; t_uint32 int32 = 0; p_file->seek_ex( 0, file::seek_from_eof, p_abort ); p_file->write_object( xid6_signature, 4, p_abort ); p_file->write_object_t( int32, p_abort ); offset_tag_start = p_file->get_position( p_abort ); value = p_info.meta_get( "title", 0 ); if ( value ) { converter.convert( value ); if ( strlen( converter ) > 32 ) write_string( XID_SONG, converter ); } value = p_info.meta_get( "album", 0 ); if ( value ) { converter.convert( value ); if ( strlen( converter ) > 32 ) write_string( XID_GAME, converter ); } value = p_info.meta_get( "artist", 0 ); if ( value ) { converter.convert( value ); if ( strlen( converter ) > 32 ) write_string( XID_ARTIST, converter ); } value = p_info.meta_get( "dumper", 0 ); if ( value ) { converter.convert( value ); if ( strlen( converter ) > 16 ) write_string( XID_DUMPER, converter ); } value = p_info.meta_get( "comment", 0 ); if ( value ) { converter.convert( value ); if ( strlen( converter ) > 32 ) write_string( XID_CMNTS, converter ); } value = p_info.meta_get( "OST", 0 ); if ( value ) { converter.convert( value ); write_string( XID_OST, converter ); } value = p_info.meta_get( "discnumber", 0 ); if ( value ) { char * end; unsigned disc = strtoul( value, &end, 10 ); if ( !*end && disc > 0 && disc <= 9 ) write_data( XID_DISC, disc ); } value = p_info.meta_get( "tracknumber", 0 ); if ( value ) { char * end; unsigned track = strtoul( value, &end, 10 ); if ( track > 0 && track < 100 ) write_data( XID_TRACK, track * 0x100 + *end ); } value = p_info.meta_get( "copyright", 0 ); if ( value ) { char * end; unsigned copyright_year = strtoul( value, &end, 10 ); if ( copyright_year > 0 && copyright_year < 65536 ) write_data( XID_COPY, copyright_year ); while ( *end && *end == ' ' ) end++; if ( *end ) { converter.convert( end ); write_string( XID_PUB, converter ); } } value = p_info.info_get( field_length ); if ( value ) { char * end; unsigned length = strtoul( value, &end, 10 ); if ( !*end && length > 0 && ( length % 1000 || length > 999000 ) ) write_int( XID_INTRO, length * 64 ); } value = p_info.info_get( field_fade ); if ( value ) { char * end; unsigned fade = strtoul( value, &end, 10 ); if ( !*end && fade > 99999 ) write_int( XID_FADE, fade * 64 ); } t_filesize offset = p_file->get_position( p_abort ); offset -= offset_tag_start; if ( offset > ( 1 << 30 ) ) throw exception_io_data(); if ( offset ) { int32 = t_uint32( offset ); p_file->seek( offset_tag_start - 4, p_abort ); p_file->write_lendian_t( int32, p_abort ); } else { p_file->seek( offset_tag_start - 8, p_abort ); p_file->set_eof( p_abort ); } }
void check_is_our_type (const char *path) { if (pfc::stricmp_ascii (pfc::string_extension (path), _7Z_EXT) != 0) throw exception_io_data (); }