nux-1.16.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "NuxCore.h" 00024 #include "Math/MathUtility.h" 00025 00026 namespace nux 00027 { 00028 00029 #define COPYBLOCKSIZE 32768 00030 00031 00032 int NFileManagerGeneric::Copy (const TCHAR *InDestFile, const TCHAR *InSrcFile, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor *Monitor) 00033 { 00034 // Direct file copier. 00035 if (Monitor && !Monitor->Progress (0.0) ) 00036 { 00037 return COPY_CANCELED; 00038 } 00039 00040 int Result = COPY_OK; 00041 NString SrcFile = InSrcFile; 00042 NString DestFile = InDestFile; 00043 00044 NSerializer *Src = CreateFileReader (SrcFile.GetTCharPtr() ); 00045 00046 if (!Src) 00047 { 00048 Result = COPY_READFAIL; 00049 } 00050 else 00051 { 00052 t_u32 Size = Src->GetFileSize(); 00053 NSerializer *Dest = CreateFileWriter (DestFile.GetTCharPtr(), (OverWriteExisting ? 0 : FILEWRITE_NOREPLACEEXISTING) | (OverWriteReadOnly ? FILEWRITE_EVENIFREADONLY : 0) ); 00054 00055 if (!Dest) 00056 { 00057 Result = COPY_WRITEFAIL; 00058 } 00059 else 00060 { 00061 t_u32 Percent = 0, NewPercent = 0; 00062 BYTE Buffer[COPYBLOCKSIZE]; 00063 00064 for (t_u32 Total = 0; Total < Size; Total += sizeof (Buffer) ) 00065 { 00066 t_u32 Count = Min<t_u32> (Size - Total, (t_u32) sizeof (Buffer) ); 00067 Src->Serialize (Buffer, Count); 00068 00069 if (Src->IsError() ) 00070 { 00071 Result = COPY_READFAIL; 00072 break; 00073 } 00074 00075 Dest->Serialize (Buffer, Count); 00076 00077 if (Dest->IsError() ) 00078 { 00079 Result = COPY_WRITEFAIL; 00080 break; 00081 } 00082 00083 NewPercent = Total * 100 / Size; 00084 00085 if (Monitor && Percent != NewPercent && !Monitor->Progress ( (float) NewPercent / 100.f) ) 00086 { 00087 Result = COPY_CANCELED; 00088 break; 00089 } 00090 00091 Percent = NewPercent; 00092 } 00093 00094 if (Result == COPY_OK) 00095 { 00096 if (!Dest->Close() ) 00097 { 00098 Result = COPY_WRITEFAIL; 00099 } 00100 } 00101 00102 delete Dest; 00103 00104 if (Result != COPY_OK) 00105 { 00106 Delete (DestFile.GetTCharPtr() ); 00107 } 00108 } 00109 00110 if (Result == COPY_OK) 00111 { 00112 if (!Src->Close() ) 00113 { 00114 Result = COPY_READFAIL; 00115 } 00116 } 00117 00118 delete Src; 00119 } 00120 00121 if (Monitor && Result == COPY_OK && !Monitor->Progress (1.0) ) 00122 { 00123 Result = COPY_CANCELED; 00124 } 00125 00126 return Result; 00127 } 00128 00129 bool NFileManagerGeneric::IsDrive (const TCHAR *Path) 00130 { 00131 // Does Path refer to a drive letter or UNC path? 00132 // A UNC is a naming convention that permits you to use a network resource, 00133 // such as a network server, without formally connecting to the network resource 00134 // with a mapped drive. A UNC path uses the following syntax: 00135 // \<Server><Share> 00136 // The share is a drive: D:\Folder of ServerA = "\\ServerA\D\Folder" 00137 00138 if (Stricmp (Path, TEXT ("") ) == 0) 00139 return 1; 00140 else if ( (ToUpperCase (Path[0]) != ToLowerCase (Path[0]) ) && (Path[1] == TEXT (':') ) && (Path[2] == 0) ) // look for "a:", "c:", "d:" ... 00141 return 1; 00142 else if (Stricmp (Path, TEXT ("\\") ) == 0) // look for "\" 00143 return 1; 00144 else if (Stricmp (Path, TEXT ("\\\\") ) == 0) // look for "\\" 00145 return 1; 00146 else if (Path[0] == TEXT ('\\') && Path[1] == TEXT ('\\') && !Strchr (Path + 2, TEXT ('\\') ) ) // look for "\\Server" 00147 return 1; 00148 else if (Path[0] == TEXT ('\\') && Path[1] == TEXT ('\\') && Strchr (Path + 2, TEXT ('\\') ) && !Strchr (Strchr (Path + 2, TEXT ('\\') ) + 1, TEXT ('\\') ) ) 00149 // look for "\\Server\share" 00150 return 1; 00151 else 00152 return 0; 00153 } 00154 00155 bool NFileManagerGeneric::MakeDirectory (const TCHAR *Path, bool CreateCompletePath) 00156 { 00157 // Support code for making a directory tree. 00158 nuxAssert (CreateCompletePath); 00159 t_u32 SlashCount = 0, CreateCount = 0; 00160 00161 for (TCHAR Full[256] = TEXT (""), *Ptr = Full; ; *Ptr++ = *Path++) 00162 { 00163 if ( (*Path == NUX_BACKSLASH_CHAR) || (*Path == NUX_SLASH_CHAR) || (*Path == 0) ) 00164 { 00165 if ( (SlashCount++ > 0) && !IsDrive (Full) ) 00166 { 00167 *Ptr = 0; 00168 00169 if (MakeDirectory (Full, 0) != NUX_OK) 00170 return 0; 00171 00172 CreateCount++; 00173 } 00174 } 00175 00176 if (*Path == 0) 00177 break; 00178 } 00179 00180 return CreateCount != 0; 00181 } 00182 00183 bool NFileManagerGeneric::DeleteDirectory (const TCHAR *Path, bool DeleteContentFirst) 00184 { 00185 nuxAssert (DeleteContentFirst); 00186 nuxAssert (Path != NULL); 00187 00188 t_size PathLength = StringLength (Path); 00189 00190 if (PathLength == 0) 00191 return false; 00192 00193 NString WildcardPath = NString (Path); 00194 00195 if ( (WildcardPath[PathLength - 1] != NUX_BACKSLASH_CHAR) && (WildcardPath[PathLength - 1] != NUX_SLASH_CHAR) ) 00196 WildcardPath += NUX_BACKSLASH_CHAR; 00197 00198 WildcardPath += TEXT ("*"); 00199 00200 std::vector<NString> List; 00201 FindFiles (List, *WildcardPath, 1, 0); 00202 00203 for (t_u32 i = 0; i < List.size(); i++) 00204 { 00205 if (!Delete (* (NString (Path) + NUX_BACKSLASH_CHAR + List[i]), 1) ) 00206 return 0; 00207 } 00208 00209 List.clear(); 00210 FindFiles (List, *WildcardPath, 0, 1); 00211 00212 for (t_u32 i = 0; i < List.size(); i++) 00213 { 00214 if (!DeleteDirectory (* (NString (Path) + NUX_BACKSLASH_CHAR + List[i]), true) ) 00215 return 0; 00216 } 00217 00218 List.clear(); 00219 return DeleteDirectory (Path, false); 00220 } 00221 00222 bool NFileManagerGeneric::Move (const TCHAR *Dest, const TCHAR *Src, bool OverWriteExisting, bool OverWriteReadOnly, NFileTransferMonitor *Monitor) 00223 { 00224 // Move file manually. 00225 if (Copy (Dest, Src, OverWriteExisting, OverWriteReadOnly, NULL) != COPY_OK) 00226 return 0; 00227 00228 Delete (Src, 1); 00229 return 1; 00230 } 00231 00232 00233 int NFileManagerGeneric::CreateUniqueFileName (const TCHAR *Filename, const TCHAR *Extension, NString &OutputFilename, unsigned int BaseIndex) 00234 { 00235 nuxAssert (Filename); 00236 nuxAssert (Extension); 00237 00238 NString FullPath (Filename); 00239 const t_size IndexMarker = FullPath.Length(); // Marks location of the four-digit index. 00240 FullPath += TEXT ("0000."); 00241 FullPath += Extension; 00242 00243 // Iterate over indices, searching for a file that doesn't exist. 00244 for (DWORD i = BaseIndex + 1 ; i < 10000 ; ++i) 00245 { 00246 FullPath[IndexMarker ] = i / 1000 + TEXT ('0'); 00247 FullPath[IndexMarker+1] = (i / 100) % 10 + TEXT ('0'); 00248 FullPath[IndexMarker+2] = (i / 10) % 10 + TEXT ('0'); 00249 FullPath[IndexMarker+3] = i % 10 + TEXT ('0'); 00250 00251 if (GFileManager.FileSize (FullPath.GetTCharPtr() ) == -1) 00252 { 00253 // The file doesn't exist; output success. 00254 OutputFilename = FullPath; 00255 return static_cast<int> (i); 00256 } 00257 } 00258 00259 // Can't find an empty filename slot with index in (StartVal, 9999]. 00260 return -1; 00261 } 00262 00263 } 00264