OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimFilename.cpp
Go to the documentation of this file.
1 //---
2 //
3 // License: MIT
4 //
5 // Description: This class provides manipulation of filenames.
6 //
7 //---
8 // $Id$
9 
10 #include <ossim/ossimConfig.h> /* to pick up platform defines */
11 
14 #include <ossim/base/ossimCommon.h>
17 #include <ossim/base/ossimDate.h>
19 #include <ossim/base/ossimNotify.h>
20 #include <ossim/base/ossimRegExp.h>
22 
23 
24 #include <cstdio>
25 #include <cstdlib>
26 #include <cstring>
27 #include <cerrno>
28 #include <iostream>
29 #include <fstream>
30 using namespace std;
31 
32 #if defined(_WIN32)
33 # include <io.h>
34 # include <direct.h>
35 # include <sys/utime.h>
36 # include <windows.h>
37 #else
38 # include <sys/types.h>
39 # include <utime.h>
40 # include <sys/stat.h>
41 # include <unistd.h>
42 # include <dirent.h>
43 # include <fcntl.h>
44 #endif
45 
46 #include <sys/stat.h>
47 
48 #ifdef __BORLANDC__
49 # include <dir.h>
50 # include <direct.h>
51 # include <stdlib.h>
52 # include <io.h>
53 #endif
54 
55 #if defined(_WIN32)
57 #else
59 #endif
60 
61 // Internal ossimFilename separator.
63 
64 
68 #if defined(_WIN32)
69 typedef WIN32_FIND_DATA FIND_STRUCT;
70 typedef HANDLE FIND_DATA;
71 typedef DWORD FIND_ATTR;
72 
73 class ossimFileHandle
74 {
75 public:
76  enum OpenMode
77  {
78  Read,
79  Write
80  };
81 
82  ossimFileHandle(const ossimString& filename, OpenMode mode)
83  {
84  m_hFile = ::CreateFile(
85  filename.c_str(), // name
86  mode == Read ? GENERIC_READ // access mask
87  : GENERIC_WRITE,
88  FILE_SHARE_READ | // sharing mode
89  FILE_SHARE_WRITE, // (allow everything)
90  NULL, // no secutity attr
91  OPEN_EXISTING, // creation disposition
92  0, // no flags
93  NULL // no template file
94  );
95 
96  if ( m_hFile == INVALID_HANDLE_VALUE )
97  {
98 // wxLogSysError(_("Failed to open '%s' for %s"),
99 // filename.c_str(),
100 // mode == Read ? _("reading") : _("writing"));
101  }
102  }
103 
104  ~ossimFileHandle()
105  {
106  if ( m_hFile != INVALID_HANDLE_VALUE )
107  {
108  if ( !::CloseHandle(m_hFile) )
109  {
110 // wxLogSysError(_("Failed to close file handle"));
111  }
112  }
113  }
114 
115  // return true only if the file could be opened successfully
116  bool isOk() const { return m_hFile != INVALID_HANDLE_VALUE; }
117 
118  // get the handle
119  operator HANDLE() const { return m_hFile; }
120 
121 private:
122  HANDLE m_hFile;
123 };
124 
125 static void convertOssimToFileTime(FILETIME *ft, const ossimDate& dt)
126 {
127  SYSTEMTIME st;
128  st.wDay = dt.getDay();
129  st.wMonth = (WORD)(dt.getMonth());
130  st.wYear = (WORD)dt.getYear();
131  st.wHour = dt.getHour();
132  st.wMinute = dt.getMin();
133  st.wSecond = dt.getSec();
134 // st.wMilliseconds = dt.GetMillisecond();
135 
136  FILETIME ftLocal;
137  if ( !::SystemTimeToFileTime(&st, &ftLocal) )
138  {
139 // wxLogLastError(_T("SystemTimeToFileTime"));
140  }
141 
142  if ( !::LocalFileTimeToFileTime(&ftLocal, ft) )
143  {
144 // wxLogLastError(_T("LocalFileTimeToFileTime"));
145  }
146 }
147 
148 static void convertFileTimeToOssim(ossimLocalTm &dt, const FILETIME &ft)
149 {
150  FILETIME ftcopy = ft;
151  FILETIME ftLocal;
152  if ( !::FileTimeToLocalFileTime(&ftcopy, &ftLocal) )
153  {
154 // wxLogLastError(_T("FileTimeToLocalFileTime"));
155  }
156 
157  SYSTEMTIME st;
158  if ( !::FileTimeToSystemTime(&ftLocal, &st) )
159  {
160 // wxLogLastError(_T("FileTimeToSystemTime"));
161  }
162 
163  dt.setDay(st.wDay);
164  dt.setMonth(st.wMonth);
165  dt.setYear(st.wYear);
166  dt.setHour(st.wHour);
167  dt.setMin(st.wMinute);
168  dt.setSec(st.wSecond);
169 
170 // dt->Set(st.wDay, wxDateTime::Month(st.wMonth - 1), st.wYear,
171 // st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
172 }
173 
174 static inline bool IsFindDataOk(FIND_DATA fd)
175 {
176  return fd != INVALID_HANDLE_VALUE;
177 }
178 
179 static inline FIND_DATA FindFirst(const ossimString& spec,
180  FIND_STRUCT *finddata)
181 {
182  return ::FindFirstFile(spec.c_str(), finddata);
183 }
184 
185 static bool ossimGetDirectoryTimes(const ossimString& dirname,
186  FILETIME *ftAccess,
187  FILETIME *ftCreate,
188  FILETIME *ftMod)
189 {
190 
191  FIND_STRUCT fs;
192  FIND_DATA fd = FindFirst(dirname, &fs);
193  if ( !IsFindDataOk(fd) )
194  {
195  return false;
196  }
197 
198  *ftAccess = fs.ftLastAccessTime;
199  *ftCreate = fs.ftCreationTime;
200  *ftMod = fs.ftLastWriteTime;
201 
202  FindClose(fd);
203 
204  return true;
205 }
206 #endif
207 
209 
211  : ossimString()
212 {}
213 
215  : ossimString(src)
216 {
217 }
218 
220  : ossimString(src)
221 {
222  if ( m_str.size() )
223  {
225  // convertToNative();
226  }
227 }
228 
229 ossimFilename::ossimFilename(const std::string& src)
230  : ossimString(src)
231 {
232  if ( m_str.size() )
233  {
235  // convertToNative();
236  }
237 }
238 
240  : ossimString(src)
241 {
242  if ( m_str.size() )
243  {
245  // convertToNative();
246  }
247 }
248 
250 {
251  if ( this != &f )
252  {
253  m_str = f.m_str;
254  }
255  return *this;
256 }
257 
258 template <class Iter> ossimFilename::ossimFilename(Iter s, Iter e)
259  : ossimString(s, e)
260 {
261  if ( m_str.size() )
262  {
264  // convertToNative();
265  }
266 }
267 
269 {
270  return ossimString::operator==(rhs);
271 }
272 
274 {
275  return ossimString::operator==(rhs);
276 }
277 
278 bool ossimFilename::operator == (const char* rhs)const
279 {
280  return ossimString::operator ==(rhs);
281 }
282 
283 #if 0
284 void ossimFilename::convertBackToForwardSlashes()
285 {
286  std::string::iterator currentChar = this->begin();
287 
288  while(currentChar != this->end())
289  {
290  if(*currentChar == '\\')
291  {
292  *currentChar = '/';
293  }
294  ++currentChar;
295  }
296 }
297 
298 void ossimFilename::convertForwardToBackSlashes()
299 {
300  std::string::iterator currentChar = this->begin();
301 
302  while(currentChar != this->end())
303  {
304  if(*currentChar == '/')
305  {
306  *currentChar = '\\';
307  }
308  ++currentChar;
309  }
310  m_pathSeparator = '\\';
311 }
312 #endif
313 
315  ossimLocalTm* modTime,
316 #if defined(_WIN32)
317  ossimLocalTm* createTime)const
318 #else
319  ossimLocalTm* /* createTime */ )const
320 #endif
321 {
322 #if defined(_WIN32)
323  if(isDir())
324  {
325  // need to implement this later
326  return false;
327  }
328  else
329  {
330  ossimFileHandle fh(this->expand(), ossimFileHandle::Write);
331  if(fh.isOk())
332  {
333  FILETIME ftAccess, ftCreate, ftWrite;
334 
335  if ( createTime )
336  {
337  convertOssimToFileTime(&ftCreate, *createTime);
338  }
339  if ( accessTime )
340  {
341  convertOssimToFileTime(&ftAccess, *accessTime);
342  }
343  if ( modTime )
344  {
345  convertOssimToFileTime(&ftWrite, *modTime);
346  }
347  if ( ::SetFileTime(fh,
348  createTime ? &ftCreate : NULL,
349  accessTime ? &ftAccess : NULL,
350  modTime ? &ftWrite : NULL) )
351  {
352  return true;
353  }
354  }
355  }
356 #else
357  if ( !accessTime && !modTime )
358  {
359  // can't modify the creation time anyhow, don't try
360  return true;
361  }
362  utimbuf utm;
363  utm.actime = accessTime ? accessTime->getTicks() : modTime->getTicks();
364  utm.modtime = modTime ? modTime->getTicks() : accessTime->getTicks();
365  if ( utime(expand().c_str(), &utm) == 0 )
366  {
367  return true;
368  }
369 
370 #endif
371 
372  return false;
373 }
374 
376  ossimLocalTm *modTime,
377  ossimLocalTm *createTime) const
378 {
379  if(!expand().exists()) return false;
380 
381 #if defined(_WIN32)
382  // we must use different methods for the files and directories under
383  // Windows as CreateFile(GENERIC_READ) doesn't work for the directories and
384  // CreateFile(FILE_FLAG_BACKUP_SEMANTICS) works -- but only under NT and
385  // not 9x
386  bool ok;
387  FILETIME ftAccess, ftCreate, ftWrite;
388  if ( isDir() )
389  {
390  ok = ossimGetDirectoryTimes(expand().c_str(),
391  &ftAccess, &ftCreate, &ftWrite);
392  ok = false;
393  }
394  else // file
395  {
396  ossimFileHandle fh(expand().c_str(), ossimFileHandle::Read);
397  if ( fh.isOk() )
398  {
399  ok = ::GetFileTime(fh,
400  createTime ? &ftCreate : NULL,
401  accessTime ? &ftAccess : NULL,
402  modTime ? &ftWrite : NULL) != 0;
403  }
404  else
405  {
406  ok = false;
407  }
408  }
409 
410  if ( ok )
411  {
412  if ( createTime )
413  {
414  convertFileTimeToOssim(*createTime, ftCreate);
415  }
416  if ( accessTime )
417  {
418  convertFileTimeToOssim(*accessTime, ftAccess);
419  }
420  if ( modTime )
421  {
422  convertFileTimeToOssim(*modTime, ftWrite);
423  }
424 
425  return true;
426  }
427 #else
428  struct stat sbuf;
429  stat(c_str(), &sbuf);
430  if ( stat( expand().c_str(), &sbuf) == 0 )
431  {
432  if ( accessTime )
433  {
434  *accessTime = ossimLocalTm(sbuf.st_atime);
435  }
436  if ( modTime )
437  {
438  *modTime = ossimLocalTm(sbuf.st_mtime);
439  }
440  if ( createTime )
441  {
442  *createTime = ossimLocalTm(sbuf.st_ctime);
443  }
444  return true;
445  }
446 #endif // platforms
447 
448 
449  return false;
450 }
451 
452 // Time in seconds since last accessed.
454 {
455  ossim_int64 result = -1;
456 
457  if( expand().exists() )
458  {
459  ossim_int64 currentTime = ossim::getTime();
460 
461 #if defined(_WIN32)
462  cerr << "ossimFilename::lastAccessed() not implemented for windows!" << endl;
463 #else
464  struct stat sbuf;
465  stat(c_str(), &sbuf);
466  if ( stat( expand().c_str(), &sbuf) == 0 )
467  {
468  time_t atime = sbuf.st_atime; // This cast to seconds(time_t).
469  result = currentTime - (ossim_int64)atime;
470  }
471 #endif // platforms
472  }
473 
474  return result;
475 }
476 
478 {
479 #if defined( _WIN32 )
480  ossimDate now;
481 
482  return setTimes(&now, &now, 0);
483 
484 #else
485  if ( utime(expand().c_str(), NULL) == 0 )
486  {
487  return true;
488  }
489 
490  return false;
491 #endif
492 }
493 
495 {
496  //---
497  // Note: ossimEnvironmentUtility::getCurrentWorkingDir() is returning
498  // a blank string on windows with vs9. This was resulting in seg faults
499  // in this method so added checks were added for size of returned result.
500  // (drb 20100113)
501  //---
502  ossimFilename result = "";
503  if ( size() )
504  {
505  result = *this;
506 
507  if ( needsExpansion() )
508  {
509 
510 //#if defined(_WIN32)
511 // result.convertBackToForwardSlashes();
512 //#endif
513 
514  bool addCwd = false;
515 
516  if ( (size() > 1) && (*(begin()) == '~') && (*(begin()+1) == OSSIM_FILENAME_PATH_SEPARATOR) )
517  {
518  ossimFilename homeDir =
520 
521  ossimFilename s( (result.begin()+2) , result.end());
522  result = homeDir.dirCat(s);
523  }
524  else if( (size() > 1) &&
525  (*(begin()) == '.') && (*(begin()+1) == OSSIM_FILENAME_PATH_SEPARATOR) )
526  {
527  // dot slash i.e. ./foo
528  addCwd = true;
529  }
530  else if ( (size() > 2) && (*(begin()) == '.')
531  && (*(begin()+1) == '.') && (*(begin()+2) == OSSIM_FILENAME_PATH_SEPARATOR) )
532  {
533  // ../foo
534  addCwd = true;
535  }
536  else if (result == ".")
537  {
539  getCurrentWorkingDir();
540  }
541 
542  if (addCwd)
543  {
545  getCurrentWorkingDir();
546  result = cwd.dirCat(result);
547  }
548  else if ( result.isRelative() )
549  {
550  if ( result.size() && ((*(result.begin())) != '$') )
551  {
553  getCurrentWorkingDir();
554  result = cwd.dirCat(result);
555  }
556  }
557 
558  // Check result to see if we're finished.
559  if ( result.needsExpansion() )
560  {
561  // now expand any environment variable substitutions
562 
563  ossimFilename finalResult;
564  const char* tempPtr = result.c_str();
565  ossim_int32 startIdx = -1;
566  ossim_int32 resultSize = (ossim_uint32)result.size();
567  ossim_int32 scanIdx = 0;
568  while(scanIdx < resultSize)
569  {
570  // look for start of substitution pattern
571  if(tempPtr[scanIdx] == '$')
572  {
573  if(tempPtr[scanIdx+1] == '(')
574  {
575  scanIdx += 2;
576  startIdx = scanIdx;
577  }
578  else
579  {
580  //---
581  // Infinite loop fix with below file on window:
582  // "\\kiosk\x$\SourceImagery\foo.ntf" (drb 21 Nov. 2016)
583  //---
584  finalResult += tempPtr[scanIdx];
585  ++scanIdx;
586  }
587  }
588  // look for an end pattern and apply if we found a start pattern
589  else if(tempPtr[scanIdx] == ')')
590  {
591  if(startIdx != -1)
592  {
593  ossimFilename value(
595  getEnvironmentVariable(ossimString(tempPtr+startIdx,
596  tempPtr+scanIdx)));
597 #if defined(_WIN32) // do windows style replacment
598  // value.convertBackToForwardSlashes();
599 #endif
600  finalResult += value;
601  // reset start idx indicator to not set so we are ready for next pattern
602  //
603  startIdx = -1;
604  }
605  else // if no start then tack on the )
606  {
607  finalResult += tempPtr[scanIdx];
608  }
609  ++scanIdx;
610  }
611  else if(startIdx == -1)
612  {
613  finalResult += tempPtr[scanIdx];
614  ++scanIdx;
615  }
616  else
617  {
618  ++scanIdx;
619  }
620  }
621 #if defined(_WIN32)
622 
623 #else
624  finalResult.gsub("//", "/", true);
625 #endif
626  result = finalResult;
627 
628  } // matches: if ( result.needsExpansion() )
629 
630 #if defined(_WIN32)
631  // result.convertForwardToBackSlashes();
632 #endif
633 
634  } // matches: if ( needsExpansion() )
635 
636  //---
637  // If we had a size before "expand()" and now we don't something went
638  // wrong...
639  //---
640  if (!result.size())
641  {
642  result = *this;
643  }
644 
645  } // matches: if ( size() )
646 
647  return result;
648 }
649 
651 {
652  bool result = false;
653  if ( isUrl() == false )
654  {
655 #if defined(_WIN32)
656  result = (_access(c_str(), ossimFilename::OSSIM_EXIST) == 0);
657 #else
658  result = ((access(c_str(), ossimFilename::OSSIM_EXIST)) == 0);
659 #endif
660  }
661  else
662  {
663  result = ossim::StreamFactoryRegistry::instance()->exists( this->string() );
664  }
665  return result;
666 }
667 
669 {
670 #if defined(_WIN32)
671  struct _stat sbuf;
672  if ( _stat(c_str(), &sbuf ) == -1)
673  return false;
674  return (_S_IFMT & sbuf.st_mode ? true : false);
675 #else
676  struct stat sbuf;
677 
678  stat(c_str(), &sbuf);
679  return ((sbuf.st_mode & S_IFMT) == S_IFREG);
680 #endif
681 }
682 
684 {
685  if ( empty() )
686  {
687  return false;
688  }
689 
690  ossimFilename temp = c_str();
691  const char& lastChar = temp[temp.size()-1];
692  if ( lastChar == '/' || lastChar == '\\' )
693  {
694  temp = temp.beforePos(temp.size() - 1);
695  }
696 
697 #if defined(_WIN32)
698 
699  struct _stat sbuf;
700  if ( _stat(temp.c_str(), &sbuf ) == -1)
701  return false;
702  return (_S_IFDIR & sbuf.st_mode ? true : false);
703 #else
704  struct stat sbuf;
705  if (stat(temp.c_str(), &sbuf) == -1)
706  return false;
707  return (S_ISDIR(sbuf.st_mode));
708 #endif
709 }
710 
712 {
713 #if defined(_WIN32)
714 
715  struct _stat sbuf;
716  if ( _stat(c_str(), &sbuf ) == -1)
717  return false;
718  return (_S_IREAD & sbuf.st_mode ? true : false);
719 #else
720  return (access(c_str(), ossimFilename::OSSIM_READ) == 0);
721 #endif
722 }
723 
725 {
726  bool result = false;
727  if ( m_str.size() )
728  {
729  //---
730  // Must have at least room for a protocol and "://", e.g.
731  // "s3://my_bucket/data1/foo.tif
732  //---
733  std::size_t found = m_str.find( std::string("://") );
734  if ( ( found != std::string::npos ) && ( found > 1 ) )
735  {
736  result = true;
737  }
738  }
739  return result;
740 }
741 
743 {
744 #if defined(_WIN32)
745 
746  struct _stat sbuf;
747  if ( _stat(c_str(), &sbuf ) == -1)
748  return false;
749  return (_S_IWRITE & sbuf.st_mode ? true : false);
750 #else
751  return (access(c_str(), ossimFilename::OSSIM_WRITE) == 0);
752 #endif
753 }
754 
756 {
757 #if defined(_WIN32)
758 
759  struct _stat sbuf;
760  if ( _stat(c_str(), &sbuf ) == -1)
761  return false;
762  return (_S_IEXEC & sbuf.st_mode ? true : false);
763 #else
764  return (access(c_str(), ossimFilename::OSSIM_EXE) == 0);
765 #endif
766 }
767 
769 {
770  std::string::size_type pos = m_str.rfind('.');
771  if (pos == std::string::npos)
772  {
773  return ossimFilename::NIL;
774  }
775 
776  return ossimFilename(m_str.substr(pos+1));
777 }
778 
780 {
781  std::string::size_type pos = m_str.rfind(OSSIM_FILENAME_PATH_SEPARATOR);
782  if (pos == std::string::npos)
783  return *this;
784  else
785  return ossimFilename(m_str.substr(pos+1));
786 }
787 
789 {
790  // finds the last occurrence of the given string; in this case '/';
791  std::string::size_type pos = m_str.rfind(OSSIM_FILENAME_PATH_SEPARATOR);
792 
793  if (pos == 0)
795  if (pos == std::string::npos)
796  {
797  // We got to the end of the file and did not find a path separator.
798  return ossimFilename::NIL;
799  }
800 
801  return ossimFilename(m_str.substr(0, pos));
802 }
803 
805 {
806  ossimFilename result;
807  ossimRegExp regEx("^([a-z|A-Z])+:");
808  if(regEx.find( m_str.c_str() ) )
809  {
810  result = ossimFilename(ossimString(this->begin() + regEx.start(),
811  this->begin() + regEx.end()));
812  }
813  else
814  {
815  result = "";
816  }
817 
818  return result;
819 }
820 
822 {
823  std::string::size_type dot_pos = m_str.rfind('.');
824  std::string::size_type slash_pos = m_str.rfind(OSSIM_FILENAME_PATH_SEPARATOR);
825 
826  if(dot_pos == std::string::npos)
827  {
828  if(slash_pos == std::string::npos)
829  {
830  return *this;
831  }
832  else
833  {
834  return ossimFilename(this->begin()+slash_pos+1,
835  this->end());
836  }
837  }
838  else if(slash_pos == std::string::npos)
839  {
840  return ossimFilename(this->begin(), this->begin()+dot_pos);
841  }
842  else if(slash_pos < dot_pos)
843  {
844  return ossimFilename(this->begin()+slash_pos+1,
845  this->begin() + dot_pos);
846  }
847 
848  return ossimFilename(this->begin()+slash_pos+1,
849  this->end());
850 
851 }
853 {
854  ossimString drivePart;
855  ossimString pathPart;
856  ossimString filePart;
857  ossimString extPart;
858 
859  split(drivePart, pathPart, filePart, extPart);
860 
861  extPart.clear();
862 
863  ossimFilename result;
864 
865  result.merge(drivePart, pathPart, filePart, extPart);
866 
867  return result;
868 }
869 
871 {
872  ossimString newExtPart = e;
873 
874  //---
875  // If e has a dot "." in the front of it strip it off...
876  //---
877  if ( (e.begin() != e.end()) && ((*(e.begin())) == '.') )
878  {
879  newExtPart = ossimString(e.begin() + 1, e.end());
880  }
881 
882  ossimString drivePart;
883  ossimString pathPart;
884  ossimString filePart;
885  ossimString extPart;
886 
887  split(drivePart,
888  pathPart,
889  filePart,
890  extPart);
891 
892  merge(drivePart,
893  pathPart,
894  filePart,
895  newExtPart);
896 
897  return *this;
898 }
899 
901 {
902  ossimString drivePart;
903  ossimString pathPart;
904  ossimString filePart;
905  ossimString extPart;
906 
907  split(drivePart,
908  pathPart,
909  filePart,
910  extPart);
911 
912  merge(d,
913  pathPart,
914  filePart,
915  extPart);
916 
917  return *this;
918 }
919 
921 {
922  ossimString drivePart;
923  ossimString pathPart;
924  ossimString filePart;
925  ossimString extPart;
926 
927  split(drivePart,
928  pathPart,
929  filePart,
930  extPart);
931 
932  merge(drivePart,
933  p,
934  filePart,
935  extPart);
936 
937  return *this;
938 }
939 
941 {
942  ossimString drivePart;
943  ossimString pathPart;
944  ossimString filePart;
945  ossimString extPart;
946 
947  split(drivePart,
948  pathPart,
949  filePart,
950  extPart);
951 
952  merge(drivePart,
953  pathPart,
954  f,
955  extPart);
956 
957  return *this;
958 }
959 
960 
962  ossimString& pathPart,
963  ossimString& filePart,
964  ossimString& extPart)const
965 {
966  drivePart = drive();
967  pathPart = path();
968  if(drivePart != "")
969  {
970  pathPart = pathPart.substitute(drivePart, "");
971  }
972  filePart = fileNoExtension();
973  extPart = ext();
974 }
975 
976 void ossimFilename::merge(const ossimString& drivePart,
977  const ossimString& pathPart,
978  const ossimString& filePart,
979  const ossimString& extPart)
980 {
981  ossimFilename result = drivePart;
982 
983  if(pathPart != "")
984  {
985  result = result.dirCat(ossimFilename(pathPart));
986  }
987 
988  if(filePart!="")
989  {
990  result = result.dirCat(ossimFilename(filePart));
991  }
992 
993  if(extPart != "")
994  {
995  result += ".";
996  result += extPart;
997  }
998 
999  *this = result;
1000 }
1001 
1003 {
1004  // If this string is empty simply return the input file.
1005  if (empty()) return file;
1006  if (file.empty()) return *this;
1007 
1008  ossimFilename dir = *this;
1009  ossimFilename tempFile = file;
1010 
1011  // Check the end and see if it already has a "/".
1012  string::const_iterator i = dir.end();
1013 
1014  --i; // decrement past the trailing null.
1015 
1016  if ( (*i) != OSSIM_FILENAME_PATH_SEPARATOR)
1017  {
1019  }
1020 
1021  // check for dot slash or just slash: ./foo or /foo
1022  std::string::iterator iter = tempFile.begin();
1023  if (iter != tempFile.end())
1024  {
1025  if ((*iter) == OSSIM_FILENAME_PATH_SEPARATOR)
1026  {
1027  ++iter; // skip slash
1028  }
1029  else if (tempFile.size() > 1)
1030  {
1031  if ( ((*iter) == '.') && ( *(iter + 1) == OSSIM_FILENAME_PATH_SEPARATOR) )
1032  {
1033  iter = iter + 2; // skip dot slash
1034  }
1035  }
1036  }
1037 
1038  dir += std::string(iter, tempFile.end());
1039 
1040  return dir;
1041 }
1042 
1044 {
1045  ossim_int64 size = 0;
1046 
1047  if ( isUrl() == false )
1048  {
1049  struct stat sbuf;
1050  if ( stat( this->c_str(), &sbuf ) == 0 )
1051  {
1052  size = (ossim_int64)sbuf.st_size;
1053  }
1054  else
1055  {
1056  ifstream in(c_str());
1057  if(in)
1058  {
1059  in.seekg(0, std::ios_base::end);
1060  size = (ossim_int64)in.tellg();
1061  }
1062  }
1063  }
1064  else
1065  {
1066  std::shared_ptr<ossim::istream> in = ossim::StreamFactoryRegistry::instance()->
1067  createIstream( this->string() );
1068  if ( in )
1069  {
1070  ossimFileInfoInterface* intf = dynamic_cast<ossimFileInfoInterface*>( in.get() );
1071  if ( intf )
1072  {
1073  size = intf->getFileSize();
1074  }
1075  else
1076  {
1077  in->seekg(0, std::ios_base::end);
1078  size = (ossim_int64)in->tellg();
1079  }
1080  }
1081  }
1082 
1083  return size;
1084 }
1085 
1086 bool ossimFilename::createDirectory( bool recurseFlag,
1087  int perm ) const
1088 {
1089  if(exists()) return true;
1090 
1091  if ( empty() ) return false;
1092 
1093  if(recurseFlag)
1094  {
1095  ossimString tempString = this->expand().c_str();
1096 
1097  vector<ossimString> result;
1098  tempString.split(result,OSSIM_FILENAME_PATH_SEPARATOR);
1099 
1100  if(result.size())
1101  {
1102  ossimString current = result[0];
1103 
1104 // Reconstruct UNC paths under Windows.
1105 #if defined(_WIN32)
1106  bool bGotUNC = false;
1107  if ( current.length() == 0 && tempString.length() > 2 )
1108  {
1109  const char* fstr = tempString.c_str();
1110  const char fstar0 = fstr[0];
1111  const char fstar1 = fstr[1];
1112  if ( fstar0=='\\' && fstar1=='\\' )
1113  {
1114  bGotUNC = true;
1116  }
1117  }
1118 #endif
1119 
1120  for(ossim_uint32 i = 1; i < result.size(); ++i)
1121  {
1122  current += (OSSIM_FILENAME_PATH_SEPARATOR+result[i]);
1123 
1124 #if defined(_WIN32)
1125  if ( bGotUNC == true && i==1 )
1126  {
1127  // The root of the UNC path is assumed to exist.
1128  continue;
1129  }
1130 #endif
1131 
1132  if(current != OSSIM_FILENAME_PATH_SEPARATOR)
1133  {
1134  if(!ossimFilename(current).exists())
1135  {
1136 #if defined(__BORLANDC__)
1137  if ( _mkdir(current.c_str()) != 0 )
1138 #elif defined(_WIN32)
1139  if ( _mkdir(current.c_str()) != 0 )
1140 #else
1141  if ( mkdir(current.c_str(), perm) != 0 )
1142 #endif
1143  {
1144  return false;
1145  }
1146  }
1147  }
1148  }
1149  }
1150  }
1151  else
1152  {
1153 #if defined (__BORLANDC__)
1154  if ( _mkdir(c_str()) != 0 )
1155 #elif defined(_WIN32)
1156  if ( _mkdir(c_str()) != 0 )
1157 #else
1158  if ( mkdir(c_str(), perm) != 0 )
1159 #endif
1160  {
1161  return false;
1162  }
1163  else
1164  {
1165  return true;
1166  }
1167  }
1168  return true;
1169 }
1170 
1172 {
1173  bool result = true;
1174 
1175 #if defined(__VISUALC__) || defined(__BORLANDC__) || defined(__WATCOMC__) || \
1176  defined(__GNUWIN32__) || defined(_MSC_VER)
1177 
1178  // Note: not sure if these work on all of the above flavors. drb - 14 Sep. 2011.
1179  if(pathname.isDir())
1180  {
1181  // Note this only removes empty directories.
1182  result = ( RemoveDirectory( pathname.c_str() ) != 0 );
1183  }
1184  else
1185  {
1186  result = ( DeleteFile( pathname.c_str() ) != 0 );
1187  }
1188 #else /* Unix flavor from unistd.h. */
1189  if(pathname.isDir())
1190  {
1191  result = ( rmdir( pathname.c_str() ) == 0 );
1192  }
1193  else
1194  {
1195  result = ( unlink( pathname.c_str() ) == 0 );
1196  }
1197 #endif
1198 
1199  return result;
1200 }
1201 
1203 {
1204  std::vector<ossimFilename> fileListToRemove;
1205  ossimFilename tempPathname = pathname;
1206 
1207  if(!tempPathname.isDir())
1208  {
1209  ossimFilename file = tempPathname.file();
1210  ossimFilename path = tempPathname.path();
1211  if(path == "")
1212  {
1213  path = ".";
1214  }
1215  ossimDirectory dir;
1216  if(dir.open(path))
1217  {
1218  dir.findAllFilesThatMatch(fileListToRemove,
1219  file.c_str());
1220  }
1221  else
1222  {
1223  }
1224  }
1225  else
1226  {
1227  fileListToRemove.push_back(ossimFilename(pathname));
1228  }
1229  ossim_uint32 idx = 0;
1230  bool result = true;
1231  for(idx = 0; idx < fileListToRemove.size(); ++idx)
1232  {
1233 #if defined(__VISUALC__) || defined(__BORLANDC__) || defined(__WATCOMC__) || \
1234  defined(__GNUWIN32__) || defined(_MSC_VER)
1235 
1236  if(remove(fileListToRemove[idx].c_str()) != 0)
1237  {
1238  result = false;
1239  }
1240 #else
1241  if (unlink(fileListToRemove[idx]) == -1)
1242  {
1243  result = false;
1244  }
1245 #endif /* HAVE_UNISTD_H */
1246  }
1247  return result;
1248 }
1249 
1250 bool ossimFilename::rename(const ossimFilename& destFile, bool overwriteDestinationFlag)const
1251 {
1252  bool result = true;
1253  if ( this->string() != destFile.string() )
1254  {
1255  if ( overwriteDestinationFlag && destFile.exists() )
1256  {
1257  destFile.remove();
1258  }
1259 
1260  if ( destFile.exists() == false )
1261  {
1262  // std::rename from cstdio returns 0 on success.
1263  if ( std::rename(this->c_str(), destFile.c_str()) != 0 )
1264  {
1265  result = false;
1266  }
1267  }
1268  else
1269  {
1271  << "ossimFilenam::rename WARNING:"
1272  << "\nDestination File Exists: " << destFile << std::endl;
1273  result = false;
1274  }
1275  }
1276  return result;
1277 }
1278 
1280 {
1281  return ossimFilename::remove(*this);
1282 }
1283 
1285 {
1286  return ossimFilename::wildcardRemove(*this);
1287 }
1288 
1289 bool ossimFilename::copyFileTo(const ossimFilename& outputFile) const
1290 {
1291  bool result = false;
1292 
1293  std::ifstream is(this->c_str(), std::ios::in|std::ios::binary);
1294  if ( is.good() )
1295  {
1296  ossimFilename f = outputFile;
1297  if ( f.isDir() )
1298  {
1299  f = f.dirCat( this->file() );
1300  }
1301 
1302  if ( f != *this )
1303  {
1304  std::ofstream os( f.c_str(), std::ios::out|std::ios::binary );
1305  if ( os.good() )
1306  {
1307  // Copy the file:
1308  char c;
1309  while(is.get(c))
1310  {
1311  os.put(c);
1312  }
1313 
1314  if ( is.eof() && !os.fail())
1315  {
1316  result = true;
1317  }
1318  else
1319  {
1321  << "WARNING: "
1322  << "ossimFilename::copyFileTo WARNING:"
1323  << "\nError detected writing from file "
1324  << this->c_str() << " to file " << f.c_str() << std::endl;
1325  }
1326  }
1327  else
1328  {
1330  << "WARNING: "
1331  << "ossimFilename::copyFileTo WARNING:"
1332  << "\nCannot open: " << f.c_str() << std::endl;
1333  }
1334  } // if ( f != *this )
1335  else
1336  {
1338  << "WARNING: "
1339  << "ossimFilename::copyFileTo WARNING:"
1340  << "\nFiles the same!" << std::endl;
1341  }
1342 
1343  } // if ( is.good() )
1344  else
1345  {
1347  << "WARNING: "
1348  << "ossimFilename::copyFileTo WARNING:"
1349  << "\nCannot open: " << this->c_str() << std::endl;
1350  }
1351 
1352  return result;
1353 }
1354 
1355 //---
1356 // We will only return false if we are absolutely sure absolutely sure we
1357 // are not relative. No pun intended:)
1358 //---
1360 {
1361  bool result = true;
1362  if (size())
1363  {
1364  //---
1365  // Look for unix "/"...
1366  // ESH: Look for Windows "\" (with prepending escape character \)
1367  //---
1368  if ( (*(begin()) == '/') || (*(begin()) == '\\') )
1369  {
1370  result = false;
1371  }
1372  else
1373  {
1374  // Look for windows drive
1375  ossimRegExp regEx("^([a-z|A-Z])+:");
1376  if ( regEx.find(c_str()) == true)
1377  {
1378  result = false;
1379  }
1380  }
1381  }
1382  return result;
1383 }
1384 
1386 {
1387  bool result = false;
1388  if ( m_str.size() )
1389  {
1390  // Do not expand URLs.
1391  if ( isUrl() == false )
1392  {
1393  result = isRelative();
1394  if (result == false)
1395  {
1396  // Check for '$'
1397  std::string::size_type pos = m_str.find('$', 0);
1398  {
1399  if (pos != std::string::npos)
1400  {
1401  // found '$'
1402  result = true;
1403  }
1404  }
1405 
1406  }
1407  }
1408  }
1409  return result;
1410 }
1411 
1413 {
1415 }
1416 
1418 {
1419  const std::string format = "%Y%m%d-%H%Mh%Ss";
1420  std::string timestamp;
1421  ossim::getFormattedTime(format, true, timestamp);
1422 
1423  return append(timestamp);
1424 }
1425 
1427 {
1428  ossimString drivePart;
1429  ossimString pathPart;
1430  ossimString filePart;
1431  ossimString extPart;
1432 
1433  split(drivePart, pathPart, filePart, extPart);
1434  filePart += append_this;
1435  merge(drivePart, pathPart, filePart, extPart);
1436 
1437  return *this;
1438 }
1439 
1441 {
1442  if ( m_str.size() )
1443  {
1444  std::replace( m_str.begin(), m_str.end(), '\\', OSSIM_FILENAME_PATH_SEPARATOR );
1445  }
1446 }
1447 
1448 std::string ossimFilename::native() const
1449 {
1450 #if defined(_WIN32)
1451  std::string s = m_str;
1452  std::replace( s.begin(), s.end(),OSSIM_FILENAME_PATH_SEPARATOR, OSSIM_NATIVE_PATH_SEPARATOR );
1453  return s;
1454 #else
1455  return m_str;
1456 #endif
1457 }
1458 
1459 #if 0
1460 void ossimFilename::convertToNative()
1461 {
1462 #if defined(_WIN32)
1463  if ( isUrl() == false )
1464  {
1465  convertForwardToBackSlashes();
1466  }
1467 #else
1468  convertBackToForwardSlashes();
1469 
1470 #endif
1471 }
1472 #endif
void clear()
Erases the entire container.
Definition: ossimString.h:432
ossimLocalTm & setDay(int day)
Definition: ossimDate.cpp:476
ossimString substitute(const ossimString &searchKey, const ossimString &replacementValue, bool replaceAll=false) const
Substitutes searchKey string with replacementValue and returns a string.
ossimFilename noExtension() const
static bool remove(const ossimFilename &pathname)
Removes pathname from filesystem if supported by platform.
OSSIM_DLL ossim_int64 getTime()
Gets the current time.
bool isWriteable() const
static const ossimFilename NIL
This was taken from Wx widgets for performing touch and access date stamps.
Definition: ossimFilename.h:40
ossimFilename & appendTimestamp()
Convenience method to append a generic timestamp to the base-name portion of the filename.
ossimFilename & setFile(const ossimString &f)
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
std::string m_str
Definition: ossimString.h:733
ossim_int64 fileSize() const
ossimFilename expand() const
Method to do file name expansion.
bool touch() const
bool getTimes(ossimLocalTm *accessTime, ossimLocalTm *modTime, ossimLocalTm *createTime) const
bool wildcardRemove() const
ossimFilename & setPath(const ossimString &p)
int getSec() const
Definition: ossimDate.cpp:580
void split(ossimString &drivePart, ossimString &pathPart, ossimString &filePart, ossimString &extPart) const
int getYear() const
Definition: ossimDate.cpp:433
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
int getMin() const
Definition: ossimDate.cpp:575
static StreamFactoryRegistry * instance()
void findAllFilesThatMatch(std::vector< ossimFilename > &result, const ossimString &regularExpressionPattern, int flags=OSSIM_DIR_DEFAULT)
ossim_int64 lastAccessed() const
Time in seconds since last accessed.
bool isDir() const
std::string::iterator end()
Definition: ossimString.h:423
bool copyFileTo(const ossimFilename &outputFile) const
Copies this file to output file.
friend OSSIM_DLL bool operator==(const char *lhs, const ossimString &rhs)
Definition: ossimString.h:955
ossimString()
default constructor
Definition: ossimString.h:31
bool isExecutable() const
bool exists(const std::string &connectionString) const
Methods to test if connection exists.
bool exists() const
std::string::size_type length() const
Definition: ossimString.h:408
OSSIM_DLL void getFormattedTime(const std::string &format, bool gmtFlag, std::string &result)
Gets the current time.
std::string::size_type size() const
Definition: ossimString.h:405
bool isUrl() const
std::string::iterator begin()
Definition: ossimString.h:420
virtual ossim_int64 getFileSize() const =0
Pure virtual file size method.
ossimLocalTm & setMonth(int month)
Definition: ossimDate.cpp:483
unsigned int ossim_uint32
bool isFile() const
static const char OSSIM_NATIVE_PATH_SEPARATOR
static const char OSSIM_FILENAME_PATH_SEPARATOR
ossim_uint32 start() const
Definition: ossimRegExp.h:209
ossimLocalTm & setYear(int year)
Definition: ossimDate.cpp:490
bool setTimes(ossimLocalTm *accessTime, ossimLocalTm *modTime, ossimLocalTm *createTime) const
Writes f to the output stream os.
bool open(const ossimFilename &dir)
std::string native() const
ossimLocalTm & setHour(int h)
Definition: ossimDate.cpp:590
bool isReadable() const
const ossimFilename & operator=(const ossimFilename &f)
ossimLocalTm & setSec(int s)
Definition: ossimDate.cpp:604
ossim_uint32 end() const
Definition: ossimRegExp.h:217
Definition: vpftable.h:80
static ossimEnvironmentUtility * instance()
char getPathSeparator() const
bool remove() const
int getMonth() const
Definition: ossimDate.cpp:448
bool isRelative() const
Checks whether file name is relative or absolute.
ossimFilename fileNoExtension() const
ossimFilename & append(const ossimString &append_this_to_filename)
Convenience method to append a string to the base-name portion of the filename.
int getDay() const
Definition: ossimDate.cpp:453
ossimLocalTm & setMin(int m)
Definition: ossimDate.cpp:597
ossimFilename dirCat(const ossimFilename &file) const
void merge(const ossimString &drivePart, const ossimString &pathPart, const ossimString &filePart, const ossimString &extPart)
ossimString beforePos(std::string::size_type pos) const
long long ossim_int64
Definition: vpftable.h:80
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
bool empty() const
Definition: ossimString.h:411
bool needsExpansion() const
Method to check if expansion is needed.
bool operator==(const ossimFilename &rhs) const
ossimFilename file() const
ossimString ext() const
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
ossimString & gsub(const ossimString &searchKey, const ossimString &replacementValue, bool replaceAll=false)
Substitutes searchKey string with replacementValue and returns a reference to *this.
ossimFilename & setExtension(const ossimString &e)
Sets the extension of a file name.
bool createDirectory(bool recurseFlag=true, int perm=0775) const
int getHour() const
Definition: ossimDate.cpp:570
ossimFilename getUserDir() const
bool find(const char *)
ossimFilename & setDrive(const ossimString &d)
Sets the file path and drive.
ossimFilename path() const
ossimFilename drive() const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
time_t getTicks() const
getTicks() will call getEpoc.
Definition: ossimDate.cpp:624
bool rename(const ossimFilename &destFile, bool overwriteDestinationFlag=true) const
int ossim_int32
const std::string & string() const
Definition: ossimString.h:414
void converPathSeparator()
Converts slashes of this to internal &#39;/&#39; format.