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_DISTI_FILE_PATH_CLASS_H
41 #define INCLUDED_DISTI_FILE_PATH_CLASS_H
42 
43 #include "disti_metadata.h"
44 #include "gls_cpp_lang_support.h"
45 #include "util.h" // This is glstudio specific
46 #include <string>
47 #include <fstream>
48 
49 namespace disti
50 {
51 /** \class FilePathClass
52  *
53  * The FilePathClass represents a single absolute path.
54  * There are methods for getting the directory, filename,
55  * file extension, and checking the validity of the path.
56  * You can get a relative path string by comparing two FilePathClass objects.
57  * FilePathClass also has methods for reading/writing absolute or relative
58  * path strings, the class remembers which was last read and writes out
59  * the same way. You can change this behavior by modifying the
60  * WriteAsAbsolutePath() flag.
61  */
63 {
64 protected:
65  /** The complete path: format is "<directory>/<filename>.<extension>" where /
66  * is last slash and . is the first dot after the last slash */
67  std::string _path;
68 
69  /** Controls how the Path is written out when WritePathString is called
70  * Defaults to false */
72 
73 public:
74  /** Default construction. Path() is initially "" and invalid */
75  GLS_EXPORT FilePathClass();
76 
77  /** Implicit conversion - Path() is set to stringPath */
78  GLS_EXPORT FilePathClass( const std::string& stringPath );
79 
80  /** Implicit conversion - Path() is set to stringPath */
81  GLS_EXPORT FilePathClass( const char* stringPath );
82 
83  /** Copy construction */
84  GLS_EXPORT FilePathClass( const FilePathClass& other )
85  {
86  *this = other;
87  }
88 
89  /** Copy assignment */
90  GLS_EXPORT FilePathClass& operator=( const FilePathClass& other )
91  {
92  if( this != &other )
93  {
94  _path = other._path;
95  _writeAsAbsolutePath = other._writeAsAbsolutePath;
96  }
97  return *this;
98  }
99 
100 #if defined( DISTI_HAS_RVAL_REFS )
101  /** Move construction */
103  {
104  *this = std::move( other );
105  }
106 
107  /** Move assignment */
109  {
110  if( this != &other )
111  {
112  _path = std::move( other._path );
113  _writeAsAbsolutePath = other._writeAsAbsolutePath;
114  }
115  return *this;
116  }
117 #endif
118 
119  /** Return true if the path points to a directory or file that COULD exist
120  * (i.e. Path() will return a valid path as close as we can verify it.)*/
121  GLS_EXPORT bool IsValid() const;
122 
123  /** Return a string containing the characters that invalid to use in a path */
124  static GLS_EXPORT const std::string& InvalidPathChars();
125 
126  /** Return true if this file path references a file that exists.
127  * Applies only to files; returns false for directories.
128  * Returns true for symbolic links that exist, regardless whether the link's target exists.
129  */
130  GLS_EXPORT bool FileExists() const;
131 
132  /** Return a string containing the relative path
133  * to this path from the given path's Directory
134  * Returns Path() if the relative path cannot be determined */
135  GLS_EXPORT std::string PathRelativeTo( const FilePathClass& basePath ) const;
136 
137  /** Return a string containing the complete path
138  * \note this method returns whatever is stored
139  * in the path whether it is valid or not */
140  const std::string& Path() const { return _path; }
141 
142  /** Get the directory containing the referenced file (includes trailing slash)
143  * "" if the Path is not valid */
144  GLS_EXPORT std::string Directory() const;
145 
146  /** Get the filename of the file (including the extension)
147  * "" if the Path is not valid or doesn't reference a file */
148  GLS_EXPORT std::string FileName() const;
149 
150  /** Get the file extension for the file (everything after the last ".")
151  * "" if the Path is not valid, doesn't reference a file, or the file has no extension */
152  GLS_EXPORT std::string FileExtension() const;
153 
154  /** Replace the current file extension with the specified string.
155  * This will also insert a '.' into the filename if needed.
156  * \param ext The new extension (e.g. "txt")
157  */
158  GLS_EXPORT void FileExtension( const std::string& ext );
159 
160  /** Equality operators
161  * If paths are equal they reference the same file
162  * If paths are not equal it doesn't guarantee that they reference different files */
163  GLS_EXPORT bool operator==( const FilePathClass& path ) const;
164  inline bool operator!=( const FilePathClass& path ) const { return !( *this == path ); }
165 
166  friend std::ostream& operator<<( std::ostream& outstr, const FilePathClass& path )
167  {
168  outstr << path.Path();
169  return outstr;
170  }
171 
172  friend std::istream& operator>>( std::istream& instr, FilePathClass& path )
173  {
174  instr >> path._path;
175  return instr;
176  }
177 
178  /** Set this object to point to the current working directory
179  * \return true on success, false if there was an error */
180  GLS_EXPORT bool SetToCWD();
181 
182  /** Get a file path set to the Current Working Directory. */
183  static GLS_EXPORT FilePathClass GetCWD()
184  {
185  FilePathClass path;
186  path.SetToCWD();
187  return path;
188  }
189 
190  /** return true if the given string contains an absolute path */
191  static GLS_EXPORT bool StringIsAbsolutePath( const std::string& strPath );
192 
193  /** return true if the given string contains an relative path */
194  static GLS_EXPORT bool StringIsRelativePath( const std::string& strPath );
195 
196  /** return true if the given string contains a valid or absolute path as close as we can verify it */
197  static GLS_EXPORT bool StringIsValidPath( const std::string& strPath );
198 
199  /** Get and set the WriteAsAbsolutePath flag */
200  inline void WriteAsAbsolutePath( bool value ) { _writeAsAbsolutePath = value; }
201  inline bool WriteAsAbsolutePath() { return _writeAsAbsolutePath; }
202 
203  /** Read a relative or absolute path from a string
204  * \pre None
205  * \post If strPath was an absolute path or invalid then this path will be set to strPath and WriteAsAbsolutePath() will be true
206  * If strPath was relative, this path will be set to basePath + strPath and WriteAsAbsolutePath() will be false
207  * \param basePath Used to build a complete path if strPath contains a relative path
208  * \param strPath The string to read into
209  * \returns true on success or false if there was an error (basePath or strPath are invalid)
210  */
211  GLS_EXPORT bool ReadPathString( const FilePathClass& basePath, const std::string& strPath );
212 
213  /** Get the path string to write to a file
214  * This strPath will be either the absolute or relative path depending
215  * on the current setting of the WriteAsAbsolutePath() flag
216  * \param basePath Used to build a relative path if WriteAsAbsolutePath is false
217  * \param strPath The string to write to
218  */
219  GLS_EXPORT void WritePathString( const FilePathClass& basePath, std::string* strPath );
220 };
221 
222 /** Attribute for reading and writing FilePathClass objects as a clear string. */
224 {
225 protected:
226  FilePathClass* _attribPtr; // Pointer to the actual storage location
227  FilePathClass _localStoragePath; // only used by local storage constructor
228  const FilePathClass& _basePath; // Used for reading relative paths
229  bool _useEmptyTag; /**< true to use _emptyTag when writing path with WriteValue() if path does not have a filename */
230  static GLS_EXPORT const char _emptyTag[];
231 
232 public:
233  /** This constructor has the storage external
234  * \param basePath
235  * \param callback
236  * \param name
237  * \param attribPtr
238  * \param useEmptyTag [optional, defaults to false] true to use _emptyTag when writing path with WriteValue()
239  * if path does not have a filename
240  */
241  GLS_EXPORT DistiAttributeFilePathClass( const FilePathClass& basePath, CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass* attribPtr, bool useEmptyTag = false )
242  : DistiAttributeBase( callback, name, false )
243  , _attribPtr( attribPtr )
244  , _basePath( basePath )
245  , _useEmptyTag( useEmptyTag )
246  {
247  }
248 
249  /** Creates local storage, and will resize as needed
250  * \param basePath
251  * \param callback
252  * \param name
253  * \param initialValue
254  * \param useEmptyTag [optional, defaults to false] true to use _emptyTag when writing path with WriteValue()
255  * if path does not have a filename
256  */
257  GLS_EXPORT DistiAttributeFilePathClass( const FilePathClass& basePath, CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass initialValue, bool useEmptyTag = false )
258  : DistiAttributeBase( callback, name, true )
259  , _attribPtr( &_localStoragePath )
260  , _localStoragePath( initialValue )
261  , _basePath( basePath )
262  , _useEmptyTag( useEmptyTag )
263  {
264  }
265 
266  static const char* GetEmptyTag() { return _emptyTag; }
267 
268  virtual GLS_EXPORT DistiAttributeBase& operator=( const DistiAttributeBase& oldClass )
269  {
270  const DistiAttributeFilePathClass* ptr;
271  ptr = dynamic_cast<const DistiAttributeFilePathClass*>( &oldClass );
272  if( ptr )
273  {
274  *_attribPtr = *( ptr->_attribPtr );
275  CallCallback();
276  }
277  else
278  {
279  return DistiAttributeBase::operator=( oldClass );
280  }
281  return *this;
282  }
283 
284  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr )
285  {
286  if( _attribPtr )
287  {
288  std::string strPath;
289 
290  if( _useEmptyTag && _attribPtr->FileName().empty() )
291  {
292  strPath = _emptyTag;
293  }
294  else
295  {
296  _attribPtr->WritePathString( _basePath, &strPath );
297  }
298 
299  outstr << strPath;
300  }
301 
302  return outstr;
303  }
304  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr )
305  {
306  std::string strPath;
307  GetToEnd( instr, strPath, true );
308 
309  if( _attribPtr )
310  {
311  // We have to always check for the empty tag
312  // for any backward compatability
313  if( strPath == _emptyTag )
314  {
315  strPath = "";
316  }
317 
318  _attribPtr->ReadPathString( _basePath, strPath );
319  CallCallback();
320  }
321 
322  return instr;
323  }
324 };
325 
326 /** This is a FilePathClass attribute that will save/read the path relative to the current working directory. */
328 {
329  FilePathClass _parentDocumentPath; // The parent document path, this is updated when we read and write
330 public:
331  /** This constructor has the storage external */
332  GLS_EXPORT DistiAttributeCWDRelativePath( CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass* attribPtr, bool useEmptyTag = false )
333  : DistiAttributeFilePathClass( _parentDocumentPath, callback, name, attribPtr, useEmptyTag )
334  {
335  }
336 
337  /** Creates local storage, and will resize as needed */
338  GLS_EXPORT DistiAttributeCWDRelativePath( CallbackMethodCallerBase* callback, const AttributeName& name, FilePathClass initialValue, bool useEmptyTag = false )
339  : DistiAttributeFilePathClass( _parentDocumentPath, callback, name, initialValue, useEmptyTag )
340  {
341  }
342 
343  virtual GLS_EXPORT std::ostream& WriteValue( std::ostream& outstr )
344  {
345  // update base path
346  _parentDocumentPath.SetToCWD();
347 
348  // write value as normal
350  }
351  virtual GLS_EXPORT std::istream& ReadValue( std::istream& instr )
352  {
353  // update base path
354  _parentDocumentPath.SetToCWD();
355 
356  // read value as normal
358  }
359 };
360 
361 } // end namespace disti
362 
363 #endif //_PATH_CLASS_H
std::string FileName() const
bool IsValid() const
The disti metadata.
FilePathClass & operator=(FilePathClass &&other)
Definition: file_path_class.h:108
virtual std::istream & ReadValue(std::istream &instr)
Definition: file_path_class.h:351
static bool StringIsValidPath(const std::string &strPath)
FilePathClass(const FilePathClass &other)
Definition: file_path_class.h:84
void WritePathString(const FilePathClass &basePath, std::string *strPath)
static bool StringIsAbsolutePath(const std::string &strPath)
FilePathClass & operator=(const FilePathClass &other)
Definition: file_path_class.h:90
bool FileExists() const
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
virtual DistiAttributeBase & operator=(const DistiAttributeBase &oldClass)
Definition: file_path_class.h:268
const std::string & Path() const
Definition: file_path_class.h:140
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: file_path_class.h:343
bool ReadPathString(const FilePathClass &basePath, const std::string &strPath)
std::string FileExtension() const
static FilePathClass GetCWD()
Definition: file_path_class.h:183
DistiAttributeCWDRelativePath(CallbackMethodCallerBase *callback, const AttributeName &name, FilePathClass *attribPtr, bool useEmptyTag=false)
Definition: file_path_class.h:332
virtual std::istream & ReadValue(std::istream &instr)
Definition: file_path_class.h:304
virtual void CallCallback()
DistiAttributeCWDRelativePath(CallbackMethodCallerBase *callback, const AttributeName &name, FilePathClass initialValue, bool useEmptyTag=false)
Definition: file_path_class.h:338
static const std::string & InvalidPathChars()
virtual std::ostream & WriteValue(std::ostream &outstr)
Definition: file_path_class.h:284
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:257
Definition: disti_metadata.h:186
std::string Directory() const
Definition: file_path_class.h:62
Definition: callback_caller_base.h:55
std::string PathRelativeTo(const FilePathClass &basePath) const
Definition: file_path_class.h:327
bool _writeAsAbsolutePath
Definition: file_path_class.h:71
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:241
bool _useEmptyTag
Definition: file_path_class.h:229
Definition: file_path_class.h:223
Macros and helper code to determine what subset of C++11/14/17 is available.
Definition: disti_metadata.h:85
FilePathClass(FilePathClass &&other)
Definition: file_path_class.h:102
Definition: bmpimage.h:46
void WriteAsAbsolutePath(bool value)
Definition: file_path_class.h:200
std::string _path
Definition: file_path_class.h:67