//! 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; }
static __inline__ navauto_mov_explorer_rec_t navauto_mov_explorer_is_file(bool b_direction, navauto_mov_options_t options) { // Look for the next playable file in the current directory while(nav_filelist_set(0, b_direction)) { if (nav_file_isdir()) break; if (!nav_file_checkext(g_navauto_filter)) continue; return NAVAUTO_MOV_EXPLORER_OK; } // In case it needs to stay in the current directory, if ( (options & NAVAUTO_MOV_OPTS_STAY_CURRENT_DIR) || (g_navauto_exp_mode == NAVAUTO_MODE_DIRONLY)) { if (!nav_file_isdir() && nav_file_checkext(g_navauto_filter)) { g_navauto_u16_pos += (!b_direction == FS_FIND_NEXT)?(1):(-1); } // Update g_navauto_u16_pos while(nav_filelist_set(0, !b_direction)) { if (nav_file_isdir()) break; if (!nav_file_checkext(g_navauto_filter)) continue; g_navauto_u16_pos += (!b_direction == FS_FIND_NEXT)?(1):(-1); } // Go to the first/last file if (navauto_mov_explorer_select_limit_file_cur_folder(b_direction) == NAVAUTO_MOV_EXPLORER_OK) { if (options & NAVAUTO_MOV_OPTS_STAY_CURRENT_DIR) return NAVAUTO_MOV_EXPLORER_OK; else return NAVAUTO_MOV_EXPLORER_OK_LOOP; } return NAVAUTO_MOV_EXPLORER_EMPTY; } // At this point, it means it reached a limit, there is no more playable files switch(is_file_process_fct[(b_direction == FS_FIND_NEXT)?1:0](b_direction)) { case NAVAUTO_MOV_EXPLORER_RECURSIVE: return NAVAUTO_MOV_EXPLORER_RECURSIVE; case NAVAUTO_MOV_EXPLORER_OK: return NAVAUTO_MOV_EXPLORER_OK; default: break; } // 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_RECURSIVE; return navauto_mov_ok_loop(b_direction, options); }
static __inline__ navauto_mov_explorer_rec_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_RECURSIVE; case NAVAUTO_MOV_EXPLORER_OK: return NAVAUTO_MOV_EXPLORER_OK; default: break; } } else return navauto_mov_explorer_enterdir(b_direction); // 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_RECURSIVE; 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 selects the first or the last playable file on the current folder //! //! @param b_direction direction of navigation (FS_FIND_NEXT or FS_FIND_PREV) //! //! @return true if a file is selected //! false otherwise //! static navauto_mov_explorer_rec_t navauto_mov_explorer_select_limit_file_cur_folder(bool b_direction) { if ((b_direction == FS_FIND_NEXT)?nav_filelist_first(FS_FILE):nav_filelist_last(FS_FILE)) { // Look for the 1st or the last playable file in the current directory // Find the 1st or the last valid file while(!nav_file_checkext(g_navauto_filter)) { if (!nav_filelist_set(0, b_direction)) return NAVAUTO_MOV_EXPLORER_ERROR; } return NAVAUTO_MOV_EXPLORER_OK; } else return NAVAUTO_MOV_EXPLORER_ERROR; }
//! This function goes to the previous position in filtered file list //! //! @return false in case of an error or no next file, see global value "fs_g_status" for more detail //! @return true otherwise //! bool nav_filterlist_previous( void ) { uint16_t u16_current_pos; u16_current_pos = nav_filelist_get(); while( nav_filelist_set( 0, FS_FIND_PREV ) ) { if( nav_file_isdir() || nav_file_checkext( fs_g_nav.sz_filterext ) ) { fs_g_nav.u16_pos_filterlist--; return true; } } nav_filelist_goto( u16_current_pos ); return false; }
//! This function goes to the next position in the filtered file list //! //! @return false in case of error or no next file, see global value "fs_g_status" for more detail //! @return true otherwise //! bool nav_filterlist_next( void ) { uint16_t u16_current_pos; u16_current_pos = nav_filelist_get(); while( nav_filelist_set( 0, FS_FIND_NEXT ) ) { if( nav_file_isdir() || nav_file_checkext( fs_g_nav.sz_filterext ) ) { if( FS_NO_SEL == u16_current_pos ) { fs_g_nav.u16_pos_filterlist = 0; }else{ fs_g_nav.u16_pos_filterlist++; } return true; } } nav_filelist_goto( u16_current_pos ); return false; }
//! @brief This function manages the ls command //! //! @param b_more enable the '|more' management when true otherwise no '|more' management //! void ushell_cmd_ls( bool b_more ) { uint8_t str_char[MAX_FILE_PATH_LENGTH]; uint16_t u16_i,u16_nb_file,u16_nb_dir,last_i; uint8_t ext_filter=false; //** Print drive name printf("%c: volume is %s\r\n", 'a'+nav_drive_get(), mem_name(nav_drive_get()) ); printf("Drive uses "); switch (nav_partition_type()) { case FS_TYPE_FAT_12: printf("FAT12\n\r"); break; case FS_TYPE_FAT_16: printf("FAT16\n\r"); break; case FS_TYPE_FAT_32: printf("FAT32\n\r"); break; default: printf("an unknown partition type\r\n"); return; } //** Print directory name if( !nav_dir_name( (FS_STRING)str_char, MAX_FILE_PATH_LENGTH ) ) return; printf("Dir name is %s\n\r",str_char); //** Check extension filter in extra parameters if(g_s_arg[0][0]!=0) { if(g_s_arg[0][0] == '*' && g_s_arg[0][1]=='.') { ext_filter=true; for(u16_i=2; u16_i<USHELL_SIZE_CMD_LINE; u16_i++) { g_s_arg[0][u16_i-2]=g_s_arg[0][u16_i]; } } } //** Print files list printf(" Size Name\n\r"); // Init loop at the beginning of directory nav_filelist_reset(); u16_nb_file=0; u16_nb_dir=0; last_i=0; // For each file in list while( nav_filelist_set(0,FS_FIND_NEXT) ) { if(!ext_filter) { // No extension filter if( nav_file_isdir() ) { printf("Dir "); u16_nb_dir++; // count the number of directory }else{ printf(" "); } } else { // If extension filter then ignore directories if(nav_file_isdir()) continue; // Check extension if(!nav_file_checkext((FS_STRING)g_s_arg[0])) continue; } u16_nb_file++; // count the total of files (directories and files) // Check 'more' step if( b_more && ((u16_nb_file%USHELL_NB_LINE)==0) && (u16_nb_file!=0) && (last_i != u16_nb_file) ) { last_i=u16_nb_file; if( !ushell_more_wait() ) return; // Exit LS command } // Display file nav_file_name((FS_STRING)str_char, MAX_FILE_PATH_LENGTH, FS_NAME_GET, true); printf("%10lu %s\n\r", nav_file_lgt(), str_char); } // Display total number printf(" %4i Files\r\n", u16_nb_file-u16_nb_dir ); printf(" %4i Dir\r\n", u16_nb_dir ); }
//! @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 opens a file list at the current position in navigator //! //! @param b_playlist if true then the current selected file is a play list file to open //! else create a file list with files included in a disk part //! @param pos If b_playlist true, then position in the play list to start //! else folder level of the current position //! //! @return false, in case of error or file list empty //! bool navauto_open( bool b_playlist , uint16_t pos ) { Navauto_mov_state state; g_navauto_b_playlist = b_playlist; g_navauto_u16_dir_level_root = 0; g_navauto_u16_nb = 0; if( b_playlist ) { g_navauto_u16_pos = pos; if( !pl_main_open(false) ) return false; g_navauto_u16_nb = pl_nav_getnbfile(); if( 0 == g_navauto_u16_nb ) return false; if( NAVAUTO_RAND_OFF == navauto_getrand() ) { if( pl_nav_setpos( g_navauto_u16_pos )) { if( nav_filelist_validpos() ) return true; } }else{ navauto_rand_init(); } // Error position then restart at the beginning g_navauto_u16_pos = 0; } else { #if( FS_NAV_AUTOMATIC_NBFILE == ENABLE ) Fs_index index; Fs_index index2; Navauto_rand rand_mode; uint16_t u16_current_pos=0; index.u8_lun = 0xFF; // Reset index (by default no valid selected file) g_navauto_u16_dir_level = pos; rand_mode = navauto_getrand(); // Save random mode navauto_setrand( NAVAUTO_RAND_OFF ); // If no valid file then found the first valid file if( !nav_file_checkext( g_navauto_filter )) { // Go to previous position because "navauto_mov_explorer()" execute a next before search valid file if( !nav_filelist_set( 0 , FS_FIND_PREV ) ) nav_filelist_reset(); state = navauto_mov_explorer(FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE); if((NAVAUTO_MOV_OK_LOOP != state.status) && (NAVAUTO_MOV_OK != state.status) ) { navauto_setrand(rand_mode); return false; // List empty } } index = nav_getindex(); // Compute the size of file list and search the position of selected file navauto_mov_explorer_reset(); // Go to beginning of loop // Note: the number of file is updated in navauto_mov_explorer() routine when the end of list is detected while( navauto_mov_explorer( FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE ).status == NAVAUTO_MOV_OK ) { index2 = nav_getindex(); // Check the current position with the selected file if( (index.u8_lun == index2.u8_lun) && (index.u32_cluster_sel_dir == index2.u32_cluster_sel_dir) && (index.u16_entry_pos_sel_file == index2.u16_entry_pos_sel_file) ) { u16_current_pos = g_navauto_u16_pos; // Save the position number found g_navauto_u16_dir_level_root = g_navauto_u16_dir_level; } } navauto_setrand(rand_mode); // Restore random mode if( 0 == g_navauto_u16_nb ) return false; // loop empty // Go to a file from file list if( NAVAUTO_RAND_OFF == navauto_getrand() ) { if( 0xFF != index.u8_lun ) { // Reselect the file selected at startup nav_gotoindex( &index ); // Go to this one g_navauto_u16_dir_level = g_navauto_u16_dir_level_root; // Update position file g_navauto_u16_pos = u16_current_pos; // Update folder level corresponding at file } // Else, the first file is already selected at the end of "compute file list size" loop return true; }else{ navauto_rand_init(); } #else Fs_index index; Navauto_rand rand_mode; rand_mode = navauto_getrand(); navauto_setrand(NAVAUTO_RAND_OFF); // If no valid file then find the first valid file if( !nav_file_checkext( g_navauto_filter )) { // Go to previous position because "navauto_mov_explorer()" execute a next before search valid file if( !nav_filelist_set( 0 , FS_FIND_PREV ) ) nav_filelist_reset(); state = navauto_mov_explorer(FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE); if((NAVAUTO_MOV_OK_LOOP != state.status) && (NAVAUTO_MOV_OK != state.status) ) { navauto_setrand(rand_mode); return false; // List empty } } index = nav_getindex(); navauto_setrand(rand_mode); navauto_mov_explorer_reset(); // Compute directory level g_navauto_u16_dir_level = 0; while(nav_dir_gotoparent()) g_navauto_u16_dir_level++; g_navauto_u16_dir_level_root = g_navauto_u16_dir_level; //g_navauto_u16_dir_level = pos; // Restore index nav_gotoindex(&index); g_navauto_u16_nb = 0xFFFF; if( NAVAUTO_RAND_OFF == navauto_getrand() ) navauto_rand_init(); if( nav_file_checkext( g_navauto_filter )) { // Valid file then update position with the first position but it is not the first ! g_navauto_u16_pos = 1; return true; } #endif } // Find first file or use the random feature state = navauto_mov(FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE); if((NAVAUTO_MOV_OK_LOOP != state.status) && (NAVAUTO_MOV_OK != state.status) ) return false; // List empty return true; }
//! This function jumps to the next or previous file in file list included in directories //! //! @param b_direction jump direction (FS_FIND_NEXT or FS_FIND_PREV) //! @param options define extra modes for this function //! //! @return the status of the action //! //! @verbatim //! This routine is not authorized then a play list file is opened //! When the random is ON, the direction is ignored //! @endverbatim //! Navauto_mov_state navauto_mov_explorer( bool b_direction, navauto_mov_options_t options ) { Navauto_mov_state state; uint16_t u16_mov_pos = 0; size_t nb_loops = 1; // Make sure the selection is different from the previous one // This should be useful only well shuffle_set == true uint16_t u16_previous_pos = g_navauto_u16_pos; // Reset the bitfield status memset(&bitfield_status, 0, sizeof(bitfield_status)); // Random implementation if (g_navauto_rand == NAVAUTO_RAND_ON) { // If shuffle is set for the first time then go to the beginning of the list if (shuffle_set) { if (options & NAVAUTO_MOV_OPTS_STAY_CURRENT_DIR) { navauto_mov_explorer_select_limit_file_cur_folder(FS_FIND_NEXT); g_navauto_u16_pos = 0; g_navauto_u16_nb = 1; while(nav_filelist_set(0, FS_FIND_NEXT)) { if (!nav_file_checkext(g_navauto_filter)) continue; g_navauto_u16_nb++; } navauto_mov_explorer_select_limit_file_cur_folder(FS_FIND_NEXT); } else { navauto_mov_explorer_limit(FS_FIND_NEXT); // Point on the 1srt file g_navauto_u16_pos = 0; navauto_mov_explorer_rec(FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE); // Reinitialize the counter to make sure we will count all the files g_navauto_u16_nb = 0; } shuffle_set = false; } u16_mov_pos = navauto_rand_choose(g_navauto_u16_pos, g_navauto_u16_nb); // To avoid end of loop (NAVAUTO_MOV_OK_LOOP state) b_direction = (u16_mov_pos > g_navauto_u16_pos)?FS_FIND_NEXT:FS_FIND_PREV; nb_loops = (u16_mov_pos > g_navauto_u16_pos)?(u16_mov_pos-g_navauto_u16_pos):(g_navauto_u16_pos-u16_mov_pos); } // This loop is done, so that the random method is not a problem once a NAVAUTO_MOV_OPTS_STAY_CURRENT_DIR option is set to 1. while(nb_loops--) { // Compute the recursive function state.status = navauto_mov_explorer_rec(b_direction, options); // Check its returning state switch(state.status) { // If the function is at the end of the loop case NAVAUTO_MOV_OK_LOOP: // Update g_navauto_u16_pos counter if (b_direction == FS_FIND_NEXT) { g_navauto_u16_nb = g_navauto_u16_pos + 1; g_navauto_u16_pos = 0; } else g_navauto_u16_pos = g_navauto_u16_nb - 1; // Means it reached the tail or the beginning of the playlist. // Then set the pointer to a limit of the "playlist" // should be at the beginning for a NEXT and at end for a PREVIOUS command. switch(limit_process_fct[(b_direction == FS_FIND_NEXT)?1:0](b_direction)) { case NAVAUTO_MOV_EXPLORER_RECURSIVE: // If it returns NAVAUTO_MOV_OK_LOOP, it means it reached two times a row the end of the playlist, // therefore, this is an empty disk! if (navauto_mov_explorer_rec(b_direction, options) == NAVAUTO_MOV_OK_LOOP) { state.bitfield.all = bitfield_status.all; state.status = NAVAUTO_MOV_EMPTY; return state; } break; default: break; } state.bitfield.all = bitfield_status.all; state.status = NAVAUTO_MOV_OK_LOOP; return state; // If a file is correctly selected case NAVAUTO_MOV_OK: // Update g_navauto_u16_pos counter g_navauto_u16_pos += (b_direction == FS_FIND_NEXT)?(1):(-1); // if the selection is the same as last one, then get next file if (g_navauto_rand == NAVAUTO_RAND_ON && u16_previous_pos == g_navauto_u16_pos && !nb_loops && g_navauto_u16_nb > 1) { return navauto_mov_explorer(b_direction, options); } break; default: state.bitfield.all = bitfield_status.all; return state; } } state.status = NAVAUTO_MOV_OK; state.bitfield.all = bitfield_status.all; return state; }
//! 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 computes the number of files and/or directories in filtered file list //! This function is not blocking. It will return after \<retry\> iteration if the result //! is not yet computed. //! //! @param fl_type FL_ALL To check all types (files and directories). <br> //! FL_DIR To check the directory presence. <br> //! FL_FILE To check the file presence. //! //! @param sz_filterext Extension filter (ASCII format, e.g.: "txt" or "txt,d*,wk" ). <br> //! If this argument in NULL, then it uses the default filter used by the filterlist. <br> //! This argument is also ignored for b_type == FS_DIR. //! @param p_total Pointer to the result which will be updated by the function (added). //! Initialization shall be done before entering into this function. //! @param retry Number of files seen before leaving the function. 0 means that the //! function is blocking until the result is known. //! //! @return number of files and/or directories present in filtered file list. //! bool nav_filterlist_nb_ex( fl_type_t fl_type, const FS_STRING sz_filterext, uint16_t* p_total, uint8_t retry ) { static uint16_t u16_save_position; bool b_is_dir; // save current position if( *p_total==(uint16_t) -1 ) { u16_save_position = fs_g_nav.u16_pos_filterlist; // Reset position if ( !nav_filterlist_reset()) return true; if (fl_type == FL_DIR) nav_filelist_single_enable(FS_DIR); else if (fl_type == FL_FILE) nav_filelist_single_enable(FS_FILE); *p_total = 0; } // Scan all while( nav_filelist_set( 0, FS_FIND_NEXT ) ) { b_is_dir = nav_file_isdir(); // Check if its a file for FL_FILE mode if (fl_type == FL_FILE && b_is_dir) { if (!update_counter(&retry)) return false; continue; } // Check if its a directory for FL_DIR mode if (fl_type == FL_DIR && !b_is_dir) { if (!update_counter(&retry)) return false; continue; } // If the selection is on a file if (!b_is_dir) { // Check the extension of the file if (!((sz_filterext)?nav_file_checkext(sz_filterext):nav_file_checkext(fs_g_nav.sz_filterext))) if (!update_counter(&retry)) return false; } (*p_total)++; if (!update_counter(&retry)) return false; } nav_filelist_single_disable(); // Restore previous position if ( u16_save_position != FS_NO_SEL ) { nav_filterlist_reset(); }else{ // After operation, there are a file selected nav_filterlist_goto( u16_save_position ); } return true; }