summaryrefslogtreecommitdiff
path: root/arm9/lib/src/FS_command_default.c
blob: bd04f740387e657a217bca5d6c48990a12a32b17 (plain)
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
#include "nitro.h"
#include "FS_file.h"
#include "FS_command.h"
#include "FS_archive.h"
#include "MI_byteAccess.h"

typedef struct
{
    FSArchive *arc;
    u32 pos;
}
FSiSyncReadParam;

FSResult FSi_ReadFileCommand(FSFile * p_file);
FSResult FSi_WriteFileCommand(FSFile * p_file);
FSResult FSi_SeekDirCommand(FSFile * p_file);
FSResult FSi_ReadDirCommand(FSFile * p_file);
FSResult FSi_FindPathCommand(FSFile * p_file);
FSResult FSi_GetPathCommand(FSFile * p_file);
FSResult FSi_OpenFileFastCommand(FSFile * p_file);
FSResult FSi_OpenFileDirectCommand(FSFile * p_file);
FSResult FSi_CloseFileCommand(FSFile * p_file);

FSResult (*const fsi_default_command[])(FSFile *) = {
    [FS_COMMAND_READFILE]       = FSi_ReadFileCommand,
    [FS_COMMAND_WRITEFILE]      = FSi_WriteFileCommand,
    [FS_COMMAND_SEEKDIR]        = FSi_SeekDirCommand,
    [FS_COMMAND_READDIR]        = FSi_ReadDirCommand,
    [FS_COMMAND_FINDPATH]       = FSi_FindPathCommand,
    [FS_COMMAND_GETPATH]        = FSi_GetPathCommand,
    [FS_COMMAND_OPENFILEFAST]   = FSi_OpenFileFastCommand,
    [FS_COMMAND_OPENFILEDIRECT] = FSi_OpenFileDirectCommand,
    [FS_COMMAND_CLOSEFILE]      = FSi_CloseFileCommand,
};

// Case-insensitive string comparison
u32 FSi_StrNICmp(const char * str1, const char * str2, u32 len)
{
    int i;
    for (i = 0; i < len; i++)
    {
        u32 c = MI_ReadByte(str1 + i) - 'A';
        u32 d = MI_ReadByte(str2 + i) - 'A';
        if (c <= 'Z' - 'A')
            c += 'a' - 'A';
        if (d <= 'Z' - 'A')
            d += 'a' - 'A';
        if (c != d)
            return c - d;
    }
    return 0;
}

FSResult FSi_ReadTable(FSiSyncReadParam * p, void * dst, u32 len)
{
    FSResult ret;
    FSArchive * const p_arc = p->arc;
    p_arc->flag |= FS_ARCHIVE_FLAG_IS_SYNC;
    switch (ret = (*p_arc->table_func)(p_arc, dst, p->pos, len))
    {
    case FS_RESULT_SUCCESS:
    case FS_RESULT_FAILURE:
        p_arc->flag &= ~FS_ARCHIVE_FLAG_IS_SYNC;
        break;
    case FS_RESULT_PROC_ASYNC:
    {
        OSIntrMode bak_psr = OS_DisableInterrupts();
        while (FSi_IsArchiveSync(p_arc))
            OS_SleepThread(&p_arc->sync_q);
        OS_RestoreInterrupts(bak_psr);
        ret = p_arc->list.next->error;
    }
        break;
    }
    p->pos += len;
    return ret;
}

FSResult FSi_SeekDirDirect(FSFile * p_dir, u32 id)
{
    p_dir->stat |= FS_FILE_STATUS_SYNC;
    p_dir->arg.seekdir.pos.arc = p_dir->arc;
    p_dir->arg.seekdir.pos.pos = 0;
    p_dir->arg.seekdir.pos.index = 0;
    p_dir->arg.seekdir.pos.own_id = (u16)id;
    return FSi_TranslateCommand(p_dir, FS_COMMAND_SEEKDIR);
}

// The actual commands
FSResult FSi_ReadFileCommand(FSFile * p_file)
{
    FSArchive *const p_arc = p_file->arc;
    const u32 pos = p_file->prop.file.pos;
    const u32 len = p_file->arg.readfile.len;
    void *const dst = p_file->arg.readfile.dst;
    p_file->prop.file.pos += len;
    return (*p_arc->read_func)(p_arc, dst, pos, len);
}

FSResult FSi_WriteFileCommand(FSFile * p_file)
{
    FSArchive *const p_arc = p_file->arc;
    const u32 pos = p_file->prop.file.pos;
    const u32 len = p_file->arg.writefile.len;
    const void *const src = p_file->arg.writefile.src;
    p_file->prop.file.pos += len;
    return (*p_arc->write_func)(p_arc, src, pos, len);
}