ios: Clean up directory listing code.

This commit is contained in:
meancoot 2013-02-09 12:01:33 -05:00
parent 4d9233b02a
commit 2d04aefe5f
6 changed files with 46 additions and 180 deletions

View File

@ -10,7 +10,6 @@
962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; };
962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; };
962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; };
96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; };
96297A0916C59EC000E6DCE0 /* module_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0816C59EC000E6DCE0 /* module_list.m */; };
96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; };
96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; };
@ -83,8 +82,6 @@
962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = "<group>"; };
962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = "<group>"; };
962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = "<group>"; };
962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = "<group>"; };
96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = "<group>"; };
96297A0816C59EC000E6DCE0 /* module_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = module_list.m; sourceTree = "<group>"; };
96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = "<group>"; };
96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = "<group>"; };
@ -336,8 +333,6 @@
96297A0D16C5ADDA00E6DCE0 /* views.h */,
96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */,
96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */,
962979FF16C4767F00E6DCE0 /* dirent_list.c */,
96297A0016C4767F00E6DCE0 /* dirent_list.h */,
96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */,
96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */,
96AFAE3416C1D4EA009DE44C /* Supporting Files */,
@ -785,7 +780,6 @@
96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */,
96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */,
962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */,
96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */,
96297A0916C59EC000E6DCE0 /* module_list.m in Sources */,
96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */,
96297A0F16C5AEA100E6DCE0 /* main.m in Sources */,

View File

@ -6,76 +6,78 @@
// Copyright (c) 2013 RetroArch. All rights reserved.
//
#include "dirent_list.h"
@implementation directory_list
{
char* directory;
struct dirent_list* files;
NSString* directory;
NSArray* list;
};
- (id)initWithPath:(const char*)path
- (id)initWithPath:(NSString*)path
{
self = [super initWithStyle:UITableViewStylePlain];
directory = strdup(path);
files = build_dirent_list(directory);
directory = path;
list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directory error:nil];
list = [directory stringsByAppendingPaths:list];
list = [list sortedArrayUsingComparator:^(id left, id right)
{
BOOL left_is_dir;
BOOL right_is_dir;
[[NSFileManager defaultManager] fileExistsAtPath:left isDirectory:&left_is_dir];
[[NSFileManager defaultManager] fileExistsAtPath:right isDirectory:&right_is_dir];
return (left_is_dir != right_is_dir) ? (left_is_dir < right_is_dir) : ([left caseInsensitiveCompare:right]);
}];
self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button;
[self setTitle: [[[NSString alloc] initWithUTF8String:directory] lastPathComponent]];
[self setTitle: [directory lastPathComponent]];
return self;
}
- (void)dealloc
{
free_dirent_list(files);
free(directory);
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
const struct dirent* item = get_dirent_at_index(files, indexPath.row);
if (!item) return;
char new_path[4096];
snprintf(new_path, 4096, "%s/%s", directory, item->d_name);
new_path[4095] = 0;
if (item->d_type)
{
[[RetroArch_iOS get].navigator
pushViewController:[[directory_list alloc] initWithPath:new_path]
animated:YES];
}
else
NSString* path = [list objectAtIndex: indexPath.row];
BOOL isdir;
if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir])
{
[RetroArch_iOS get].window.rootViewController = [[game_view alloc] init];
if (isdir)
{
[[RetroArch_iOS get].navigator
pushViewController:[[directory_list alloc] initWithPath:path]
animated:YES];
}
else
{
[RetroArch_iOS get].window.rootViewController = [[game_view alloc] init];
extern void ios_load_game(const char*);
ios_load_game(new_path);
extern void ios_load_game(const char*);
ios_load_game([path UTF8String]);
}
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return get_dirent_list_count(files);
return [list count];
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"];
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"];
const struct dirent* item = get_dirent_at_index(files, indexPath.row);
if (item)
NSString* path = [list objectAtIndex: indexPath.row];
BOOL isdir;
if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir])
{
cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name];
cell.accessoryType = (item->d_type) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
cell.imageView.image = (item->d_type) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon;
[cell.imageView sizeToFit];
cell.textLabel.text = [path lastPathComponent];
cell.accessoryType = (isdir) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
cell.imageView.image = (isdir) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon;
}
return cell;

View File

@ -1,97 +0,0 @@
#include <sys/stat.h>
#include <dirent.h>
#include <stddef.h>
#include "general.h"
#include "dirent_list.h"
static int compare_dirent(const void *left, const void *right)
{
const struct dirent* l = (const struct dirent*) left;
const struct dirent* r = (const struct dirent*) right;
// Directories first
if (l->d_type != r->d_type)
return (l->d_type) ? -1 : 1;
// Name
return strcmp(l->d_name, r->d_name);
}
static bool is_dirent_verboten(const struct dirent* entry)
{
if (!entry) return true;
if (strcmp(entry->d_name, ".") == 0) return true;
if (strcmp(entry->d_name, "..") == 0) return true;
return false;
}
struct dirent_list* build_dirent_list(const char* path)
{
struct dirent_list* result = 0;
DIR* dir = opendir(path);
if (dir)
{
struct dirent* ent = 0;
// Count the number of items
size_t count = 0;
while ((ent = readdir(dir)))
{
count += is_dirent_verboten(ent) ? 0 : 1;
}
rewinddir(dir);
// String buffer for 'stat'ing
char* stat_path = malloc(strlen(path) + sizeof(ent->d_name));
strcpy(stat_path, path);
uint32_t last_index = strlen(stat_path);
// Build and fill the result
result = malloc(sizeof(struct dirent_list));
result->count = count;
result->entries = malloc(sizeof(struct dirent) * count);
size_t index = 0;
while ((ent = readdir(dir)))
{
if (is_dirent_verboten(ent)) continue;
memcpy(&result->entries[index], ent, sizeof(struct dirent));
// Chage dirent.d_type to a boolean indication if it is a directory
struct stat stat_buf;
strcat(strcat(stat_path, "/"), ent->d_name);
stat(stat_path, &stat_buf);
result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0;
stat_path[last_index] = 0;
index ++;
}
closedir(dir);
free(stat_path);
qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent);
}
return result;
}
void free_dirent_list(struct dirent_list* list)
{
if (list) free(list->entries);
free(list);
}
const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index)
{
if (!list) return 0;
return (index < list->count) ? &list->entries[index] : 0;
}
unsigned get_dirent_list_count(struct dirent_list* list)
{
return list ? list->count : 0;
}

View File

@ -1,33 +0,0 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __RARCH_IOS_DIRENT_LIST_H
#define __RARCH_IOS_DIRENT_LIST_H
#include <dirent.h>
struct dirent_list
{
size_t count;
struct dirent* entries;
};
struct dirent_list* build_dirent_list(const char* path);
void free_dirent_list(struct dirent_list* list);
const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index);
unsigned get_dirent_list_count(struct dirent_list* list);
#endif

View File

@ -33,7 +33,7 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[RetroArch_iOS get].module_path = [modules objectAtIndex:indexPath.row];
[[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:"/"] animated:YES];
[[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:@"/"] animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
@ -46,7 +46,7 @@
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"];
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"];
cell.textLabel.text = [[modules objectAtIndex:indexPath.row] lastPathComponent];
cell.textLabel.text = [[[modules objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension];
return cell;
}

View File

@ -10,5 +10,5 @@
@end
@interface directory_list : UITableViewController
- (id)initWithPath:(const char*)path;
- (id)initWithPath:(NSString*)path;
@end