1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - FS - libraries
3   File:     util.h
4 
5   Copyright 2007-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2009-07-14#$
14   $Rev: 10906 $
15   $Author: yosizaki $
16 
17  *---------------------------------------------------------------------------*/
18 
19 
20 #if	!defined(NITRO_FS_UTIL_H_)
21 #define NITRO_FS_UTIL_H_
22 
23 #include <nitro/misc.h>
24 #include <nitro/types.h>
25 
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 
32 /*---------------------------------------------------------------------------*/
33 /* Constants */
34 
35 // Enable this definition when you want to use the file system from the ARM7
36 // #define SDK_ARM7FS
37 
38 // This is only defined for environments that should include the full set of file system functionality
39 #if	!defined(SDK_ARM7) || defined(SDK_ARM7FS)
40 #define	FS_IMPLEMENT
41 #endif
42 
43 
44 /*---------------------------------------------------------------------------*/
45 /* Functions */
46 
47 /*---------------------------------------------------------------------------*
48   Name:         FSi_IsSlash
49 
50   Description:  Internal function.
51                 Determine if a character is a directory delimiter.
52 
53   Arguments:    c: Character to determine
54 
55   Returns:      TRUE if a directory delimiting character.
56  *---------------------------------------------------------------------------*/
FSi_IsSlash(u32 c)57 SDK_INLINE BOOL FSi_IsSlash(u32 c)
58 {
59     return (c == '/') || (c == '\\');
60 }
61 
62 /*---------------------------------------------------------------------------*
63   Name:         FSi_IncrementSjisPosition
64 
65   Description:  Advances the access position of a Shift JIS string by one character.
66 
67   Arguments:    str: Pointer indicating the start of the Shift_JIS string
68                 pos: Current string reference position (in bytes)
69 
70   Returns:      The access position that results from advancing pos by one character.
71  *---------------------------------------------------------------------------*/
FSi_IncrementSjisPosition(const char * str,int pos)72 SDK_INLINE int FSi_IncrementSjisPosition(const char *str, int pos)
73 {
74     return pos + 1 + STD_IsSjisLeadByte(str[pos]);
75 }
76 
77 /*---------------------------------------------------------------------------*
78   Name:         FSi_DecrementSjisPosition
79 
80   Description:  Returns one character from the Shift_JIS string reference position.
81 
82   Arguments:    str: Pointer indicating the start of the Shift_JIS string
83                 pos: Current string reference position (in bytes)
84 
85   Returns:      pos is either one returned character from the referenced position or -1.
86  *---------------------------------------------------------------------------*/
87 int FSi_DecrementSjisPosition(const char *str, int pos);
88 
89 /*---------------------------------------------------------------------------*
90   Name:         FSi_IncrementSjisPositionToSlash
91 
92   Description:  Advances reference position of Shift_JIS string to either directory delimiter or end.
93 
94 
95   Arguments:    str: Pointer indicating the start of the Shift_JIS string
96                 pos: Current string reference position (in bytes)
97 
98   Returns:      Either first directory delimiter that appears after pos or the end position.
99  *---------------------------------------------------------------------------*/
100 int FSi_IncrementSjisPositionToSlash(const char *str, int pos);
101 
102 /*---------------------------------------------------------------------------*
103   Name:         FSi_DecrementSjisPositionToSlash
104 
105   Description:  Return reference position of Shift_JIS string to either directory separator character or beginning.
106 
107 
108   Arguments:    str: Pointer indicating the start of the Shift_JIS string
109                 pos: Current string reference position (in bytes)
110 
111   Returns:      Either first directory delimiter that appears before pos or -1.
112  *---------------------------------------------------------------------------*/
113 int FSi_DecrementSjisPositionToSlash(const char *str, int pos);
114 
115 /*---------------------------------------------------------------------------*
116   Name:         FSi_TrimSjisTrailingSlash
117 
118   Description:  Deletes if end of Shift_JIS string is a directory delimiter.
119 
120   Arguments:    str: Shift_JIS string
121 
122   Returns:      Length of string.
123  *---------------------------------------------------------------------------*/
124 int FSi_TrimSjisTrailingSlash(char *str);
125 
126 /*---------------------------------------------------------------------------*
127   Name:         FSi_StrNICmp
128 
129   Description:  Performs a case-insensitive string comparison for only the specified number of bytes.
130                 Note that this does not consider the terminating null character.
131 
132   Arguments:    str1: Source string to compare
133                 str2: Target string to compare
134                 len: Number of bytes to compare
135 
136   Returns:      The result of comparing (str1 - str2).
137  *---------------------------------------------------------------------------*/
FSi_StrNICmp(const char * str1,const char * str2,u32 len)138 SDK_INLINE int FSi_StrNICmp(const char *str1, const char *str2, u32 len)
139 {
140     int     retval = 0;
141     int     i;
142     for (i = 0; i < len; ++i)
143     {
144         u32     c = (u8)(str1[i] - 'A');
145         u32     d = (u8)(str2[i] - 'A');
146         if (c <= 'Z' - 'A')
147         {
148             c += 'a' - 'A';
149         }
150         if (d <= 'Z' - 'A')
151         {
152             d += 'a' - 'A';
153         }
154         retval = (int)(c - d);
155         if (retval != 0)
156         {
157             break;
158         }
159     }
160     return retval;
161 }
162 
163 /*---------------------------------------------------------------------------*
164   Name:         FSi_IsUnicodeSlash
165 
166   Description:  Determines whether a Unicode character is a path delimiter.
167 
168   Arguments:    c: Unicode1 character
169 
170   Returns:      TRUE if it is L'/' (0x2F) or L'\\' (0x5C).
171  *---------------------------------------------------------------------------*/
FSi_IsUnicodeSlash(u16 c)172 SDK_INLINE BOOL FSi_IsUnicodeSlash(u16 c)
173 {
174     return (c == L'/') || (c == L'\\');
175 }
176 
177 /*---------------------------------------------------------------------------*
178   Name:         FSi_DecrementUnicodePosition
179 
180   Description:  Returns one character of the Unicode string reference position.
181 
182   Arguments:    str: Pointer indicating the start of the Unicode string
183                 pos: Current string reference position (in bytes)
184 
185   Returns:      pos is either one returned character from the referenced position or -1
186  *---------------------------------------------------------------------------*/
187 int FSi_DecrementUnicodePosition(const u16 *str, int pos);
188 
189 /*---------------------------------------------------------------------------*
190   Name:         FSi_DecrementUnicodePositionToSlash
191 
192   Description:  Returns reference position of Unicode string to either directory delimiter or beginning.
193 
194 
195   Arguments:    str: Pointer indicating the start of the Unicode string
196                 pos: Current string reference position (in bytes)
197 
198   Returns:      Either first directory delimiter that appears before pos or -1.
199  *---------------------------------------------------------------------------*/
200 int FSi_DecrementUnicodePositionToSlash(const u16 *str, int pos);
201 
202 /*---------------------------------------------------------------------------*
203   Name:         FSi_WaitConditionChange
204 
205   Description:  Sleeps until any of the specified bits takes a predetermined state.
206 
207   Arguments:    flags: Group of bits to monitor
208                 on: Bit that might take the value '1'
209                 off: Bit that might take the value '0'
210                 queue: Sleep queue or NULL
211 
212   Returns:      None.
213  *---------------------------------------------------------------------------*/
FSi_WaitConditionChange(u32 * flags,u32 on,u32 off,OSThreadQueue * queue)214 SDK_INLINE void FSi_WaitConditionChange(u32 *flags, u32 on, u32 off, OSThreadQueue *queue)
215 {
216     OSIntrMode bak = OS_DisableInterrupts();
217     while ((!on || ((*flags & on) == 0)) &&
218            (!off || ((*flags & off) != 0)))
219     {
220         OS_SleepThread(queue);
221     }
222     (void)OS_RestoreInterrupts(bak);
223 }
224 
225 /*---------------------------------------------------------------------------*
226   Name:         FSi_WaitConditionOn
227 
228   Description:  Sleeps until the specified bit is 1.
229 
230   Arguments:    flags: Group of bits to monitor
231                 bits: Bit that should change to 1
232                 queue: Sleep queue or NULL
233 
234   Returns:      None.
235  *---------------------------------------------------------------------------*/
FSi_WaitConditionOn(u32 * flags,u32 bits,OSThreadQueue * queue)236 SDK_INLINE void FSi_WaitConditionOn(u32 *flags, u32 bits, OSThreadQueue *queue)
237 {
238     FSi_WaitConditionChange(flags, bits, 0, queue);
239 }
240 
241 /*---------------------------------------------------------------------------*
242   Name:         FSi_WaitConditionOff
243 
244   Description:  Sleeps until the specified bit is 0.
245 
246   Arguments:    flags: Group of bits to monitor
247                 bits: Bit that should change to 0
248                 queue: Sleep queue or NULL
249 
250   Returns:      None.
251  *---------------------------------------------------------------------------*/
FSi_WaitConditionOff(u32 * flags,u32 bits,OSThreadQueue * queue)252 SDK_INLINE void FSi_WaitConditionOff(u32 *flags, u32 bits, OSThreadQueue *queue)
253 {
254     FSi_WaitConditionChange(flags, 0, bits, queue);
255 }
256 
257 /*---------------------------------------------------------------------------*
258   Name:         FSi_GetFileLengthIfProc
259 
260   Description:  If the specified file is an archive procedure, gets the size.
261 
262   Arguments:    file: File handle
263                 length: Storage destination of the size
264 
265   Returns:      If the specified file is an archive procedure, returns its size.
266  *---------------------------------------------------------------------------*/
267 BOOL FSi_GetFileLengthIfProc(FSFile *file, u32 *length);
268 
269 /*---------------------------------------------------------------------------*
270   Name:         FSi_GetFilePositionIfProc
271 
272   Description:  If the specified file is an archive procedure, gets the current position.
273 
274   Arguments:    file: File handle
275                 length: Storage destination of the size
276 
277   Returns:      If the specified file is an archive procedure, returns its current position.
278  *---------------------------------------------------------------------------*/
279 BOOL FSi_GetFilePositionIfProc(FSFile *file, u32 *length);
280 
281 
282 /*---------------------------------------------------------------------------*/
283 
284 
285 #ifdef __cplusplus
286 } /* extern "C" */
287 #endif
288 
289 
290 #endif /* NITRO_FS_UTIL_H_ */
291