GL Studio C++ Runtime API
file_path_class.h
Go to the documentation of this file.
1 /*! \file
2  \brief A class to handle file paths.
3 
4  \par Copyright Information
5 
6  Copyright (c) 2017 by The DiSTI Corporation.<br>
7  11301 Corporate Blvd; Suite 100<br>
8  Orlando, Florida 32817<br>
9  USA<br>
10  <br>
11  All rights reserved.<br>
12 
13  This Software contains proprietary trade secrets of DiSTI and may not be
14 reproduced, in whole or part, in any form, or by any means of electronic,
15 mechanical, or otherwise, without the written permission of DiSTI. Said
16 permission may be derived through the purchase of applicable DiSTI product
17 licenses which detail the distribution rights of this content and any
18 Derivative Works based on this or other copyrighted DiSTI Software.
19 
20  NO WARRANTY. THE SOFTWARE IS PROVIDED "AS-IS," WITHOUT WARRANTY OF ANY KIND,
21 AND ANY USE OF THIS SOFTWARE PRODUCT IS AT YOUR OWN RISK. TO THE MAXIMUM EXTENT
22 PERMITTED BY APPLICABLE LAW, DISTI AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES
23 AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24 IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY AND/OR FITNESS FOR A
25 PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT, WITH REGARD TO THE SOFTWARE.
26 
27  LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW,
28 IN NO EVENT SHALL DISTI OR ITS SUPPLIERS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
29 INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION,
30 DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
31 INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
32 INABILITY TO USE THE SOFTWARE, EVEN IF DISTI HAS BEEN ADVISED OF THE POSSIBILITY
33 OF SUCH DAMAGES. DISTI'S ENTIRE LIABILITY AND YOUR EXCLUSIVE REMEDY SHALL NOT
34 EXCEED FIVE DOLLARS (US$5.00).
35 
36  The aforementioned terms and restrictions are governed by the laws of the
37 State of Florida and the United States of America.
38 
39 */
40 #ifndef INCLUDED_FILE_PATH_CLASS_H
41 #define INCLUDED_FILE_PATH_CLASS_H
42 
43 #include "disti_metadata.h"
44 #include "util.h" // This is glstudio specific
45 #include <string>
46 
47 namespace disti
48 {
49 /** \class FilePathClass
50  *
51  * The FilePathClass represents a single absolute path.
52  * There are methods for getting the directory, filename,
53  * file extension, and checking the validity of the path.
54  * You can get a relative path string by comparing two FilePathClass objects.
55  * FilePathClass also has methods for reading/writing absolute or relative
56  * path strings, the class remembers which was last read and writes out
57  * the same way. You can change this behavior by modifying the
58  * WriteAsAbsolutePath() flag.
59  */
61 {
62 protected:
63  /** The complete path: format is "<directory>/<filename>.<extension>" where /
64  * is last slash and . is the first dot after the last slash */
65  std::string _path;
66 
67  /** Controls how the Path is written out when WritePathString is called
68  * Defaults to false */
70 
71 public:
72  /** Constructor. Path() is initially "" and invalid */
73  GLS_EXPORT FilePathClass();
74  /** Implicit conversion - Path() is set to stringPath */
75  GLS_EXPORT FilePathClass( const std::string& stringPath );
76  GLS_EXPORT FilePathClass( const char* stringPath );
77 
78  /** Return true if the path points to a directory or file that COULD exist
79  * (i.e. Path() will return a valid path as close as we can verify it.)*/
80  GLS_EXPORT bool IsValid() const;
81 
82  /** Return a string containing the characters that invalid to use in a path */
83  static GLS_EXPORT const std::string& InvalidPathChars();
84 
85  /** Return true if this file path references a file that exists.
86  * Applies only to files; returns false for directories.
87  * Returns true for symbolic links that exist, regardless whether the link's target exists.
88  */
89  GLS_EXPORT bool FileExists() const;
90 
91  /** Return true if the Directory() of this path DOES exist */
92  // Not Implemented
93  //GLS_EXPORT bool DirectoryExists() const;
94 
95  /** Create the Directory() for this path if it doesn't exist
96  * \return true if the directory exists
97  * \return false if there was an error creating the directory */
98  // Not Implemented
99  //GLS_EXPORT bool CreateDirectory() const;
100 
101  /** Return a string containing the relative path
102  * to this path from the given path's Directory
103  * Returns Path() if the relative path cannot be determined */
104  GLS_EXPORT std::string PathRelativeTo( const FilePathClass& basePath ) const;
105 
106  /** Return a string containing the complete path
107  * \note this method returns whatever is stored
108  * in the path whether it is valid or not */
109  const std::string& Path() const { return _path; }
110 
111  /** Get the directory containing the referenced file (includes trailing slash)
112  * "" if the Path is not valid */
113  GLS_EXPORT std::string Directory() const;
114 
115  /** Get the filename of the file (including the extension)
116  * "" if the Path is not valid or doesn't reference a file */
117  GLS_EXPORT std::string FileName() const;
118 
119  /** Get the file extension for the file (everything after the last ".")
120  * "" if the Path is not valid, doesn't reference a file, or the file has no extension */
121  GLS_EXPORT std::string FileExtension() const;
122 
123  /** Replace the current file extension with the specified string.
124  * This will also insert a '.' into the filename if needed.
125  * \param ext The new extension (e.g. "txt")
126  */
127  GLS_EXPORT void FileExtension( const std::string& ext );
128 
129  /** Equality operators
130  * If paths are equal they reference the same file
131  * If paths are not equal it doesn't guarantee that they reference different files */
132  GLS_EXPORT bool operator==( const FilePathClass& path ) const;
133  inline bool operator!=( const FilePathClass& path ) const { return !( *this == path ); }
134 
135  friend std::ostream& operator<<( std::ostream& outstr, const FilePathClass& path )
136  {
137  outstr << path.Path();
138  return outstr;
139  }
140 
141  friend std::istream& operator>>( std::istream& instr, FilePathClass& path )
142  {
143  instr >> path._path;
144  return instr;
145  }
146 
147  /** Assignment operator (absolute path) */
148  GLS_EXPORT FilePathClass& operator=( const FilePathClass& path );
149 
150  /** Set this object to point to the current working directory
151  * \return true on success, false if there was an error */
152  GLS_EXPORT bool SetToCWD();
153 
154  /** return true if the given string contains an absolute path */
155  static GLS_EXPORT bool StringIsAbsolutePath( const std::string& strPath );
156 
157  /** return true if the given string contains an relative path */
158  static GLS_EXPORT bool StringIsRelativePath( const std::string& strPath );
159 
160  /** return true if the given string contains a valid or absolute path as close as we can verify it */
161  static GLS_EXPORT bool StringIsValidPath( const std::string& strPath );
162 
163  /** Get and set the WriteAsAbsolutePath flag */
164  inline void WriteAsAbsolutePath( bool value ) { _writeAsAbsolutePath = value; }
165  inline bool WriteAsAbsolutePath() { return _writeAsAbsolutePath; }
166 
167  /** Read a relative or absolute path from a string
168  * \pre None
169  * \post If strPath was an absolute path or invalid then this path will be set to strPath and WriteAsAbsolutePath() will be true
170  * If strPath was relative, this path will be set to basePath + strPath and WriteAsAbsolutePath() will be false
171  * \param basePath Used to build a complete path if strPath contains a relative path
172  * \param strPath The string to read into
173  * \returns true on success or false if there was an error (basePath or strPath are invalid)
174  */
175  GLS_EXPORT bool ReadPathString( const FilePathClass& basePath, const std::string& strPath );
176 
177  /** Get the path string to write to a file
178  * This strPath will be either the absolute or relative path depending
179  * on the current setting of the WriteAsAbsolutePath() flag
180  * \param basePath Used to build a relative path if WriteAsAbsolutePath is false
181  * \param strPath The string to write to
182  */
183  GLS_EXPORT void WritePathString( const FilePathClass& basePath, std::string* strPath );
184 };
185 
186 /** Attribute for reading and writing FilePathClass objects as a clear string. */
188 {
189 protected:
190  FilePathClass* _attribPtr; // Pointer to the actual storage location
191  FilePathClass _localStoragePath; // only used by local storage constructor
192  const FilePathClass& _basePath; // Used for reading relative paths
193  bool _useEmptyTag; /**< true to use _emptyTag when writing path with WriteValue() if path does not have a filename */
194  static GLS_EXPORT const char _emptyTag[];
195 
196 public:
197  /** This constructor has the storage external
198  * \param basePath
199  * \param callback
200  * \param name
201  * \param attribPtr
202  * \param useEmptyTag [optional, defaults to false] true to use _emptyTag when writing path with WriteValue()
203  * if path does not have a filename
204  */
205  GLS_EXPORT DistiAttributeFilePathClass( const FilePathClass& basePath, CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass* attribPtr, bool useEmptyTag = false )
206  : DistiAttributeBase( callback, name, false )
207  , _attribPtr( attribPtr )
208  , _basePath( basePath )
209  , _useEmptyTag( useEmptyTag )
210  {
211  }
212 
213  /** Creates local storage, and will resize as needed
214  * \param basePath
215  * \param callback
216  * \param name
217  * \param initialValue
218  * \param useEmptyTag [optional, defaults to false] true to use _emptyTag when writing path with WriteValue()
219  * if path does not have a filename
220  */
221  GLS_EXPORT DistiAttributeFilePathClass( const FilePathClass& basePath, CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass initialValue, bool useEmptyTag = false )
222  : DistiAttributeBase( callback, name, true )
223  , _attribPtr( &_localStoragePath )
224  , _localStoragePath( initialValue )
225  , _basePath( basePath )
226  , _useEmptyTag( useEmptyTag )
227  {
228  }
229 
230  static const char* GetEmptyTag() { return _emptyTag; }
231 
232  virtual GLS_EXPORT DistiAttributeBase& operator=( const DistiAttributeBase& oldClass )
233  {
234  const DistiAttributeFilePathClass* ptr;
235  ptr = dynamic_cast<const DistiAttributeFilePathClass*>( &oldClass );
236  if( ptr )
237  {
238  *_attribPtr = *( ptr->_attribPtr );
239  CallCallback();
240  }
241  else
242  {
243  return DistiAttributeBase::operator=( oldClass );
244  }
245  return *this;
246  }
247 
248  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr )
249  {
250  if( _attribPtr )
251  {
252  std::string strPath;
253 
254  if( _useEmptyTag && _attribPtr->FileName().empty() )
255  {
256  strPath = _emptyTag;
257  }
258  else
259  {
260  _attribPtr->WritePathString( _basePath, &strPath );
261  }
262 
263  outstr << strPath;
264  }
265 
266  return outstr;
267  }
268  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr )
269  {
270  std::string strPath;
271  GetToEnd( instr, strPath, true );
272 
273  if( _attribPtr )
274  {
275  // We have to always check for the empty tag
276  // for any backward compatability
277  if( strPath == _emptyTag )
278  {
279  strPath = "";
280  }
281 
282  _attribPtr->ReadPathString( _basePath, strPath );
283  CallCallback();
284  }
285 
286  return instr;
287  }
288 };
289 
290 /** This is a FilePathClass attribute that will save/read the path relative to the current working directory. */
292 {
293  FilePathClass _parentDocumentPath; // The parent document path, this is updated when we read and write
294 public:
295  /** This constructor has the storage external */
296  GLS_EXPORT DistiAttributeCWDRelativePath( CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass* attribPtr, bool useEmptyTag = false )
297  : DistiAttributeFilePathClass( _parentDocumentPath, callback, name, attribPtr, useEmptyTag )
298  {
299  }
300 
301  /** Creates local storage, and will resize as needed */
302  GLS_EXPORT DistiAttributeCWDRelativePath( CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass initialValue, bool useEmptyTag = false )
303  : DistiAttributeFilePathClass( _parentDocumentPath, callback, name, initialValue, useEmptyTag )
304  {
305  }
306 
307  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr )
308  {
309  // update base path
310  _parentDocumentPath.SetToCWD();
311 
312  // write value as normal
314  }
315  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr )
316  {
317  // update base path
318  _parentDocumentPath.SetToCWD();
319 
320  // read value as normal
322  }
323 };
324 
325 } // end namespace disti
326 
327 #endif //_PATH_CLASS_H
std::string FileName() const
bool IsValid() const
FilePathClass & operator=(const FilePathClass &path)
The disti metadata.
virtual std::istream & ReadValue(std::istream &instr)
Definition: file_path_class.h:315
static bool StringIsValidPath(const std::string &strPath)
void WritePathString(const FilePathClass &basePath, std::string *strPath)
static bool StringIsAbsolutePath(const std::string &strPath)
bool FileExists() const
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
Definition: file_path_class.h:232
const std::string & Path() const
Definition: file_path_class.h:109
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: file_path_class.h:307
bool ReadPathString(const FilePathClass &basePath, const std::string &strPath)
std::string FileExtension() const
DistiAttributeCWDRelativePath(CallbackMethodCallerBase *callback, const AttributeName &name, FilePathClass *attribPtr, bool useEmptyTag=false)
Definition: file_path_class.h:296
virtual std::istream & ReadValue(std::istream &instr)
Definition: file_path_class.h:268
virtual void CallCallback()
DistiAttributeCWDRelativePath(CallbackMethodCallerBase *callback, const AttributeName &name, FilePathClass initialValue, bool useEmptyTag=false)
Definition: file_path_class.h:302
static const std::string & InvalidPathChars()
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: file_path_class.h:248
Generally useful defines, macros, enumerations and function prototypes.
static bool StringIsRelativePath(const std::string &strPath)
DistiAttributeFilePathClass(const FilePathClass &basePath, CallbackMethodCallerBase *callback, const AttributeName &name, FilePathClass initialValue, bool useEmptyTag=false)
Definition: file_path_class.h:221
Definition: disti_metadata.h:182
std::string Directory() const
Definition: file_path_class.h:60
Definition: callback_caller_base.h:55
std::string PathRelativeTo(const FilePathClass &basePath) const
Definition: file_path_class.h:291
bool _writeAsAbsolutePath
Definition: file_path_class.h:69
bool operator==(const FilePathClass &path) const
DistiAttributeFilePathClass(const FilePathClass &basePath, CallbackMethodCallerBase *callback, const AttributeName &name, FilePathClass *attribPtr, bool useEmptyTag=false)
Definition: file_path_class.h:205
bool _useEmptyTag
Definition: file_path_class.h:193
Definition: file_path_class.h:187
Definition: disti_metadata.h:84
Definition: bmpimage.h:46
void WriteAsAbsolutePath(bool value)
Definition: file_path_class.h:164
std::string _path
Definition: file_path_class.h:65