Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/util/filesys/file.cc @ 8372

Last change on this file since 8372 was 8333, checked in by bensch, 18 years ago

trunk: some nicer updates

File size: 7.3 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16#include "file.h"
17
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <stdio.h>
21
22#include <iostream>
23#include <fstream>
24
25#ifdef __unix__
26#include <unistd.h>
27#elif __WIN32__ || _MS_DOS_
28#include <dir.h>
29#else
30//#include <direct.h>
31#endif
32
33/**
34 * @brief default constructor.
35 */
36File::File()
37{
38  this->init();
39}
40
41/**
42 * @brief A File will be constructed and stated from a given FileName.
43 * @param fileName the FileName to load and stat.
44 */
45File::File(const std::string& fileName)
46{
47  this->init();
48  this->setFileName(fileName);
49}
50
51/**
52 * @brief A File will be constructed and stated from a given other File.
53 * @param file the File to get the Name from.
54 */
55File::File(const File& file)
56{
57  this->init();
58  this->setFileName(file.name());
59}
60
61File::~File()
62{
63  this->close();
64
65  if (this->_status)
66    delete this->_status;
67}
68
69
70/**
71 * @brief initializes the File
72 *
73 * Stats the File, looks if it exists and sets the hadle to 0
74 */
75void File::init()
76{
77  this->_handle = 0;
78  this->_status = NULL;
79}
80
81
82/**
83 * @brief sets a new File to apply to this File.
84 * @param fileName the Filename of the File to access.
85 */
86void File::setFileName(const std::string& fileName)
87{
88  this->close();
89  this->_name = fileName;
90  File::homeDirCheck(this->_name);
91  this->statFile();
92}
93
94/**
95 * @brief sets the file to the new File.
96 * @param fileName the FileName to set the File to.
97 * @returns this File.
98 */
99File& File::operator=(const std::string& fileName)
100{
101  this->setFileName(fileName);
102  return *this;
103}
104
105/**
106 * @brief sets the file to the new File.
107 * @param file the File to set the File to.
108 * @returns this File.
109 */
110File& File::operator=(const File& file)
111{
112  this->setFileName(file.name());
113  return *this;
114}
115
116/**
117 * @brief compares two files.
118 * @param fileName the File to compare against the stored one.
119 * @returns true if the filenames match.
120 */
121bool File::operator==(const std::string& fileName) const
122{
123  return (this->_name == fileName);
124}
125
126/**
127 * @brief compares two files.
128 * @param file the File to compare against the stored one.
129 * @returns true if the filenames match.
130 */
131bool File::operator==(const File& file) const
132{
133  return (this->_name == file.name());
134}
135
136
137/**
138 * @brief stats a File.
139 * Gathers information about the File, like permissions, and if it exists.
140 */
141void File::statFile()
142{
143  if (this->_status == NULL)
144    this->_status = new struct stat;
145  // Check the End of the FileName and chop away any \ and //
146  std::string name = this->_name;
147  while (name[name.size()-1] == '/' ||
148         name[name.size()-1] == '\\')
149    name.resize(name.size()-1);
150  if (stat(name.c_str(), this->_status))
151  {
152    delete this->_status;
153    this->_status = NULL;
154  }
155}
156
157bool File::open(OpenMode mode)
158{
159#warning implement
160  return false;
161}
162
163bool File::close()
164{
165#warning implement
166  return false;
167}
168
169bool File::exists() const
170{
171  return (this->_status != NULL);
172}
173
174/**
175 * @brief checks if the file is a Link (symlink/hardlink on UNIX)
176 * @returns true if the File is a Link, false otherwise (on windows always false)
177 */
178bool File::isLink() const
179{
180#ifndef __WIN32__
181  return (this->_status != NULL && this->_status->st_mode & (S_IFLNK));
182#else
183  return false;
184#endif
185}
186
187/**
188 * @brief checks if the File is a regular File
189 * @returns true if the File is a Regular file.
190 */
191bool File::isFile() const
192{
193  return (this->_status != NULL && this->_status->st_mode & (S_IFREG));
194}
195
196/**
197 * @brief Checks if the File is a Directory
198 * @returns true if it is a directory/symlink false otherwise
199 */
200bool File::isDirectory() const
201{
202  return (this->_status != NULL && this->_status->st_mode & (S_IFDIR));
203}
204
205
206/// FIXME NEXT THREE FUNCTIONS
207bool File::isReadeable() const
208{
209#ifndef __WIN32__
210  return (this->_status != NULL && this->_status->st_mode & (S_IRUSR));
211#else
212  return (this->_status != NULL);
213#endif
214}
215bool File::isWriteable() const
216{
217#ifndef __WIN32__
218  return (this->_status != NULL && this->_status->st_mode & (S_IWUSR));
219#else
220  return (this->_status != NULL);
221#endif
222}
223bool File::isExecutable() const
224{
225#ifndef __WIN32__
226  return (this->_status != NULL && this->_status->st_mode & (S_IXUSR));
227#else
228  return (this->_status != NULL);
229#endif
230}
231
232/**
233 * @brief copies the File to another File.
234 * @param destination the Destination File.
235 * @returns true on success, false otherwise.
236 */
237bool File::copy(const File& destination)
238{
239  if (*this == destination)
240  {
241    std::cout << "files are the Same '" << this->_name << "'\n";
242    return false;
243  }
244  char ch;
245  std::ifstream iFile(this->_name.c_str());
246  std::ofstream oFile(destination.name().c_str());
247  while (iFile.get(ch))
248  {
249    oFile.put(ch);
250  }
251  return true;
252}
253
254/**
255 * @brief renames the File (move)
256 * @param destination the Destination to move this file to.
257 * @returns true on success, false otherwise.
258 *
259 * if the File was opened, it will be closed throuh this function.
260 * The File will also be closed, if the File was not renamed.
261 */
262bool File::rename(const File& destination)
263{
264  this->close();
265
266  if (!std::rename(this->_name.c_str(), destination.name().c_str()))
267  {
268    this->_name = destination.name();
269    this->statFile();
270    return true;
271  }
272  return false;
273}
274
275/**
276 * @brief touches the File.
277 * @returns true if the file could have been touched. false otherwise.
278 *
279 * Touching a File means creating it.
280 */
281bool File::touch()
282{
283  FILE* stream;
284  if( (stream = fopen (this->_name.c_str(), "w")) == NULL)
285  {
286    std::cout << "could not touch '" << this->_name << "' for writing\n";
287    return false;
288  }
289  fclose(stream);
290
291  this->statFile();
292  return true;
293}
294
295/**
296 * @brief delete the File on the Disk
297 * @returns true on success, false otherwise.
298 */
299bool File::remove()
300{
301  if (!this->exists())
302    return false;
303
304  this->close();
305  unlink(this->_name.c_str());
306  delete this->_status;
307  this->_status = NULL;
308
309  return true;
310}
311
312/**
313 * @brief transforms a Relative path to an absolute one.
314 * @param fileName the Absolute Path.
315 */
316void File::relToAbs(std::string& relFileName)
317{
318  if (relFileName.empty())
319    return ;
320  if (relFileName[0] !=  '/')
321  {
322    if (relFileName[0] == '.' && relFileName[1] != '.')
323      relFileName.erase(0);
324    relFileName = File::cwd() + relFileName;
325  }
326}
327
328void File::absToRel(std::string& absFileName)
329{
330  if (absFileName.find(cwd()) == 0)
331    absFileName.replace(0, File::cwd().size(), ".");
332}
333
334
335std::string File::_cwd = "";
336
337/**
338 * @returns the Current Woring Directory
339 */
340const std::string& File::cwd()
341{
342  if (File::_cwd.empty())
343  {
344    char cwd[1024];
345    char* errorCode = getcwd(cwd, 1024);
346    if (errorCode == 0)
347      return File::_cwd;
348
349    File::_cwd = cwd;
350  }
351  return File::_cwd;
352}
353
354/**
355 * @brief check if fileName has the '~/` prepended.
356 * @returns the fileName in absolute coordinate.
357 */
358void File::homeDirCheck(std::string& fileName)
359{
360  if (fileName.size() < 2 || fileName[0] != '~' || fileName[1] != '/')
361    return;
362  std::string homeDir;
363#ifdef __WIN32__
364  homeDir = getenv("USERPROFILE");
365#else
366  homeDir = getenv("HOME");
367#endif
368  fileName = homeDir + fileName.substr(1);
369}
Note: See TracBrowser for help on using the repository browser.