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