1 /*****************************************************************
5 | Copyright (c) 2002-2008, Axiomatic Systems, LLC.
8 | Redistribution and use in source and binary forms, with or without
9 | modification, are permitted provided that the following conditions are met:
10 | * Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 | * Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in the
14 | documentation and/or other materials provided with the distribution.
15 | * Neither the name of Axiomatic Systems nor the
16 | names of its contributors may be used to endorse or promote products
17 | derived from this software without specific prior written permission.
19 | THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY
20 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY
23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 ****************************************************************/
32 /*----------------------------------------------------------------------
34 +---------------------------------------------------------------------*/
37 #include "NptConstants.h"
38 #include "NptStreams.h"
39 #include "NptDataBuffer.h"
40 #include "NptLogging.h"
42 /*----------------------------------------------------------------------
44 +---------------------------------------------------------------------*/
45 NPT_SET_LOCAL_LOGGER("neptune.file")
47 /*----------------------------------------------------------------------
48 | NPT_FilePath::BaseName
49 +---------------------------------------------------------------------*/
51 NPT_FilePath::BaseName(const char* path
, bool with_extension
/* = true */)
53 NPT_String result
= path
;
54 int separator
= result
.ReverseFind(Separator
);
56 result
= path
+separator
+NPT_StringLength(Separator
);
59 if (!with_extension
) {
60 int dot
= result
.ReverseFind('.');
62 result
.SetLength(dot
);
69 /*----------------------------------------------------------------------
70 | NPT_FilePath::DirName
71 +---------------------------------------------------------------------*/
73 NPT_FilePath::DirName(const char* path
)
75 NPT_String result
= path
;
76 int separator
= result
.ReverseFind(Separator
);
79 result
.SetLength(NPT_StringLength(Separator
));
81 result
.SetLength(separator
);
90 /*----------------------------------------------------------------------
91 | NPT_FilePath::FileExtension
92 +---------------------------------------------------------------------*/
94 NPT_FilePath::FileExtension(const char* path
)
96 NPT_String result
= path
;
97 int separator
= result
.ReverseFind('.');
99 result
= path
+separator
;
107 /*----------------------------------------------------------------------
108 | NPT_FilePath::Create
109 +---------------------------------------------------------------------*/
111 NPT_FilePath::Create(const char* directory
, const char* basename
)
113 if (!directory
|| NPT_StringLength(directory
) == 0) return basename
;
114 if (!basename
|| NPT_StringLength(basename
) == 0) return directory
;
116 NPT_String result
= directory
;
117 if (!result
.EndsWith(Separator
) && basename
[0] != Separator
[0]) {
125 /*----------------------------------------------------------------------
126 | NPT_File::CreateDir
127 +---------------------------------------------------------------------*/
129 NPT_File::CreateDir(const char* path
, bool create_intermediate_dirs
)
131 NPT_String full_path
= path
;
133 // normalize path separators
134 full_path
.Replace((NPT_FilePath::Separator
[0] == '/')?'\\':'/', NPT_FilePath::Separator
);
136 // remove superfluous delimiters at the end
137 full_path
.TrimRight(NPT_FilePath::Separator
);
139 // create intermediate directories if needed
140 if (create_intermediate_dirs
) {
143 // look for the next path separator
144 int separator
= full_path
.Find(NPT_FilePath::Separator
, 1);
145 while (separator
> 0) {
146 // copy the path up to the separator
147 dir_path
= full_path
.SubString(0, separator
);
149 // create the directory non recursively
150 NPT_CHECK_WARNING(NPT_File::CreateDir(dir_path
, false));
152 // look for the next delimiter
153 separator
= full_path
.Find(NPT_FilePath::Separator
, separator
+ 1);
157 // create the final directory
158 NPT_Result result
= NPT_File::CreateDir(full_path
);
160 // return error only if file didn't exist
161 if (NPT_FAILED(result
) && result
!= NPT_ERROR_FILE_ALREADY_EXISTS
) {
169 /*----------------------------------------------------------------------
170 | NPT_File::RemoveDir
171 +---------------------------------------------------------------------*/
173 NPT_File::RemoveDir(const char* path
, bool force_if_not_empty
)
175 NPT_String root_path
= path
;
177 // normalize path separators
178 root_path
.Replace((NPT_FilePath::Separator
[0] == '/')?'\\':'/', NPT_FilePath::Separator
);
180 // remove superfluous delimiters at the end
181 root_path
.TrimRight(NPT_FilePath::Separator
);
183 // remove all entries in the directory if required
184 if (force_if_not_empty
) {
185 // enumerate all entries
186 NPT_File
dir(root_path
);
187 NPT_List
<NPT_String
> entries
;
188 NPT_CHECK_WARNING(dir
.ListDir(entries
));
189 for (NPT_List
<NPT_String
>::Iterator it
= entries
.GetFirstItem(); it
; ++it
) {
190 NPT_File::Remove(NPT_FilePath::Create(root_path
, *it
), true);
194 // remove the (now empty) directory
195 return NPT_File::RemoveDir(root_path
);
198 /*----------------------------------------------------------------------
200 +---------------------------------------------------------------------*/
202 NPT_File::Load(const char* path
, NPT_DataBuffer
& buffer
, NPT_FileInterface::OpenMode mode
)
204 // create and open the file
206 NPT_Result result
= file
.Open(mode
);
207 if (NPT_FAILED(result
)) return result
;
210 result
= file
.Load(buffer
);
218 /*----------------------------------------------------------------------
220 +---------------------------------------------------------------------*/
222 NPT_File::Load(const char* path
, NPT_String
& data
, NPT_FileInterface::OpenMode mode
)
224 NPT_DataBuffer buffer
;
226 // reset ouput params
229 // create and open the file
231 NPT_Result result
= file
.Open(mode
);
232 if (NPT_FAILED(result
)) return result
;
235 result
= file
.Load(buffer
);
237 if (NPT_SUCCEEDED(result
) && buffer
.GetDataSize() > 0) {
238 data
.Assign((const char*)buffer
.GetData(), buffer
.GetDataSize());
239 data
.SetLength(buffer
.GetDataSize());
248 /*----------------------------------------------------------------------
250 +---------------------------------------------------------------------*/
252 NPT_File::Save(const char* filename
, NPT_String
& data
)
254 NPT_DataBuffer
buffer(data
.GetChars(), data
.GetLength());
255 return NPT_File::Save(filename
, buffer
);
258 /*----------------------------------------------------------------------
260 +---------------------------------------------------------------------*/
262 NPT_File::Save(const char* filename
, const NPT_DataBuffer
& buffer
)
264 // create and open the file
265 NPT_File
file(filename
);
266 NPT_Result result
= file
.Open(NPT_FILE_OPEN_MODE_WRITE
| NPT_FILE_OPEN_MODE_CREATE
| NPT_FILE_OPEN_MODE_TRUNCATE
);
267 if (NPT_FAILED(result
)) return result
;
270 result
= file
.Save(buffer
);
278 /*----------------------------------------------------------------------
280 +---------------------------------------------------------------------*/
282 NPT_File::Load(NPT_DataBuffer
& buffer
)
284 NPT_InputStreamReference input
;
286 // get the input stream for the file
287 NPT_CHECK_WARNING(GetInputStream(input
));
290 return input
->Load(buffer
);
293 /*----------------------------------------------------------------------
295 +---------------------------------------------------------------------*/
297 NPT_File::Save(const NPT_DataBuffer
& buffer
)
299 NPT_OutputStreamReference output
;
301 // get the output stream for the file
302 NPT_CHECK_WARNING(GetOutputStream(output
));
304 // write to the stream
305 return output
->WriteFully(buffer
.GetData(), buffer
.GetDataSize());
308 /*----------------------------------------------------------------------
310 +---------------------------------------------------------------------*/
312 NPT_File::GetInfo(NPT_FileInfo
& info
)
315 info
.m_Type
= NPT_FileInfo::FILE_TYPE_SPECIAL
;
317 info
.m_Attributes
= 0;
318 info
.m_AttributesMask
= 0;
321 return GetInfo(m_Path
.GetChars(), &info
);
324 /*----------------------------------------------------------------------
326 +---------------------------------------------------------------------*/
328 NPT_File::GetSize(NPT_LargeSize
& size
)
335 NPT_Result result
= GetInfo(info
);
336 if (NPT_FAILED(result
)) {
340 switch (info
.m_Type
) {
341 case NPT_FileInfo::FILE_TYPE_DIRECTORY
: {
342 NPT_List
<NPT_String
> entries
;
343 NPT_CHECK_WARNING(ListDir(entries
));
344 size
= entries
.GetItemCount();
348 case NPT_FileInfo::FILE_TYPE_REGULAR
:
349 case NPT_FileInfo::FILE_TYPE_OTHER
:
360 /*----------------------------------------------------------------------
362 +---------------------------------------------------------------------*/
364 NPT_File::GetSize(const char* path
, NPT_LargeSize
& size
)
367 return file
.GetSize(size
);
370 /*----------------------------------------------------------------------
372 +---------------------------------------------------------------------*/
374 NPT_File::Remove(const char* path
, bool recurse
/* = false */)
378 // make sure the path exists
379 NPT_CHECK_WARNING(GetInfo(path
, &info
));
381 if (info
.m_Type
== NPT_FileInfo::FILE_TYPE_DIRECTORY
) {
382 return RemoveDir(path
, recurse
);
384 return RemoveFile(path
);
388 /*----------------------------------------------------------------------
390 +---------------------------------------------------------------------*/
392 NPT_File::Rename(const char* path
)
394 NPT_Result result
= Rename(m_Path
.GetChars(), path
);
395 if (NPT_SUCCEEDED(result
)) {
401 /*----------------------------------------------------------------------
403 +---------------------------------------------------------------------*/
405 NPT_File::ListDir(NPT_List
<NPT_String
>& entries
)
408 return ListDir(m_Path
.GetChars(), entries
);