void writeOverlappedPass(HANDLE handle, HANDLE myEvent, t_filesize position, const void * in,DWORD inBytes, abort_callback & abort) { abort.check(); if (inBytes == 0) return; OVERLAPPED ol = {}; fillOverlapped(ol, myEvent, position); ResetEvent(myEvent); DWORD bytesWritten; SetLastError(NO_ERROR); if (WriteFile( handle, in, inBytes, &bytesWritten, &ol)) { // succeeded already? if (bytesWritten != inBytes) throw exception_io(); return; } { const DWORD code = GetLastError(); if (code != ERROR_IO_PENDING) exception_io_from_win32(code); } const HANDLE handles[] = {myEvent, abort.get_abort_event()}; SetLastError(NO_ERROR); DWORD state = WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE); if (state == WAIT_OBJECT_0) { try { WIN32_IO_OP( GetOverlappedResult(handle,&ol,&bytesWritten,TRUE) ); } catch(...) { CancelIo(handle); throw; } if (bytesWritten != inBytes) throw exception_io(); return; } CancelIo(handle); throw exception_aborted(); }
void run(threaded_process_status & p_status,abort_callback & p_abort) { try { const t_uint32 decode_flags = input_flag_no_seeking | input_flag_no_looping; // tell the decoders that we won't seek and that we don't want looping on formats that support looping. input_helper input; audio_hash.set_count(m_items.get_size()); for(t_size walk = 0; walk < m_items.get_size(); ++walk) { p_abort.check(); // in case the input we're working with fails at doing this p_status.set_progress(walk, m_items.get_size()); p_status.set_progress_secondary(0); p_status.set_item_path( m_items[walk]->get_path() ); input.open(NULL, m_items[walk], decode_flags, p_abort); double length; { // fetch the track length for proper dual progress display; file_info_impl info; // input.open should have preloaded relevant info, no need to query the input itself again. // Regular get_info() may not retrieve freshly loaded info yet at this point (it will start giving the new info when relevant info change callbacks are dispatched); we need to use get_info_async. if (m_items[walk]->get_info_async(info)) length = info.get_length(); else length = 0; } memset( &ctx, 0, sizeof( sha1_context ) ); sha1_starts( &ctx ); audio_chunk_impl_temporary l_chunk; double decoded = 0; while(input.run(l_chunk, p_abort)) { // main decode loop sha1_update(&ctx,(unsigned char*)l_chunk.get_data(),l_chunk.get_data_length()); //m_peak = l_chunk.get_peak(m_peak); if (length > 0) { // don't bother for unknown length tracks decoded += l_chunk.get_duration(); if (decoded > length) decoded = length; p_status.set_progress_secondary_float(decoded / length); } p_abort.check(); // in case the input we're working with fails at doing this } unsigned char sha1sum[20] ={0}; sha1_finish(&ctx,sha1sum); pfc::string_formatter msg; for(int i = 0; i < 20; i++ ) { msg <<pfc::format_hex(sha1sum[i]); audio_hash[walk] =msg; } } } catch(std::exception const & e) { m_failMsg = e.what(); } }
void CMutex::AcquireByHandle( HANDLE hMutex, abort_callback & aborter ) { SetLastError(0); HANDLE hWait[2] = {hMutex, aborter.get_abort_event()}; switch(WaitForMultipleObjects( 2, hWait, FALSE, INFINITE ) ) { case WAIT_FAILED: WIN32_OP_FAIL_CRITICAL("WaitForSingleObject"); case WAIT_OBJECT_0: return; case WAIT_OBJECT_0 + 1: PFC_ASSERT( aborter.is_aborting() ); throw exception_aborted(); default: uBugCheck(); } }
t_size MultiWaitAbortable_MsgLoop(const HANDLE * ev, t_size evCount, abort_callback & abort) { pfc::array_t<HANDLE> handles; handles.set_size(evCount + 1); handles[0] = abort.get_abort_event(); pfc::memcpy_t(handles.get_ptr() + 1, ev, evCount); for(;;) { SetLastError(0); const DWORD status = MsgWaitForMultipleObjects(handles.get_count(), handles.get_ptr(), FALSE, INFINITE, QS_ALLINPUT); switch(status) { case WAIT_TIMEOUT: PFC_ASSERT(!"How did we get here?"); uBugCheck(); case WAIT_OBJECT_0: throw exception_aborted(); case WAIT_FAILED: WIN32_OP_FAIL(); default: { t_size index = (t_size)(status - (WAIT_OBJECT_0 + 1)); if (index == evCount) { ProcessPendingMessages(); } else if (index < evCount) { return index; } else { uBugCheck(); } } } } }
bool input_helper::open_path(file::ptr p_filehint,const char * path,abort_callback & p_abort,bool p_from_redirect,bool p_skip_hints) { p_abort.check(); if (!need_file_reopen(path)) return false; m_input.release(); service_ptr_t<file> l_file = p_filehint; process_fullbuffer(l_file,path,m_fullbuffer,p_abort); TRACK_CODE("input_entry::g_open_for_decoding", input_entry::g_open_for_decoding(m_input,l_file,path,p_abort,p_from_redirect) ); if (!p_skip_hints) { try { static_api_ptr_t<metadb_io>()->hint_reader(m_input.get_ptr(),path,p_abort); } catch(exception_io_data) { //Don't fail to decode when this barfs, might be barfing when reading info from another subsong than the one we're trying to decode etc. m_input.release(); if (l_file.is_valid()) l_file->reopen(p_abort); TRACK_CODE("input_entry::g_open_for_decoding", input_entry::g_open_for_decoding(m_input,l_file,path,p_abort,p_from_redirect) ); } } m_path = path; return true; }
void input_helper::open(service_ptr_t<file> p_filehint,const playable_location & p_location,unsigned p_flags,abort_callback & p_abort,bool p_from_redirect,bool p_skip_hints) { p_abort.check(); if (m_input.is_empty() || metadb::path_compare(p_location.get_path(),m_path) != 0) { m_input.release(); service_ptr_t<file> l_file = p_filehint; process_fullbuffer(l_file,p_location.get_path(),m_fullbuffer,p_abort); TRACK_CODE("input_entry::g_open_for_decoding", input_entry::g_open_for_decoding(m_input,l_file,p_location.get_path(),p_abort,p_from_redirect) ); if (!p_skip_hints) { try { static_api_ptr_t<metadb_io>()->hint_reader(m_input.get_ptr(),p_location.get_path(),p_abort); } catch(exception_io_data) { //don't fail to decode when this barfs m_input.release(); if (l_file.is_valid()) l_file->reopen(p_abort); TRACK_CODE("input_entry::g_open_for_decoding", input_entry::g_open_for_decoding(m_input,l_file,p_location.get_path(),p_abort,p_from_redirect) ); } } m_path = p_location.get_path(); } TRACK_CODE("input_decoder::initialize",m_input->initialize(p_location.get_subsong_index(),p_flags,p_abort)); }
void stream_writer_buffered::write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) { p_abort.check_e(); const char * source = (const char*)p_buffer; t_size source_remaining = p_bytes; const t_size buffer_size = m_buffer.get_size(); if (source_remaining >= buffer_size) { flush(p_abort); m_base->write_object(source,source_remaining,p_abort); return; } if (m_buffer_ptr + source_remaining >= buffer_size) { t_size delta = buffer_size - m_buffer_ptr; memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,delta); source += delta; source_remaining -= delta; m_buffer_ptr += delta; flush(p_abort); } memcpy(m_buffer.get_ptr() + m_buffer_ptr, source,source_remaining); m_buffer_ptr += source_remaining; }
void seekabilizer::seek(t_filesize p_position,abort_callback & p_abort) { assert(m_position_base >= m_buffer.get_depth()); p_abort.check_e(); if (m_size != filesize_invalid && p_position > m_size) throw exception_io_seek_out_of_range(); t_filesize lowest = m_position_base - m_buffer.get_depth(); if (p_position < lowest) { if (m_file->can_seek()) { m_buffer.reset(); t_filesize target = p_position; t_size delta = m_buffer.get_max_depth(); if (delta > backread_on_seek) delta = backread_on_seek; if (target > delta) target -= delta; else target = 0; m_file->seek(target,p_abort); m_position_base = target; } else { m_buffer.reset(); m_file->reopen(p_abort); m_position_base = 0; } } m_position = p_position; }
bool WaitAbortable_MsgLoop(HANDLE ev, abort_callback & abort, DWORD timeout /*must not be INFINITE*/) { PFC_ASSERT( timeout != INFINITE ); const DWORD entry = GetTickCount(); const HANDLE handles[2] = {ev, abort.get_abort_event()}; for(;;) { const DWORD done = GetTickCount() - entry; if (done >= timeout) return false; SetLastError(0); const DWORD status = MsgWaitForMultipleObjects(2, handles, FALSE, timeout - done, QS_ALLINPUT); switch(status) { case WAIT_TIMEOUT: return false; case WAIT_OBJECT_0: return true; case WAIT_OBJECT_0 + 1: throw exception_aborted(); case WAIT_OBJECT_0 + 2: ProcessPendingMessages(); break; case WAIT_FAILED: WIN32_OP_FAIL(); default: uBugCheck(); } } }
pfc::list_t<metadb_handle_ptr> get_sorted_playlist(const pfc::list_base_const_t<metadb_handle_ptr> &data, threaded_process_status &p_status, abort_callback &p_abort) { std::multimap<int, metadb_handle_ptr, std::greater<int>> temp; std::multimap<int, metadb_handle_ptr, std::greater<int>>::iterator it; pfc::list_t<metadb_handle_ptr> result; pfc::lores_timer timer; pfc::string8 message, msg; int size = data.get_count(); for (int i = 0; i < size; i++) { message.reset(); message << "Track " << i + 1 << " of " << size; p_status.set_item(message); p_status.set_progress(i + 1, size); timer.start(); const metadb_handle_ptr track = data[i]; int count = get_track_count(track, p_abort); msg.reset(); msg << count; console::print(msg); // don't make more than 5 requests per second // (averaged over a 5 minute period) if (timer.query() < 0.2) { p_abort.sleep(0.2); } if (i && (i % 100 == 0)) { p_abort.sleep(10); } if (count > 0) { temp.insert(std::pair<int, metadb_handle_ptr>(count, track)); } else { temp.insert(std::pair<int, metadb_handle_ptr>(0, track)); } } for (it = temp.begin(); it != temp.end(); it++) { metadb_handle_ptr track = it->second; result.add_item(track); } return result; }
HANDLE createFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile, abort_callback & abort) { abort.check(); return CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); // CancelSynchronousIo() doesn't f*****g work. Useless. #if 0 pCancelSynchronousIo_t pCancelSynchronousIo = (pCancelSynchronousIo_t) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "CancelSynchronousIo"); if (pCancelSynchronousIo == NULL) { #ifdef _DEBUG uDebugLog() << "Async CreateFile unavailable - using regular"; #endif return CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); } else { #ifdef _DEBUG uDebugLog() << "Starting async CreateFile..."; pfc::hires_timer t; t.start(); #endif createFileData_t data = {lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, NULL, 0}; HANDLE hThread = (HANDLE) _beginthreadex(NULL, 0, createFileProc, &data, 0, NULL); HANDLE waitHandles[2] = {hThread, abort.get_abort_event()}; switch(WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE)) { case WAIT_OBJECT_0: // succeeded break; case WAIT_OBJECT_0 + 1: // abort #ifdef _DEBUG uDebugLog() << "Aborting async CreateFile..."; #endif pCancelSynchronousIo(hThread); WaitForSingleObject(hThread, INFINITE); break; default: uBugCheck(); } CloseHandle(hThread); SetLastError(data.dwErrorCode); #ifdef _DEBUG uDebugLog() << "Async CreateFile completed in " << pfc::format_time_ex(t.query(), 6) << ", status: " << (uint32_t) data.dwErrorCode; #endif if (abort.is_aborting()) { if (data.hResult != INVALID_HANDLE_VALUE) CloseHandle(data.hResult); throw exception_aborted(); } return data.hResult; } #endif }
DWORD readOverlappedPass(HANDLE handle, HANDLE myEvent, t_filesize position, void * out, DWORD outBytes, abort_callback & abort) { abort.check(); if (outBytes == 0) return 0; OVERLAPPED ol = {}; fillOverlapped(ol, myEvent, position); ResetEvent(myEvent); DWORD bytesDone; SetLastError(NO_ERROR); if (ReadFile( handle, out, outBytes, &bytesDone, &ol)) { // succeeded already? return bytesDone; } { const DWORD code = GetLastError(); switch(code) { case ERROR_HANDLE_EOF: case ERROR_BROKEN_PIPE: return 0; case ERROR_IO_PENDING: break; // continue default: exception_io_from_win32(code); }; } const HANDLE handles[] = {myEvent, abort.get_abort_event()}; SetLastError(NO_ERROR); DWORD state = WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE); if (state == WAIT_OBJECT_0) { SetLastError(NO_ERROR); if (!GetOverlappedResult(handle,&ol,&bytesDone,TRUE)) { const DWORD code = GetLastError(); if (code == ERROR_HANDLE_EOF || code == ERROR_BROKEN_PIPE) bytesDone = 0; else { CancelIo(handle); exception_io_from_win32(code); } } return bytesDone; } CancelIo(handle); throw exception_aborted(); }
t_size seekabilizer::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) { p_abort.check_e(); if (m_position > m_position_base + pfc::max_t<t_size>(m_buffer.get_max_depth(),backread_on_seek) && m_file->can_seek()) { m_buffer.reset(); t_filesize target = m_position; if (target < backread_on_seek) target = 0; else target -= backread_on_seek; m_file->seek(target,p_abort); m_position_base = target; } //seek ahead while(m_position > m_position_base) { enum {tempsize = 1024}; t_uint8 temp[tempsize]; t_size delta = (t_size) pfc::min_t<t_filesize>(tempsize,m_position - m_position_base); t_size bytes_read = 0; bytes_read = m_file->read(temp,delta,p_abort); m_buffer.write(temp,bytes_read); m_position_base += bytes_read; if (bytes_read < delta) { return 0; } } t_size done = 0; t_uint8 * targetptr = (t_uint8*) p_buffer; //try to read backbuffer if (m_position < m_position_base) { if (m_position_base - m_position > (t_filesize)m_buffer.get_depth()) throw exception_io_seek_out_of_range(); t_size backread_depth = (t_size) (m_position_base - m_position); t_size delta = pfc::min_t<t_size>(backread_depth,p_bytes-done); m_buffer.read(backread_depth,targetptr,delta); done += delta; m_position += delta; } //regular read if (done < p_bytes) { t_size bytes_read; bytes_read = m_file->read(targetptr+done,p_bytes-done,p_abort); m_buffer.write(targetptr+done,bytes_read); done += bytes_read; m_position += bytes_read; m_position_base += bytes_read; } return done; }
t_size reader_membuffer_base::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) { p_abort.check_e(); t_size max = get_buffer_size(); if (max < m_offset) uBugCheck(); max -= m_offset; t_size delta = p_bytes; if (delta > max) delta = max; memcpy(p_buffer,(char*)get_buffer() + m_offset,delta); m_offset += delta; return delta; }
mutexScope::mutexScope(HANDLE hMutex_, abort_callback & abort) : hMutex(hMutex_) { HANDLE h[2] = {hMutex, abort.get_abort_event()}; switch( WaitForMultipleObjects(2, h, FALSE, INFINITE) ) { case WAIT_OBJECT_0: break; // and enter case WAIT_OBJECT_0+1: throw exception_aborted(); default: uBugCheck(); } }
void input_entry::g_open_for_info_write_timeout(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,double p_timeout,bool p_from_redirect) { pfc::lores_timer timer; timer.start(); for(;;) { try { g_open_for_info_write(p_instance,p_filehint,p_path,p_abort,p_from_redirect); break; } catch(exception_io_sharing_violation) { if (timer.query() > p_timeout) throw; p_abort.sleep(0.01); } } }
bool directory_callback_impl::on_entry(filesystem * owner,abort_callback & p_abort,const char * url,bool is_subdirectory,const t_filestats & p_stats) { p_abort.check_e(); if (is_subdirectory) { if (m_recur) { try { owner->list_directory(url,*this,p_abort); } catch(exception_io const &) {} } } else { m_data.add_item(pfc::rcnew_t<t_entry>(url,p_stats)); } return true; }
void stream_reader_chunk::flush(abort_callback & p_abort) { while(!m_eof) { p_abort.check_e(); t_uint8 temp; m_reader->read_lendian_t(temp,p_abort); m_buffer_size = temp; if (temp != sizeof(m_buffer)) m_eof = true; m_buffer_state = 0; if (m_buffer_size>0) { m_reader->skip_object(m_buffer_size,p_abort); } } }
t_filesize file::g_transfer(stream_reader * p_src,stream_writer * p_dst,t_filesize p_bytes,abort_callback & p_abort) { enum {BUFSIZE = 1024*1024*8}; pfc::array_t<t_uint8> temp; temp.set_size((t_size)pfc::min_t<t_filesize>(BUFSIZE,p_bytes)); void* ptr = temp.get_ptr(); t_filesize done = 0; while(done<p_bytes) { p_abort.check_e(); t_size delta = (t_size)pfc::min_t<t_filesize>(BUFSIZE,p_bytes-done); delta = p_src->read(ptr,delta,p_abort); if (delta<=0) break; p_dst->write(ptr,delta,p_abort); done += delta; } return done; }
static void index_tracks_helper(const char * p_path,const service_ptr_t<file> & p_reader,const t_filestats & p_stats,playlist_loader_callback::t_entry_type p_type,playlist_loader_callback::ptr p_callback, abort_callback & p_abort,bool & p_got_input) { TRACK_CALL_TEXT("index_tracks_helper"); if (p_reader.is_empty() && filesystem::g_is_remote_safe(p_path)) { TRACK_CALL_TEXT("remote"); metadb_handle_ptr handle; p_callback->handle_create(handle,make_playable_location(p_path,0)); p_got_input = true; p_callback->on_entry(handle,p_type,p_stats,true); } else { TRACK_CALL_TEXT("hintable"); service_ptr_t<input_info_reader> instance; input_entry::g_open_for_info_read(instance,p_reader,p_path,p_abort); t_filestats stats = instance->get_file_stats(p_abort); t_uint32 subsong,subsong_count = instance->get_subsong_count(); bool bInfoGetError = false; for(subsong=0;subsong<subsong_count;subsong++) { TRACK_CALL_TEXT("subsong-loop"); p_abort.check(); metadb_handle_ptr handle; t_uint32 index = instance->get_subsong(subsong); p_callback->handle_create(handle,make_playable_location(p_path,index)); p_got_input = true; if (! bInfoGetError && p_callback->want_info(handle,p_type,stats,true) ) { file_info_impl info; try { TRACK_CODE("get_info",instance->get_info(index,info,p_abort)); } catch(std::exception const & e) { bInfoGetError = true; } p_callback->on_entry_info(handle,p_type,stats,info,true); } else { p_callback->on_entry(handle,p_type,stats,true); } } } }
bool WaitAbortable(HANDLE ev, abort_callback & abort, DWORD timeout) { const HANDLE handles[2] = {ev, abort.get_abort_event()}; SetLastError(0); const DWORD status = WaitForMultipleObjects(2, handles, FALSE, timeout); switch(status) { case WAIT_TIMEOUT: PFC_ASSERT( timeout != INFINITE ); return false; case WAIT_OBJECT_0: return true; case WAIT_OBJECT_0 + 1: throw exception_aborted(); case WAIT_FAILED: WIN32_OP_FAIL(); default: uBugCheck(); } }
void SleepAbortable_MsgLoop(abort_callback & abort, DWORD timeout /*must not be INFINITE*/) { PFC_ASSERT( timeout != INFINITE ); const DWORD entry = GetTickCount(); const HANDLE handles[1] = {abort.get_abort_event()}; for(;;) { const DWORD done = GetTickCount() - entry; if (done >= timeout) return; SetLastError(0); const DWORD status = MsgWaitForMultipleObjects(1, handles, FALSE, timeout - done, QS_ALLINPUT); switch(status) { case WAIT_TIMEOUT: return; case WAIT_OBJECT_0: throw exception_aborted(); case WAIT_OBJECT_0 + 1: ProcessPendingMessages(); default: throw exception_win32(GetLastError()); } } }
static bool grab_items_by_path(pfc::list_base_t<metadb_handle_ptr> & p_out,const char * p_path,abort_callback & p_abort) { try { pfc::string8 path; filesystem::g_get_canonical_path(p_path,path); p_out.remove_all(); service_ptr_t<input_info_reader> reader; input_entry::g_open_for_info_read(reader,0,path,p_abort); static_api_ptr_t<metadb> l_metadb; const t_uint32 count = reader->get_subsong_count(); for(t_uint32 n=0;n<count;n++) { p_abort.check_e(); metadb_handle_ptr ptr; l_metadb->handle_create(ptr,make_playable_location(path,reader->get_subsong(n))); p_out.add_item(ptr); } return p_out.get_count() > 0; } catch(std::exception const &) {return false;} }
void open_path_helper(input_decoder::ptr & p_input, file::ptr p_file, const char * path,abort_callback & p_abort,bool p_from_redirect,bool p_skip_hints) { p_abort.check(); p_input.release(); TRACK_CODE("input_entry::g_open_for_decoding", input_entry::g_open_for_decoding(p_input,p_file,path,p_abort,p_from_redirect) ); if (!p_skip_hints) { try { static_api_ptr_t<metadb_io>()->hint_reader(p_input.get_ptr(),path,p_abort); } catch(exception_io_data) { //Don't fail to decode when this barfs, might be barfing when reading info from another subsong than the one we're trying to decode etc. p_input.release(); if (p_file.is_valid()) p_file->reopen(p_abort); TRACK_CODE("input_entry::g_open_for_decoding", input_entry::g_open_for_decoding(p_input,p_file,path,p_abort,p_from_redirect) ); } } }
t_size stream_reader_buffered::read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) { if (p_bytes <= m_bufferRemaining) { memcpy( p_buffer, m_bufferPtr, p_bytes ); m_bufferRemaining -= p_bytes; m_bufferPtr += p_bytes; return p_bytes; } p_abort.check(); char * output = (char*) p_buffer; t_size output_ptr = 0; while(output_ptr < p_bytes) { { t_size delta = pfc::min_t(p_bytes - output_ptr, m_bufferRemaining); if (delta > 0) { memcpy(output + output_ptr, m_bufferPtr, delta); output_ptr += delta; m_bufferPtr += delta; m_bufferRemaining -= delta; } } if (m_bufferRemaining == 0) { t_size bytes_read; bytes_read = m_base->read(m_buffer.get_ptr(), m_buffer.get_size(), p_abort); m_bufferPtr = m_buffer.get_ptr(); m_bufferRemaining = bytes_read; if (m_bufferRemaining == 0) break; } } return output_ptr; }
void WaitAbortable_MsgLoop(HANDLE ev, abort_callback & abort) { const HANDLE handles[2] = {ev, abort.get_abort_event()}; for(;;) { SetLastError(0); const DWORD status = MsgWaitForMultipleObjects(2, handles, FALSE, INFINITE, QS_ALLINPUT); switch(status) { case WAIT_TIMEOUT: PFC_ASSERT(!"How did we get here?"); uBugCheck(); case WAIT_OBJECT_0: return; case WAIT_OBJECT_0 + 1: throw exception_aborted(); case WAIT_OBJECT_0 + 2: ProcessPendingMessages(); break; case WAIT_FAILED: WIN32_OP_FAIL(); default: uBugCheck(); } } }
static void track_indexer__g_get_tracks_wrap(const char * p_path,const service_ptr_t<file> & p_reader,const t_filestats & p_stats,playlist_loader_callback::t_entry_type p_type,playlist_loader_callback::ptr p_callback, abort_callback & p_abort) { bool got_input = false; bool fail = false; try { index_tracks_helper(p_path,p_reader,p_stats,p_type,p_callback,p_abort, got_input); } catch(exception_aborted) { throw; } catch(exception_io_unsupported_format) { fail = true; } catch(std::exception const & e) { fail = true; console::formatter() << "could not enumerate tracks (" << e << ") on:\n" << file_path_display(p_path); } if (fail) { if (!got_input && !p_abort.is_aborting()) { if (p_type == playlist_loader_callback::entry_user_requested) { metadb_handle_ptr handle; p_callback->handle_create(handle,make_playable_location(p_path,0)); p_callback->on_entry(handle,p_type,p_stats,true); } } } }
void reader_membuffer_base::seek(t_filesize position,abort_callback & p_abort) { p_abort.check_e(); t_filesize max = get_buffer_size(); if (position == filesize_invalid || position > max) throw exception_io_seek_out_of_range(); m_offset = (t_size)position; }
void load_database_t::load_cache(HWND wnd, ipod_device_ptr_ref_t p_ipod, bool b_CheckIfFilesChanged, threaded_process_v2_t & p_status, abort_callback & p_abort) { pfc::string8 base; p_ipod->get_root_path(base); metadb_handle_list handlestoread(m_handles); pfc::string8 cachePath = base; cachePath << "metadata_cache.fpl"; //We want to hint from main thread to avoid annoyances static_api_ptr_t<main_thread_callback_manager> p_main_thread; p_status.update_text("Loading metadata cache"); service_ptr_t<t_main_thread_load_cache_v2_t> p_cache_loader = new service_impl_t<t_main_thread_load_cache_v2_t> (base); p_cache_loader->callback_run(); //p_main_thread->add_callback(p_cache_loader); if (!p_cache_loader->m_signal.wait_for(-1)) throw pfc::exception("Cache read timeout!"); if (!p_cache_loader->m_ret) throw pfc::exception(pfc::string8() << "Error reading metadata cache: " << p_cache_loader->m_error); p_status.update_text("Checking files for changes"); //pfc::hires_timer timer2; //timer2.start(); t_size n = handlestoread.get_count(), count = n; for (; n; n--) { if (p_ipod->mobile || !b_CheckIfFilesChanged) { if (handlestoread[n - 1]->is_info_loaded_async()) handlestoread.remove_by_idx(n - 1); m_tracks[n - 1]->m_runtime_filestats.m_timestamp = filetimestamp_invalid; if (m_tracks[n - 1]->original_timestamp_valid) m_tracks[n - 1]->m_runtime_filestats.m_timestamp = m_tracks[n - 1]->original_timestamp; else if (m_tracks[n - 1]->lastmodifiedtime) m_tracks[n - 1]->m_runtime_filestats.m_timestamp = filetime_time_from_appletime(m_tracks[n - 1]->lastmodifiedtime); m_tracks[n - 1]->m_runtime_filestats.m_size = m_tracks[n - 1]->size; } else { if (true) { if (n % 20 == 0) p_abort.check(); t_filestats stats = handlestoread[n - 1]->get_filestats(); const char * path = handlestoread[n - 1]->get_path(); if (!stricmp_utf8_max(path, "file://", 7)) { path += 7; win32::handle_ptr_t p_file = CreateFile(pfc::stringcvt::string_os_from_utf8(path), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (p_file.is_valid()) { t_filestats newstats = filestats_invalid; GetFileSizeEx(p_file, (PLARGE_INTEGER)&newstats.m_size); GetFileTime(p_file, NULL, NULL, (LPFILETIME)&newstats.m_timestamp); m_tracks[n - 1]->m_runtime_filestats = newstats; if (handlestoread[n - 1]->is_info_loaded_async()) { t_uint64 hour = 60 * 60; hour *= 10000000; if (stats.m_size == newstats.m_size && (stats.m_timestamp == newstats.m_timestamp || _abs64(newstats.m_timestamp - stats.m_timestamp) == hour) && newstats.m_size != filesize_invalid && newstats.m_timestamp != filetimestamp_invalid) handlestoread.remove_by_idx(n - 1); } } } } } p_status.update_progress_subpart_helper(count - n + 1, count); } //console::formatter() << "info checked in: " << pfc::format_time_ex(timer2.query(),6); if (handlestoread.get_count()) { p_status.update_text("Loading file info"); //static_api_ptr_t<main_thread_callback_manager> p_main_thread; service_ptr_t<t_main_thread_scan_file_info> p_info_loader = new service_impl_t<t_main_thread_scan_file_info> (handlestoread, metadb_io::load_info_force, wnd); p_main_thread->add_callback(p_info_loader); if (!p_info_loader->m_signal.wait_for(-1)) throw pfc::exception("File info reading timeout!"); if (p_info_loader->m_ret == metadb_io::load_info_aborted) throw pfc::exception("File info read was aborted"); } p_abort.check(); }
/** Does /not/ throw exception_io_data, unlike normal */ pfc::string8 SpotifySession::waitForLogin(abort_callback & p_abort) { while (WAIT_OBJECT_0 != WaitForSingleObject(loggedInEvent, 200)) if (p_abort.is_aborting()) return "user aborted"; return loginResult; }