-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathfolder.h
286 lines (211 loc) · 13.8 KB
/
folder.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/*
* folder.h
*
* Created on: Nov 21, 2020
* Author: micahbly
*
* This is a huge cut-down of the Amiga WorkBench2000 code, for F256 f/manager and B128 f/manager
* 8-bit version started Jan 12, 2023
*/
#ifndef FOLDER_H_
#define FOLDER_H_
/* about this class: WB2KFolderObject
*
* This handles folders on disk, with FileObject children for any files in the folder
*
*** things this class needs to be able to do
*
* get a listing of the files in the folder
* indicate if a passed file object or filepath is a match for something in its list
* perform actions on all or only-selected files in the folder, using recursion and a function pointer
* - get total of all file sizes
* - delete
* - move
* - copy
*
*** things objects of this class have
*
* A list of WB2KFileObjects (potentially empty)
* count of files in the folder, kept up to date
* total size, in bytes, of all files in the folder, including files in sub-folders (on request; not kept up to date for performance reasons)
*
*/
/*****************************************************************************/
/* Includes */
/*****************************************************************************/
#include "app.h"
#include "file.h"
#include "list.h"
#include <stdio.h>
/*****************************************************************************/
/* Macro Definitions */
/*****************************************************************************/
#define FOLDER_SYSTEM_ROOT_NAME (char*)"[ROOT]"
// #define DO_NOT_DESTROY_FILE_OBJECT false // for Folder_RemoveFileListItem()
// #define DESTROY_FILE_OBJECT true // for Folder_RemoveFileListItem()
#define PROCESS_FOLDER_FILE_BEFORE_CHILDREN true // for Folder_ProcessContents()
#define PROCESS_FOLDER_FILE_AFTER_CHILDREN false // for Folder_ProcessContents()
#define MARK_AS_SELECTED true // for Folder_SetFileSelectionByRow()
#define MARK_AS_UNSELECTED false // for Folder_SetFileSelectionByRow()
#define FOLDER_MAX_TRIES_AT_FOLDER_CREATION 128 // arbitrary, for use with Folder_CreateNewFolder; stop at "unnamed folder 128"
#define _CBM_T_DEL 0x00U // deleted file
#define _CBM_T_CBM 0x01U /* 1581 sub-partition */
#define _CBM_T_DIR 0x02U /* IDE64 and CMD sub-directory */
#define _CBM_T_LNK 0x03U /* IDE64 soft-link */
#define _CBM_T_OTHER 0x04U /* File-type not recognized */
#define _CBM_T_HEADER 0x05U /* Disk header / title */
#define _CBM_T_REG 0x10U /* Bit set for regular files */
#define _CBM_T_SEQ 0x10U
#define _CBM_T_PRG 0x11U
#define _CBM_T_USR 0x12U
#define _CBM_T_REL 0x13U
#define _CBM_T_VRP 0x14U /* Vorpal fast-loadable format */
#define FNX_FILETYPE_FONT 200 // any 2k file ending in .fnt
#define FNX_FILETYPE_EXE 201 // any .pgz, etc executable
#define FNX_FILETYPE_BASIC 202 // a .bas file that f/manager will try to pass to SuperBASIC
#define FNX_FILETYPE_MUSIC 203 // a .mod file that f/manager will try to pass to modojr
#define FNX_FILETYPE_IMAGE 204 // a .256 or .lbm image file.
#define FNX_FILETYPE_TEXT 205 // a .txt or .src text file that can/will be opened in a text editor
#define FNX_FILETYPE_MIDI 206 // a .mid file that f/manager will try to pass to midiplayer.pgz
#define FNX_FILETYPE_MP3 207 // a .mp3 file that f/manager will try to pass to audioplayer.pgz
#define FNX_FILETYPE_OGG 208 // a .ogg file that f/manager will try to pass to audioplayer.pgz
#define FNX_FILETYPE_WAV 209 // a .wav file that f/manager will try to pass to audioplayer.pgz
/*****************************************************************************/
/* Enumerations */
/*****************************************************************************/
typedef enum folder_error_code
{
FOLDER_ERROR_OUT_OF_MEMORY = -10,
FOLDER_ERROR_NO_FILE_EXTENSION = -2,
FOLDER_ERROR_NON_LETHAL_ERROR = -1,
FOLDER_ERROR_NO_ERROR = 0,
FOLDER_ERROR_SUCCESS = 1,
} folder_error_code;
/*****************************************************************************/
/* Structs */
/*****************************************************************************/
// this is a duplicate of the FILE struct defined in cc65. defined to make it possible to access the f_fd and f_flags bytes easily.
// it is defined in cc65/asminc/_file.inc in ASM fully, but in include/stdio.h it is only typedef'ed, without the definition.
typedef struct FILEmimic
{
uint8_t f_fd;
uint8_t f_flags;
uint8_t f_pushback;
} FILEmimic;
typedef struct WB2KFolderObject
{
WB2KList** list_;
char* file_name_; // rather than having whole folder object, we will only use a name now
char* file_path_; // rather than having in file, where it gets stored a lot, will just have in folder.
uint16_t file_count_;
int16_t cur_row_; // 0-n: selected file num. 0=first file. -1 if no file.
// uint32_t total_bytes_;
// uint32_t selected_bytes_;
// uint16_t total_blocks_;
// uint16_t selected_blocks_;
bool is_meatloaf_; // flag set if the folder is currently configured in meatloaf mode.
uint8_t device_number_; // For CBM, 8-9-10-11. for fnx, 0-1-2
} WB2KFolderObject;
/*****************************************************************************/
/* Global Variables */
/*****************************************************************************/
/*****************************************************************************/
/* Public Function Prototypes */
/*****************************************************************************/
void cmd_ls(void);
// **** CONSTRUCTOR AND DESTRUCTOR *****
// constructor
// allocates space for the object and any string or other properties that need allocating
// if the passed folder pointer is not NULL, it will pass it back without allocating a new one.
// if the passed folder pointer is NULL, it will reset the folder, without destroying it, to a condition where it can be completely repopulated
// destroys all child objects except the folder file, which is emptied out
// recreates the folder file based on the device number and the new_path string (eg, "0:myfolder")
// returns NULL on any non-fatal error
WB2KFolderObject* Folder_NewOrReset(WB2KFolderObject* the_existing_folder,uint8_t the_device_number, char* new_path);
// destructor
// frees all allocated memory associated with the passed object, and the object itself
void Folder_Destroy(WB2KFolderObject** the_folder);
// free every fileobject in the folder's list, and remove the nodes from the list
void Folder_DestroyAllFiles(WB2KFolderObject* the_folder);
// **** SETTERS *****
// sets the row num (-1, or 0-n) of the currently selected file
void Folder_SetCurrentRow(WB2KFolderObject* the_folder, int16_t the_row_number);
// **** GETTERS *****
// // returns the list of files associated with the folder
// WB2KList** Folder_GetFileList(WB2KFolderObject* the_folder);
// // returns the file object for the root folder
// WB2KFileObject* Folder_GetFolderFile(WB2KFolderObject* the_folder);
// returns true if folder has any files/folders in it. based on curated file_count_ property, not on a live check of disk.
bool Folder_HasChildren(WB2KFolderObject* the_folder);
// returns total number of files in this folder
uint16_t Folder_GetCountFiles(WB2KFolderObject* the_folder);
// returns the row num (-1, or 0-n) of the currently selected file
int16_t Folder_GetCurrentRow(WB2KFolderObject* the_folder);
// returns the currently selected file, or NULL if no file is marked as selected
WB2KFileObject* Folder_GetCurrentFile(WB2KFolderObject* the_folder);
// returns the file type of the currently selected file, or 0 if no file is marked as selected
uint8_t Folder_GetCurrentFileType(WB2KFolderObject* the_folder);
// // returns true if folder has any files/folders showing as selected
// bool Folder_HasSelections(WB2KFolderObject* the_folder);
// // returns number of currently selected files in this folder
// uint16_t Folder_GetCountSelectedFiles(WB2KFolderObject* the_folder);
// // returns the first selected file/folder in the folder.
// WB2KFileObject* Folder_GetFirstSelectedFile(WB2KFolderObject* the_folder);
// // returns the first file/folder in the folder.
// WB2KFileObject* Folder_GetFirstFile(WB2KFolderObject* the_folder);
// // Returns NULL if nothing matches, or returns pointer to first FileObject with a filename that starts with the same string as the one passed
// // DOES NOT REQUIRE a match to the full filename
// WB2KFileObject* Folder_FindFileByFileNameStartsWith(WB2KFolderObject* the_folder, char* string_to_match, int compare_len);
// looks through all files in the file list, comparing the passed row to that of each file.
// Returns NULL if nothing matches, or returns pointer to first matching FileObject
WB2KFileObject* Folder_FindFileByRow(WB2KFolderObject* the_folder, uint8_t the_row);
// **** OTHER FUNCTIONS *****
// Add a file object to the list of files without checking for duplicates.
// returns true in all cases. NOTE: this is part of series of functions designed to be called by Window_ModifyOpenFolders(), and all need to return bools.
bool Folder_AddNewFile(WB2KFolderObject* the_folder, WB2KFileObject* the_file);
// Add a file object to the list of files without checking for duplicates. This variant makes a copy of the file before assigning it. Use case: MoveFiles or CopyFiles.
// returns true in all cases.
// NOTE: this is part of series of functions designed to be called by Window_ModifyOpenFolders(), and all need to return bools.
bool Folder_AddNewFileAsCopy(WB2KFolderObject* the_folder, WB2KFileObject* the_file);
// // removes the passed list item from the list of files in the folder. Does NOT delete file from disk. Does NOT delete the file object.
// // returns true if a matching file was found and successfully removed.
// // NOTE: this is part of series of functions designed to be called by Window_ModifyOpenFolders(), and all need to return bools.
// bool Folder_RemoveFile(WB2KFolderObject* the_folder, WB2KFileObject* the_file);
// // deletes the passed file/folder. If a folder, it must have been previously emptied of files.
// bool Folder_DeleteFile(WB2KFolderObject* the_folder, WB2KList* the_item, WB2KFolderObject* not_needed);
// // removes the passed list item from the list of files in the folder. Does NOT delete file from disk. Optionally frees the file object.
// void Folder_RemoveFileListItem(WB2KFolderObject* the_folder, WB2KList* the_item, bool destroy_the_file_object);
// // Create a new folder on disk, and a new file object for it, and assign it to this folder.
// // if try_until_successful is set, will rename automatically with trailing number until it can make a new folder (by avoiding already-used names)
// bool Folder_CreateNewFolder(WB2KFolderObject* the_folder, char* the_file_name, bool try_until_successful);
// copies the passed file/folder. If a folder, it will create directory on the target volume if it doesn't already exist
bool Folder_CopyFile(WB2KFolderObject* the_folder, WB2KFileObject* the_file, WB2KFolderObject* the_target_folder);
// copies the currently selected file
bool Folder_CopyCurrentFile(WB2KFolderObject* the_folder, WB2KFolderObject* the_target_folder);
// compare 2 folder objects. When done, the original_root_folder will have been updated with removals/additions as necessary to match the updated file list
// returns true if any changes were detected, or false if files appear to be identical
bool Folder_SyncFolderContentsByFilePath(WB2KFolderObject* original_root_folder, WB2KFolderObject* updated_root_folder);
// populate the files in a folder by doing a directory command
uint8_t Folder_PopulateFiles(uint8_t the_panel_id, WB2KFolderObject* the_folder);
// counts the bytes in the passed file/folder, and adds them to folder.selected_bytes_
bool Folder_CountBytes(WB2KFolderObject* the_folder, WB2KList* the_item, WB2KFolderObject* not_needed);
// processes, with recursion where necessary, the contents of a folder, using the passed function pointer to process individual files/empty folders.
// returns -1 in event of error, or count of files affected
int Folder_ProcessContents(WB2KFolderObject* the_folder, WB2KFolderObject* the_target_folder, uint8_t the_scope, bool do_folder_before_children, bool (* action_function)(WB2KFolderObject*, WB2KList*, WB2KFolderObject*));
// move every currently selected file into the specified folder. Use when you DO have a folder object to work with
// returns -1 in event of error, or count of files moved
int Folder_MoveSelectedFiles(WB2KFolderObject* the_folder, WB2KFolderObject* the_target_folder);
// move every currently selected file into the specified folder file. Use when you only have a target folder file, not a full folder object to work with.
// returns -1 in event of error, or count of files moved
int Folder_MoveSelectedFilesToFolderFile(WB2KFolderObject* the_folder, WB2KFileObject* the_target_folder_file);
// select or unselect 1 file by row id, and change cur_row_ accordingly
WB2KFileObject* Folder_SetFileSelectionByRow(WB2KFolderObject* the_folder, uint16_t the_row, bool do_selection, uint8_t y_offset);
// populate the folder's List by iterating through the DOS List objects and treating each as a folder/file
bool Folder_PopulateVolumeList(WB2KFolderObject* the_folder);
// get a file handle for the target path, in "write" mode
// returns NULL on any error, including not being able to get a good handle
FILE* Folder_GetTargetHandleForWriting(const char* the_target_file_path);
// TEMPORARY DEBUG FUNCTIONS
// helper function called by List class's print function: prints folder total bytes, and calls print on each file
void Folder_Print(void* the_payload);
#endif /* FOLDER_H_ */