//! This function enters in a the selected directory //! //! @param b_direction direction of navigation (FS_FIND_NEXT or FS_FIND_PREV) //! //! @return The state of the function //! static navauto_mov_explorer_rec_t navauto_mov_explorer_enterdir(bool b_direction) { bool b_enterdir_ok; // Enter in this new directory #if defined(NAVAUTO_SPEED_OPTIMIZATION) && NAVAUTO_SPEED_OPTIMIZATION == true i_navauto_cache++; if (i_navauto_cache < NAVAUTO_SPEED_OPTIMIZATION_LEVEL) { // navauto_cache[i_navauto_cache].u32_cluster = fs_g_nav.u32_cluster_sel_dir; navauto_cache[i_navauto_cache].u16_pos_file = fs_g_nav.u16_pos_sel_file; navauto_cache[i_navauto_cache].u16_entry_pos_file = fs_g_nav_fast.u16_entry_pos_sel_file; } b_enterdir_ok = nav_dir_cd(); #else b_enterdir_ok = nav_dir_cd(); #endif // In case of error if (!b_enterdir_ok) return NAVAUTO_MOV_EXPLORER_ERROR; // Update directory level g_navauto_u16_dir_level++; // Set folder change bit bitfield_status.folder_change = 1; return NAVAUTO_MOV_EXPLORER_RECURSIVE; }
//! Go to next file or directory in file list FLAT //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! bool nav_flat_next( void ) { uint16_t u16_save_current_pos; u16_save_current_pos = nav_filelist_get(); if( nav_file_isdir() ) { // The current file is a dir then enter in this if( !nav_dir_cd() ) return false; if( nav_filelist_set( 0 , FS_FIND_NEXT ) ) { // A file is present in this dir then valid the new position fs_g_nav.u8_flat_dir_level++; fs_g_nav.u16_flat_pos_offset += u16_save_current_pos+1; return true; }else{ // No file then return in parent dir if( !nav_dir_gotoparent() ) return false; // Error } } // Find next file in the current dir or the parent dir while( !nav_filelist_set( 0 , FS_FIND_NEXT ) ) { // End of the directory then goes to parent if( 0 == fs_g_nav.u8_flat_dir_level ) return false; // End of list FLAT if( !nav_dir_gotoparent() ) return false; // Error fs_g_nav.u8_flat_dir_level--; } fs_g_nav.u16_flat_pos_offset = (fs_g_nav.u16_flat_pos_offset +u16_save_current_pos +1) -nav_filelist_get(); return true; }
//! This function enters in the selected directory in file list FLAT //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! bool nav_flat_cd( void ) { if( !nav_dir_cd() ) return false; fs_g_nav.u8_flat_dir_level = 0; fs_g_nav.u16_flat_pos_offset = 0; return true; }
//! This function enters in the selected directory in file list FLAT //! //! @return FALSE in case of error, see global value "fs_g_status" for more detail //! @return TRUE otherwise //! Bool nav_flat_cd( void ) { if( !nav_dir_cd() ) return FALSE; fs_g_nav.u8_flat_dir_level = 0; fs_g_nav.u16_flat_pos_offset = 0; return TRUE; }
//! This function selects the first or the last directory on the current folder //! and enters in it //! //! @param b_direction direction of navigation (FS_FIND_NEXT or FS_FIND_PREV) //! //! @return The state of the function //! static navauto_mov_explorer_rec_t navauto_mov_explorer_select_limit_dir_cur_folder(bool b_direction) { if (!((b_direction == FS_FIND_NEXT)?nav_filelist_first(FS_DIR):nav_filelist_last(FS_DIR))) return NAVAUTO_MOV_EXPLORER_ERROR; // Update directory level g_navauto_u16_dir_level++; // Enter in this new directory nav_dir_cd(); // Set folder change bit bitfield_status.folder_change = 1; return NAVAUTO_MOV_EXPLORER_RECURSIVE; }
static __inline__ uint8_t navauto_mov_explorer_is_dir(bool b_direction, navauto_mov_options_t options) { bool status; // Look for the next/previous directory in the current directory if ((status = nav_filelist_set(0, b_direction))) status = nav_file_isdir(); // If status == false, it means it reached a limit if (!status) { switch(is_dir_process_fct[(b_direction == FS_FIND_NEXT)?1:0](b_direction)) { case NAVAUTO_MOV_EXPLORER_RECURSIVE: return navauto_mov_explorer_rec(b_direction, options); case NAVAUTO_MOV_EXPLORER_OK: return NAVAUTO_MOV_OK; default: break; } } else { g_navauto_u16_dir_level++; // Enter in this new directory nav_dir_cd(); // Set folder change bit bitfield_status.folder_change = 1; return navauto_mov_explorer_rec(b_direction, options); } // At this point, there is no directory available and the limit function // returns ERROR if (navauto_mov_explorer_updir(b_direction) == NAVAUTO_MOV_EXPLORER_RECURSIVE) return navauto_mov_explorer_rec(b_direction, options); return navauto_mov_ok_loop(b_direction, options); }
//! Go to previous file or directory in file list FLAT //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! bool nav_flat_previous( void ) { uint16_t u16_save_current_pos; u16_save_current_pos = nav_filelist_get(); if( nav_filelist_set( 0 , FS_FIND_PREV ) ) { while( 1 ) { if( !nav_file_isdir() ) { fs_g_nav.u16_flat_pos_offset = ((fs_g_nav.u16_flat_pos_offset +u16_save_current_pos) -nav_filelist_get()) -1; return true; // New valid position } // The selection is a dir then enter in this if( !nav_dir_cd() ) return false; if( !nav_filelist_set( 0 , FS_FIND_NEXT ) ) { // The dir is empty then goes to the parent nav_dir_gotoparent(); // The parent dir is the new selection fs_g_nav.u16_flat_pos_offset = ((fs_g_nav.u16_flat_pos_offset +u16_save_current_pos) -nav_filelist_get()) -1; return true; } fs_g_nav.u8_flat_dir_level++; // Go to the end of dir while( nav_filelist_set( 0 , FS_FIND_NEXT ) ); } } // Beginning of the directory then goes to parent directory if( 0 == fs_g_nav.u8_flat_dir_level ) return false; // beginning of the file list FLAT if( !nav_dir_gotoparent() ) return false; fs_g_nav.u8_flat_dir_level--; fs_g_nav.u16_flat_pos_offset -= (nav_filelist_get()+1); return true; }
//! This function goes to the previous position in filtered file list //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! bool nav_filterflat_previous( void ) { uint16_t u16_save_current_pos; u16_save_current_pos = nav_filterlist_get(); if( nav_filterlist_previous() ) { while( 1 ) { if( !nav_file_isdir() ) { fs_g_nav.u16_flat_pos_offset = ((fs_g_nav.u16_flat_pos_offset +u16_save_current_pos) -nav_filterlist_get()) -1; return true; // New position valid } // The file is a dir then enter in this if( !nav_dir_cd() ) return false; if( !nav_filterlist_next() ) { // Dir empty then goes to parent and dir is the new selection nav_filterlist_gotoparent(); fs_g_nav.u16_flat_pos_offset = ((fs_g_nav.u16_flat_pos_offset +u16_save_current_pos) -nav_filterlist_get()) -1; return true; } fs_g_nav.u8_flat_dir_level++; // Go to end of the dir while( nav_filterlist_next() ); } } // Beginning of current directory then goes to parent if( 0 == fs_g_nav.u8_flat_dir_level ) return false; // beginning of list FLAT if( !nav_filterlist_gotoparent() ) return false; fs_g_nav.u8_flat_dir_level--; fs_g_nav.u16_flat_pos_offset -= (nav_filterlist_get()+1); return true; }
//! @brief Synchronize a path with an other path //! //! @return true if success //! bool ushell_cmd_sync( void ) { Fs_index sav_index; uint8_t u8_folder_level = 0; if( g_s_arg[0][0] == 0 ) return false; if( g_s_arg[1][0] == 0 ) return false; // Add '\' at the end of path, else the nav_setcwd select the directory but don't enter into. ushell_path_valid_syntac( g_s_arg[0] ); ushell_path_valid_syntac( g_s_arg[1] ); printf("Synchronize folders:\n\r"); sav_index = nav_getindex(); // Save the position // Select source directory in COPYFILE navigator handle nav_select( FS_NAV_ID_COPYFILE ); printf("Select source directory\n\r"); if( !nav_setcwd( (FS_STRING)g_s_arg[0], true, false ) ) goto ushell_cmd_sync_error; nav_filelist_reset(); // Select destination directory in USHELL navigator handle nav_select( FS_NAV_ID_USHELL_CMD ); printf("Select destination directory\n\r"); if( !nav_setcwd( (FS_STRING)g_s_arg[1], true, true ) ) goto ushell_cmd_sync_error; nav_filelist_reset(); // loop to scan and create ALL folders and files while(1) { while(1) { // Loop to Search files or directories // Reselect Source nav_select( FS_NAV_ID_COPYFILE ); if( nav_filelist_set( 0 , FS_FIND_NEXT ) ) break; // a next file and directory is found // No other dir or file in current dir then go to parent dir on Source and Destination disk if( 0 == u8_folder_level ) { // end of update folder //********* END OF COPY ************** goto ushell_cmd_sync_finish; } printf("Go to parent\n\r"); // Remark, nav_dir_gotoparent() routine go to in parent dir and select the children dir in list u8_folder_level--; if( !nav_dir_gotoparent() ) goto ushell_cmd_sync_error; // Select Destination navigator and go to the same dir of Source nav_select( FS_NAV_ID_USHELL_CMD ); if( !nav_dir_gotoparent() ) goto ushell_cmd_sync_error; } // end of while (1) if( nav_file_isdir()) { printf("Dir found - create dir: "); //** here, a new directory is found and is selected // Get name of current selection (= dir name on Source) if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, false )) goto ushell_cmd_sync_error; // Enter in dir (on Source) if( !nav_dir_cd()) goto ushell_cmd_sync_error; u8_folder_level++; // Select Destination disk nav_select( FS_NAV_ID_USHELL_CMD ); // Create folder in Destination disk printf((char*)g_s_arg[0]); printf("\n\r"); if( !nav_dir_make( (FS_STRING )g_s_arg[0] )) { if( FS_ERR_FILE_EXIST != fs_g_status ) goto ushell_cmd_sync_error; // here, error the name exist } // Here the navigator have selected the folder on Destination if( !nav_dir_cd()) { if( FS_ERR_NO_DIR == fs_g_status ) { // FYC -> Copy impossible, because a file have the same name of folder } goto ushell_cmd_sync_error; } // here, the folder is created and the navigator is entered in this dir } else { printf("File found - copy file: "); //** here, a new file is found and is selected // Get name of current selection (= file name on Source) if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, false )) goto ushell_cmd_sync_error; printf((char*)g_s_arg[0]); printf("\n\r"); if( !nav_file_copy()) goto ushell_cmd_sync_error; // Paste file in current dir of Destination disk nav_select( FS_NAV_ID_USHELL_CMD ); while( !nav_file_paste_start( (FS_STRING)g_s_arg[0] ) ) { // Error if( fs_g_status != FS_ERR_FILE_EXIST ) goto ushell_cmd_sync_error; // File exists then deletes this one printf("File exists then deletes this one.\n\r"); if( !nav_file_del( true ) ) goto ushell_cmd_sync_error; // here, retry PASTE } // Copy running { uint8_t status; do{ status = nav_file_paste_state(false); }while( COPY_BUSY == status ); if( COPY_FINISH != status ) goto ushell_cmd_sync_error; } } // if dir OR file } // end of first while(1) ushell_cmd_sync_error: // Restore the position nav_select( FS_NAV_ID_USHELL_CMD ); nav_gotoindex(&sav_index); printf("!!!Copy fail\n\r"); return false; ushell_cmd_sync_finish: // Restore the position nav_select( FS_NAV_ID_USHELL_CMD ); nav_gotoindex(&sav_index); printf("End of copy\n\r"); return true; }
//! This function adds files in play list //! //! @param sz_filterext add file only corresponding to the extension filter //! @param u8_mode PL_ADD_FILE, PL_ADD_DIR, PL_ADD_SUBDIR //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! //! @verbatim //! It is possible to select a file or all files in a directory //! @endverbatim //! bool pl_add( const FS_STRING sz_filterext , uint8_t u8_mode ) { uint8_t nav_id_save; uint8_t u8_folder_level; if( !pl_main_modify() ) return false; nav_id_save = nav_get(); // Check last character of file nav_select( FS_NAV_ID_PLAYLIST ); if( 0!=nav_file_lgt() ) { #if( PL_UNICODE == true) file_string_unicode(); file_seek( 2, FS_SEEK_END); if( '\n' != file_getc()) { file_seek( 2, FS_SEEK_END); file_putc('\n'); } file_string_ascii(); #else file_seek( 1, FS_SEEK_END); if( '\n' != file_getc()) { file_seek( 1, FS_SEEK_END); file_putc('\n'); } #endif } nav_select( nav_id_save ); // Get path of play list file and check with current to create a relative path if( PL_ADD_FILE == u8_mode ) goto pl_add_file; // Add all files valid in current dir u8_folder_level = 0; nav_filelist_reset(); while(1) { while(1) { if( nav_filelist_set( 0 , FS_FIND_NEXT ) ) break; // a next file and directory is found // No other dir or file in current dir then go to parent dir if( 0 == u8_folder_level ) goto pl_add_end; // end of ADD // Remark, nav_dir_gotoparent() routine go to in parent dir and select the children dir in list u8_folder_level--; if( !nav_dir_gotoparent() ) return false; } if( nav_file_isdir()) { if( PL_ADD_SUBDIR == u8_mode ) { // Enter in sub dir if( !nav_dir_cd()) return false; u8_folder_level++; } } else { pl_add_file: if( nav_file_checkext( sz_filterext ) ) { // It is a valid file // Get name of current file #if( (FS_ASCII == true) && (FS_UNICODE == true) && (PL_UNICODE == false) ) nav_string_ascii(); #endif nav_getcwd( (FS_STRING)pl_cache_path, PL_CACHE_PATH_MAX_SIZE, true ); #if( (FS_ASCII == true) && (FS_UNICODE == true) && (PL_UNICODE == false) ) nav_string_unicode(); #endif // Write path in file list nav_select( FS_NAV_ID_PLAYLIST ); #if( PL_UNICODE == true) file_string_unicode(); #endif if( file_puts(pl_cache_path)) file_putc('\n'); #if( PL_UNICODE == true) file_string_ascii(); #endif nav_select( nav_id_save ); pl_g_u16_list_size++; } if( PL_ADD_FILE == u8_mode ) goto pl_add_end; } // if dir OR file } // end of first while(1) pl_add_end: // Go to beginning of file AND no file selected nav_select( FS_NAV_ID_PLAYLIST ); file_seek( 0 , FS_SEEK_SET ); pl_g_u16_list_sel = 0; nav_select( nav_id_save ); return true; }
//! //! @brief Synchronize the contents of two directories (limited to files). //! //! @param dst_fs_idx Fs_index *: File system index for destination navigation path //! @param dst_dir const char *: Pointer to destination directory name //! @param src_fs_idx Fs_index *: File system index for source navigation path //! @param src_dir const char *: Pointer to source directory name //! //! @return bool: true on success //! //! @todo Do recursive directory copy... //! bool host_mass_storage_task_sync_dir(Fs_index *dst_fs_idx, const char *dst_dir, Fs_index *src_fs_idx, const char *src_dir) { uint8_t nb_file; uint8_t i; uint32_t free_space; uint16_t file_size; // First, check the host controller is in full operating mode with the // B-device attached and enumerated if (!Is_host_ready()) return false; // Go to source navigation nav_gotoindex(src_fs_idx); if (!goto_code_name(src_dir)) return false; // Check that source directory exists nav_dir_cd(); // Source directory exists, so go to it *src_fs_idx = nav_getindex(); // Save navigation position nav_filelist_first(FS_FILE); // Go to first file nb_file = nav_filelist_nb(FS_FILE); // Get the number of files in this directory // Go to destination navigation nav_gotoindex(dst_fs_idx); if (!goto_code_name(dst_dir)) // Destination directory does not exist, so create it { str_code_to_unicode_ram(dst_dir, ms_str_unicode); nav_dir_make(ms_str_unicode); if (!goto_code_name(dst_dir)) return false; // Check that destination directory has been created } nav_dir_cd(); *dst_fs_idx = nav_getindex(); // Get available free space free_space = nav_partition_space(); nav_gotoindex(src_fs_idx); nav_filelist_first(FS_FILE); // For all files in directory for (i = 0; i < nb_file; i++) { // Get source name to be used as destination name nav_file_name(ms_str_unicode, MAX_FILE_PATH_LENGTH, FS_NAME_GET); file_size = nav_file_lgtsector(); // Get file size if (file_size > free_space) return false; // Check that there is enough free space left // Update free space (to save time, do no call nav_partition_space() again) free_space -= file_size; // Mark source nav_file_copy(); // Save current source position *src_fs_idx = nav_getindex(); // Go to destination navigation nav_gotoindex(dst_fs_idx); if (goto_unicode_name(ms_str_unicode)) // If file already exists { nav_file_del(); // Delete it } // Paste nav_file_paste_start(ms_str_unicode); // Restore previous navigation position nav_gotoindex(src_fs_idx); // Copy while (nav_file_paste_state(false) == COPY_BUSY); // Restore previous navigation position nav_gotoindex(src_fs_idx); nav_filelist_set(0, FS_FIND_NEXT); } return true; }
//! This function enters in the selected directory //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! //! @verbatim //! After this routine the file list changes and contains the files and directories of the new directory. //! By default no file is selected. //! @endverbatim //! bool nav_filterlist_cd( void ) { fs_g_nav.u16_pos_filterlist = FS_NO_SEL; return nav_dir_cd(); }