1 #pragma once
2 
3 #ifndef T_FILEPATH_INCLUDED
4 #define T_FILEPATH_INCLUDED
5 
6 #include "tcommon.h"
7 #include "texception.h"
8 
9 #undef DVAPI
10 #undef DVVAR
11 #ifdef TSYSTEM_EXPORTS
12 #define DVAPI DV_EXPORT_API
13 #define DVVAR DV_EXPORT_VAR
14 #else
15 #define DVAPI DV_IMPORT_API
16 #define DVVAR DV_IMPORT_VAR
17 #endif
18 
19 class QString;
20 
21 //-----------------------------------------------------------------------------
22 /*
23   This is an example of how to use TFilePath and TFrameId classes.
24 */
25 
26 //!\include frameid_ex.cpp
27 //! The class TFrameId describes a frame identified by an integer number of four
28 //! figures and, in case, by a character (necessary for added frames)
29 class DVAPI TFrameId {
30   int m_frame;
31   char m_letter;  // serve per i frame "aggiunti" del tipo pippo.0001a.tzp =>
32                   // f=1 c='a'
33   int m_zeroPadding;
34   char m_startSeqInd;
35 
36 public:
37   enum {
38     EMPTY_FRAME = -1,  // es. pippo..tif
39     NO_FRAME    = -2   // es. pippo.tif
40   };
41 
42   enum FrameFormat {
43     FOUR_ZEROS,
44     NO_PAD,
45     UNDERSCORE_FOUR_ZEROS,  // pippo_0001.tif
46     UNDERSCORE_NO_PAD,
47     CUSTOM_PAD,
48     UNDERSCORE_CUSTOM_PAD,
49     USE_CURRENT_FORMAT
50   };  // pippo_1.tif
51 
52   TFrameId(int f = EMPTY_FRAME)
m_frame(f)53       : m_frame(f), m_letter(0), m_zeroPadding(4), m_startSeqInd('.') {}
TFrameId(int f,char c)54   TFrameId(int f, char c)
55       : m_frame(f), m_letter(c), m_zeroPadding(4), m_startSeqInd('.') {}
TFrameId(int f,char c,int p)56   TFrameId(int f, char c, int p)
57       : m_frame(f), m_letter(c), m_zeroPadding(p), m_startSeqInd('.') {}
TFrameId(int f,char c,int p,char s)58   TFrameId(int f, char c, int p, char s)
59       : m_frame(f), m_letter(c), m_zeroPadding(p), m_startSeqInd(s) {}
60 
61   inline bool operator==(const TFrameId &f) const {
62     return f.m_frame == m_frame && f.m_letter == m_letter;
63   }
64   inline bool operator!=(const TFrameId &f) const {
65     return (m_frame != f.m_frame || m_letter != f.m_letter);
66   }
67   inline bool operator<(const TFrameId &f) const {
68     return (m_frame < f.m_frame ||
69             (m_frame == f.m_frame && m_letter < f.m_letter));
70   }
71   inline bool operator>(const TFrameId &f) const { return f < *this; }
72   inline bool operator>=(const TFrameId &f) const { return !operator<(f); }
73   inline bool operator<=(const TFrameId &f) const { return !operator>(f); }
74 
75   const TFrameId &operator++();
76   const TFrameId &operator--();
77 
78   TFrameId &operator=(const TFrameId &f) {
79     m_frame       = f.m_frame;
80     m_letter      = f.m_letter;
81     m_zeroPadding = f.m_zeroPadding;
82     m_startSeqInd = f.m_startSeqInd;
83     return *this;
84   }
85 
isEmptyFrame()86   bool isEmptyFrame() const { return m_frame == EMPTY_FRAME; }
isNoFrame()87   bool isNoFrame() const { return m_frame == NO_FRAME; }
88 
89   // operator string() const;
90   std::string expand(FrameFormat format = FOUR_ZEROS) const;
getNumber()91   int getNumber() const { return m_frame; }
getLetter()92   char getLetter() const { return m_letter; }
93 
setZeroPadding(int p)94   void setZeroPadding(int p) { m_zeroPadding = p; }
getZeroPadding()95   int getZeroPadding() const { return m_zeroPadding; }
96 
setStartSeqInd(char c)97   void setStartSeqInd(char c) { m_startSeqInd = c; }
getStartSeqInd()98   char getStartSeqInd() const { return m_startSeqInd; }
99 
getCurrentFormat()100   FrameFormat getCurrentFormat() const {
101     switch (m_zeroPadding) {
102     case 0:
103       return (m_startSeqInd == '.' ? NO_PAD : UNDERSCORE_NO_PAD);
104     case 4:
105       return (m_startSeqInd == '.' ? FOUR_ZEROS : UNDERSCORE_FOUR_ZEROS);
106     default:
107       break;
108     }
109 
110     return (m_startSeqInd == '.' ? CUSTOM_PAD : UNDERSCORE_CUSTOM_PAD);
111   }
112 };
113 
114 //-----------------------------------------------------------------------------
115 /*! \relates TFrameId*/
116 
117 inline std::ostream &operator<<(std::ostream &out, const TFrameId &f) {
118   if (f.isNoFrame())
119     out << "<noframe>";
120   else if (f.isEmptyFrame())
121     out << "''";
122   else
123     out << f.expand().c_str();
124   return out;
125 }
126 
127 //-----------------------------------------------------------------------------
128 
129 /*!The class TFilePath defines a file path.Its constructor creates a string
130    according
131    to the platform and to certain rules.For more information see the
132    constructor.*/
133 class DVAPI TFilePath {
134   static bool m_underscoreFormatAllowed;
135   std::wstring m_path;
136   void setPath(std::wstring path);
137 
138 public:
139   /*! this static method allows correct reading of levels in the form
140    * pippo_0001.tif (represented  always as pippo..tif) */
setUnderscoreFormatAllowed(bool state)141   static void setUnderscoreFormatAllowed(bool state) {
142     m_underscoreFormatAllowed = state;
143   }
144 
145   /*!This constructor creates a string removing redundances ('//', './',etc.)
146 and final slashes,
147       correcting (redressing) the "twisted" slashes.
148       Note that if the current directory is ".", it becomes "".
149 If the path is "<alpha>:" a slash will be added*/
150 
151   explicit TFilePath(const char *path = "");
152   explicit TFilePath(const std::string &path);
153   explicit TFilePath(const std::wstring &path);
154   explicit TFilePath(const QString &path);
155 
~TFilePath()156   ~TFilePath() {}
TFilePath(const TFilePath & fp)157   TFilePath(const TFilePath &fp) : m_path(fp.m_path) {}
158   TFilePath &operator=(const TFilePath &fp) {
159     m_path = fp.m_path;
160     return *this;
161   }
162 
163   bool operator==(const TFilePath &fp) const;
164   inline bool operator!=(const TFilePath &fp) const {
165     return !(m_path == fp.m_path);
166   }
167   bool operator<(const TFilePath &fp) const;
168 
169   const std::wstring getWideString() const;
170   QString getQString() const;
171 
172   /*!Returns:
173    a.  "" if there is no filename extension
174    b. "." if there is a filename extension but no frame
175    c.".." if there are both filename extension and frame */
176   std::string getDots() const;  // ritorna ""(no estensione), "."(estensione, no
177                                 // frame) o ".."(estensione e frame)
178 
179   /*!Returns the filename extension, including leading period (.).
180       Returns "" if there is no filename extension.*/
181   std::string getDottedType() const;  // ritorna l'estensione con il PUNTO (se
182                                       // non c'e' estensione ritorna "")
183 
184   /*!Returns the filename extension, escluding leading period (.).
185       Returns "" if there is no filename extension.*/
186   std::string getUndottedType() const;  // ritorna l'estensione senza PUNTO
187 
188   /*!It is equal to getUndottedType():
189       Returns the filename extension, excluding leading period (.).
190       Returns "" if there is no filename extension.*/
getType()191   std::string getType() const {
192     return getUndottedType();
193   }  // ritorna l'estensione SENZA PUNTO
194   /*!Returns the base filename (no extension, no dots, no slash)*/
195   std::string getName() const;       // noDot! noSlash!
196   std::wstring getWideName() const;  // noDot! noSlash!
197 
198   /*!Returns the filename (with extension, escluding in case the frame number).
199       ex.: TFilePath("/pippo/pluto.0001.gif").getLevelName() == "pluto..gif"
200    */
201   std::string getLevelName()
202       const;  // es. TFilePath("/pippo/pluto.0001.gif").getLevelName() ==
203               // "pluto..gif"
204   std::wstring getLevelNameW()
205       const;  // es. TFilePath("/pippo/pluto.0001.gif").getLevelName() ==
206               // "pluto..gif"
207 
208   /*!Returns the parent directory escluding the eventual final slash.*/
209   TFilePath getParentDir() const;  // noSlash!;
210 
211   TFrameId getFrame() const;
212   bool isFfmpegType() const;
213   bool isLevelName()
214       const;  //{return getFrame() == TFrameId(TFrameId::EMPTY_FRAME);};
215   bool isAbsolute() const;
216   bool isRoot() const;
isEmpty()217   bool isEmpty() const { return m_path == L""; }
218 
219   /*!Return a TFilePath with extension type.
220 type is a string that indicate the filename extension(ex:. bmp or .bmp)*/
221   TFilePath withType(const std::string &type) const;
222   /*!Return a TFilePath with filename "name".*/
223   TFilePath withName(const std::string &name) const;
224   /*!Return a TFilePath with filename "name". Unicode*/
225   TFilePath withName(const std::wstring &name) const;
226   /*!Return a TFilePath with parent directory "dir".*/
227   TFilePath withParentDir(const TFilePath &dir) const;
228   /*!Return a TFilePath without parent directory */
withoutParentDir()229   TFilePath withoutParentDir() const { return withParentDir(TFilePath()); }
230   /*!Return a TFilePath with frame "frame".*/
231   TFilePath withFrame(
232       const TFrameId &frame,
233       TFrameId::FrameFormat format = TFrameId::USE_CURRENT_FORMAT) const;
234   /*!Return a TFilePath with a frame identified by an integer number "f".*/
withFrame(int f)235   TFilePath withFrame(int f) const { return withFrame(TFrameId(f)); }
236   /*!Return a TFilePath with a frame identified by an integer and by a
237    * character*/
withFrame(int f,char letter)238   TFilePath withFrame(int f, char letter) const {
239     return withFrame(TFrameId(f, letter));
240   }
241 
withFrame()242   TFilePath withFrame() const {
243     return withFrame(TFrameId(TFrameId::EMPTY_FRAME));
244   }
withNoFrame()245   TFilePath withNoFrame() const {
246     return withFrame(TFrameId(TFrameId::NO_FRAME));
247   }  // pippo.tif
248 
249   TFilePath operator+(const TFilePath &fp) const;
250   TFilePath &operator+=(const TFilePath &fp) /*{*this=*this+fp;return *this;}*/;
251 
252   inline TFilePath operator+(const std::string &s) const {
253     return operator+(TFilePath(s));
254   }
255   inline TFilePath &operator+=(const std::string &s) {
256     return operator+=(TFilePath(s));
257   }
258 
259   TFilePath &operator+=(const std::wstring &s);
260   TFilePath operator+(const std::wstring &s) const {
261     TFilePath res(*this);
262     return res += s;
263   }
264 
265   bool isAncestorOf(const TFilePath &) const;
266 
267   TFilePath operator-(
268       const TFilePath &fp) const;  // TFilePath("/a/b/c.txt")-TFilePath("/a/")
269                                    // == TFilePath("b/c.txt");
270   // se fp.isAncestorOf(this) == false ritorna this
271 
272   bool match(const TFilePath &fp)
273       const;  // sono uguali a meno del numero di digits del frame
274 
275   // '/a/b/c.txt' => head='a' tail='b/c.txt'
276   void split(std::wstring &head, TFilePath &tail) const;
277 };
278 
279 //-----------------------------------------------------------------------------
280 
281 class TMalformedFrameException final : public TException {
282 public:
283   TMalformedFrameException(const TFilePath &fp,
284                            const std::wstring &msg = std::wstring())
285       : TException(fp.getWideName() + L":" + msg) {}
286 
287 private:
288   TMalformedFrameException();
289 };
290 
291 //-----------------------------------------------------------------------------
292 
293 DVAPI std::ostream &operator<<(std::ostream &out, const TFilePath &path);
294 
295 typedef std::list<TFilePath> TFilePathSet;
296 
297 #endif  // T_FILEPATH_INCLUDED
298