Angel 3.2
A 2D Game Prototyping Engine
FileUtil.cpp
1 
2 // Copyright (C) 2008-2013, Shane Liesegang
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of the copyright holder nor the names of any
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "stdafx.h"
31 #include "../Util/FileUtil.h"
32 
33 #include "../Infrastructure/Common.h"
34 #include "../Infrastructure/Log.h"
35 #include "../Util/StringUtil.h"
36 
37 #if defined(WIN32)
38  #include <shlobj.h>
39 #elif defined(__linux__)
40  #include <linux/limits.h>
41  #include <unistd.h>
42 #endif
43 #include <fstream>
44 #include <sys/types.h>
45 #include <sys/stat.h>
46 
47 
48 using namespace std;
49 
50 bool GetLinesFromFile(const String& fileName, StringList& outList )
51 {
52  ifstream inputFile( fileName.c_str() );
53  if( inputFile.is_open() )
54  {
55  while (! inputFile.eof() )
56  {
57  String line;
58  getline (inputFile,line);
59  outList.push_back( line );
60  }
61  inputFile.close();
62  return true;
63  }
64 
65  return false;
66 }
67 
68 const String ReadWholeFile(const String& fileName)
69 {
70  String forReturn = "";
71  StringList lines;
72  GetLinesFromFile(fileName, lines);
73  for (int i=0; i < lines.size(); i++)
74  {
75  forReturn += lines[i];
76  }
77  return forReturn;
78 }
79 
80 bool WriteLinesToFile( const String& fileName, const StringList& strings )
81 {
82  ofstream outputFile( fileName.c_str(), ios_base::trunc );
83  if( outputFile.is_open() )
84  {
85  for( unsigned int i = 0; i < strings.size(); i++ )
86  {
87  outputFile << strings[i] << endl;
88  }
89  outputFile.close();
90  return true;
91  }
92  return false;
93 }
94 
95 bool AppendLineToFile( const String& fileName, const String& line )
96 {
97  ofstream outputFile( fileName.c_str(), ios_base::app );
98  if( outputFile.is_open() )
99  {
100  outputFile << line << endl;
101  outputFile.close();
102  return true;
103  }
104  return false;
105 }
106 
107 bool MakeDirectories( const String& path )
108 {
109  #if defined(WIN32)
110  if (SHCreateDirectoryExA(NULL, path.c_str(), NULL) == ERROR_SUCCESS)
111  {
112  return true;
113  }
114  else
115  {
116  return false;
117  }
118  #else
119  char currentDir[PATH_MAX];
120  getcwd(currentDir, PATH_MAX);
121  chdir("/");
122  bool retVal = true;
123 
124  StringList elements = SplitString(path, "/");
125  struct stat statInfo;
126  StringList::iterator it = elements.begin();
127  String pathAccum;
128  while (it != elements.end())
129  {
130  pathAccum += *it;
131  if (stat(pathAccum.c_str(), &statInfo) < 0)
132  {
133  //path doesn't exist
134  if (mkdir(pathAccum.c_str(), S_IRWXU) != 0)
135  {
136  //couldn't be made
137  retVal = false;
138  break;
139  }
140  }
141  if (!S_ISDIR(statInfo.st_mode))
142  {
143  //exists, but it's not a directory
144  retVal = false;
145  break;
146  }
147 
148  pathAccum += "/";
149  it++;
150  }
151 
152  chdir(currentDir);
153  return retVal;
154  #endif
155 }
156 
157 const String GetStorageDirectory()
158 {
159  #if defined(WIN32)
160  return "./";
161  #elif defined(__APPLE__)
162  #if !ANGEL_MOBILE
163  String writeDirectory = getenv("HOME");
164  writeDirectory += "/Library/Application Support/Angel Games/" + GetExeName() + "/";
165  return writeDirectory;
166  #else
167  NSArray* arrayPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
168  NSString* docPath = [arrayPaths objectAtIndex:0];
169  String writeDirectory = [docPath UTF8String];
170  writeDirectory += "/" + GetExeName() + "/";
171  return writeDirectory;
172  #endif
173  #elif defined(__linux__)
174  String writeDirectory = getenv("HOME");
175  writeDirectory += "/.angel/" + GetExeName() + "/";
176  return writeDirectory;
177  #endif
178 }
179 
180 const String GetDocumentsPath()
181 {
182  #if defined(WIN32)
183  char myDocs[MAX_PATH];
184  HRESULT result = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, myDocs);
185  if (result != S_OK)
186  {
187  sysLog.Log("ERROR: Couldn't get path to \"My Documents\" directory.");
188  return String("");
189  }
190  else
191  {
192  return String(myDocs);
193  }
194  #elif defined(__APPLE__)
195  String path = getenv("HOME");
196  return path + "/Documents/";
197  #elif defined(__linux__)
198  String path = getenv("HOME");
199  return path + "/Documents/";
200  #endif
201 }
202 
203 const String GetExeName()
204 {
205  String pathSplit = "/";
206  #if defined (WIN32)
207  TCHAR exePathWin[MAX_PATH];
208  GetModuleFileName( NULL, exePathWin, MAX_PATH );
209  String exePath(exePathWin);
210  int length = exePath.length();
211  if (exePath.substr(length - 4, length) == ".exe")
212  {
213  exePath = exePath.substr(0, length - 4);
214  }
215  pathSplit = "\\";
216  #elif defined (__APPLE__)
217  CFBundleRef mainBundle = CFBundleGetMainBundle();
218  CFURLRef exeURL = CFBundleCopyExecutableURL(mainBundle);
219  char exePath[PATH_MAX];
220  if (!CFURLGetFileSystemRepresentation(exeURL, TRUE, (UInt8 *)exePath, PATH_MAX))
221  {
222  CFRelease(exeURL);
223  sysLog.Log("Couldn't get exe name.");
224  return "";
225  }
226  CFRelease(exeURL);
227  #elif defined (__linux__)
228  String exePath = ReadWholeFile("/proc/self/cmdline");
229  String splitChars = "";
230  splitChars.push_back('\0'); // have to construct null-containing strings carefully
231  exePath = SplitString(exePath, splitChars)[0];
232  #endif
233 
234  StringList pathElements = SplitString(exePath, pathSplit);
235  String exeName = pathElements[pathElements.size()-1];
236 
237  return exeName;
238 }
239 
240 const long GetModificationTime(const String& fileName)
241 {
242  struct stat statInfo;
243  if (stat(fileName.c_str(), &statInfo) != -1)
244  {
245  #if defined(__APPLE__)
246  return statInfo.st_mtimespec.tv_sec;
247  #else //Linux or Windows
248  return statInfo.st_mtime;
249  #endif
250  }
251  else
252  {
253  return 0;
254  }
255 }