HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FS_Reader.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: FS_Reader.h ( FS Library, C++)
7  *
8  * COMMENTS:
9  *
10  */
11 
12 #ifndef __FS_Reader__
13 #define __FS_Reader__
14 
15 #include "FS_API.h"
16 #include "FS_ReaderStream.h"
17 #include <UT/UT_NonCopyable.h>
18 #include <UT/UT_ValArray.h>
19 #include <SYS/SYS_Types.h>
20 
21 #include <time.h>
22 
23 class UT_IStream;
24 class UT_Options;
25 class UT_String;
26 class UT_StringArray;
27 class UT_StringHolder;
28 class FS_IndexFile;
29 class FS_ReaderHelper;
31 
32 /// Class for reading files
33 class FS_API FS_Reader final
34 {
35 public:
36  FS_Reader();
37 
38  /// Use this constructor to create a new reader. The specified file is
39  /// opened immediately.
40  /// Common options:
41  /// - "string cache_mode" - Specify the "caching" pattern. This gives a
42  /// hint to the file system about how the stream will be accessed.
43  /// * "normal" - Normal caching
44  /// * "random" - Access pattern is random
45  /// * "sequential" - Access pattern is sequential
46  /// - "int buffer_size" - Specify the buffer size (see setvbuf)
47  /// - "bool ascii" - Specify whether the file should be opened in ASCII
48  /// read mode for automatically translating line-endings.
49  FS_Reader(const char *source, const UT_Options *options=0);
50 
51  /// NOTE: This new FS_Reader takes ownership of the FS_ReaderStream
52  FS_Reader(FS_ReaderStream *sourcestream);
53  ~FS_Reader();
54 
56 
58 
59  /// Get the amount of memory owned by this FS_Reader
60  int64 getMemoryUsage(bool inclusive) const;
61 
62  /// Closes the stream. After calling this function, the getStream()
63  /// function will always return @c nullptr.
64  void close();
65 
66  /// This function is used to check if the file was successfully opened
67  bool isGood() const
68  { return myStream && myStream->isGood(); }
69 
70  /// This function retrieves the C++ stream object which you can interact
71  /// with in the normal ways. If this function returns @c nullptr, the file
72  /// specified in the constructor could not be found.
73  UT_IStream *getStream() const;
74 
75  // Obtains a stream reader that reads a portion of this reader's stream.
76  // Note, the underlying buffers are shared, invoking this method will
77  // advance the current read position to the subset's beginning, and any
78  // subsequent reading will further advance the read position.
79  FS_ReaderStream *shareDataAndGetSubstream(int64 stream_offset,
80  int64 sub_stream_size, int64 sub_data_size,
81  const FS_IStreamFilterFactory * f = nullptr) const;
82 
83  time_t getModTime() const;
84  int64 getLength() const;
85  const UT_StringHolder &getFilename() const;
86 
87  // Obtains filter factories that are piggyacked from another FS_IndexFile.
88  FS_IStreamFilterFactory *getSubStreamReadFilterFactory() const;
89  FS_WriteFilterFactory *getSubStreamWriteFilterFactory() const;
90 
91  // Functions for adding and removing helpers.
92  static void addReaderHelper(FS_ReaderHelper *helper);
93  static void removeReaderHelper(FS_ReaderHelper *helper);
94 
95  /// @{
96  /// Utility fuction to split the original source path into the index file
97  /// path and the section name. It asks all registered reader helpers
98  /// whether they recognize the source path protocol and can provide the
99  /// section name. If none of the helpers do, then it tries FS_IndexFile to
100  /// split the source path on '?' by default.
101  /// @param[in] source_section_path The original source path to split.
102  /// @param[out] index_file_path If the original source path refers to
103  /// an index file section, this parameter is set to the
104  /// index file path. Otherwise, it is set to the
105  /// source_section_path parameter.
106  /// @param[out] section_name If the original source path refers to
107  /// and index file section, this parameter is set to the
108  /// name of that section. Otherwise, it is set to an empty
109  /// string. If there are many nested sections in the source
110  /// path, then this argument will contain the innermost
111  /// section name, and the index_file_path will point
112  /// to the containing section (itself an index file).
113  /// @param[out] section_names If the original source path refers to
114  /// a section that is nested within other
115  /// sections (that themselves are index files), then
116  /// this parameter is set to these section names, with
117  /// the outermost section at the beginning of the array
118  /// and the innermost section (contained within the outer
119  /// sections) at the end of the array. If there is just
120  /// a single section, the array will contain just one
121  /// entry (ie, the single section name),
122  /// and the call will be equivalent to the method
123  /// that takes just the single string.
124  /// @return True if the path refered to a section name and the outgoing
125  /// parameter 'section_name' contains a non-empty string;
126  /// otherwise, returns false.
127  static bool splitIndexFileSectionPath(
128  const char *source_section_path,
129  UT_String &index_file_path,
130  UT_String &section_name);
131  static bool splitIndexFileSectionPath(
132  const char *source_section_path,
133  UT_StringHolder &index_file_path,
134  UT_StringHolder &section_name);
135  static bool splitIndexFileSectionPath(
136  const char *source_section_path,
137  UT_String &index_file_path,
138  UT_StringArray &section_names );
139  /// @}
140 
141  /// @{
142  /// Utility function to combine index file name and section name into the
143  /// section path. It asks all registered reader helpers
144  /// whether they recognize the index_file_path path protocol and can
145  /// combine it with the section name into the section full path.
146  /// If none of the helpers do, then it asks FS_IndexFile to
147  /// combine the components, joining them with '?' by default.
148  /// @param[out] source_section_path The combined section full path.
149  /// @param[in] index_file_path The base path to the index file.
150  /// @param[in] section_name The name of the section inside the index file.
151  /// @param[in] section_names The names of the nested sections in
152  /// the index file, with the outermost section at the
153  /// beginning of the array and the innermost section
154  /// (contained within the outer sections) at the end
155  /// of the array. If the array contains only one entry,
156  /// it's equivalent to the method that takes just a single
157  /// string.
158  static void combineIndexFileSectionPath(
159  UT_String &source_section_path,
160  const char *index_file_path,
161  const char *section_name);
162  static void combineIndexFileSectionPath(
163  UT_String &source_section_path,
164  const char *index_file_path,
165  const UT_StringArray &section_names );
166  /// @}
167 
168 
169 private:
170  void createStreamFromSource(const char *source,
171  const UT_Options *options);
172 
173  static UT_ValArray<FS_ReaderHelper *> &getHelpers();
174 
175  FS_ReaderStream *myStream;
176 };
177 
178 /// This class provides a plug-in method for adding a custom "file-system"
179 /// @see FS_WriterHelper, FS_InfoHelper
181 {
182 public:
184  { FS_Reader::addReaderHelper(this); }
187 
189 
190  /// Return an FS_ReaderStream if the helper is able to open the source
191  /// filename.
192  ///
193  /// The options are passed through directly from the FS_Reader
194  /// constructor. See FS_Reader for list of options.
195  virtual FS_ReaderStream *createStream(const char *source,
196  const UT_Options *options=nullptr) = 0;
197 
198  /// Parse the source path into the index file path and the section name.
199  ///
200  /// The FS library recognizes a special source format for FS_IndexFile,
201  /// which is a file containing several sections indexed and accessible
202  /// by their name. That source format contains '?' as a separator between
203  /// the file path and the section name.
204  /// FS_Reader scans for '?' in the source path before asking helpers
205  /// to handle it. This way index files are supported for custom protoclos
206  /// automatically without them needing to implement it explicitly.
207  /// Eg, "myfiles:path/to/indexfile?section" will work automaticaly, since
208  /// FS_Reader will ask the helper for a read stream for
209  /// "myfiles:/path/to/indexfile" but will create and use the "section"
210  /// read stream itself.
211  /// The downside is that custom protocols can't use '?' in their path
212  /// format. To address this isse, this method has been added to let the
213  /// helpers decide how to handle the '?'.
214  ///
215  /// If the helper does not use '?' for any special purpose, it does not need
216  /// to override this virtual (or it can overloaded it and return false).
217  /// If the helper uses '?' for some special meaning (or if it supports some
218  /// custom syntax to refer to sections of an index file), then it should
219  /// override it and return true. Further, it can return a non-empty section
220  /// name if the protocol supports section naming and the source path indeed
221  /// refers to a section in an index file. Or, it can return an empty string
222  /// for the section name, if the source path does not refer to an index
223  /// file (or if helper does not want the automatic index file handling and
224  /// plans to handle index files explicitly by itself).
225  ///
226  /// @param[in] source_section_path Original source path to be opened for
227  /// reading.
228  /// @param[out] index_file_path If source_section_path refers to a section
229  /// in an index file, then this parameter is set to the index
230  /// file path (and method returns true).
231  /// If source_section_path does not refer to a section, then
232  /// this parameter is set to original path, ie, equal to
233  /// source_section_path (and method returns true).
234  /// If the helper does not recognize the source_section_path
235  /// (ie, it's another protocol), or if recognizes it but does
236  /// not need (nor want) custom handling for '?' separator,
237  /// then this parameter is not set (and method returns false).
238  /// @param[out] section_name This Similar to index_file_path, but this
239  /// outgoing parameter is set to the section name, if
240  /// source_section_path refers to a section and is set to
241  /// empty-string if it does not (and method returns true).
242  /// If the method returns false, it is not set.
243  ///
244  /// @return True if the source_section_path can be handled by the
245  /// helper, in which case index_file_path and section_name
246  /// are also set (though section can be an empty-string).
247  /// False if the source_code_path is not handled by helper,
248  /// or if helper wants default index file naming convention
249  /// (with '?' splitting the file and section name).
250  ///
251  virtual bool splitIndexFileSectionPath(const char *source_section_path,
252  UT_String &index_file_path,
253  UT_String &section_name)
254  {
255  return false;
256  }
257 
258  /// Utility function to combine index file name and section name into the
259  /// section path. Performs the reverse of splitIndexFileSectionPath().
260  /// If the helper does not use '?' for any special purpose in the source
261  /// path, then it does not need to override this virtual (see above).
262  /// @param[out] source_section_path The combined full section path.
263  /// @param[in] index_file_path The base path to the index file.
264  /// @param[in] section_name The name of the section inside the index file.
265  /// @return True if the helper recognizes the 'index_file_path' as its
266  /// own file protocol. False, if it does not recognize the
267  /// protocol or if it wants the default joining of file and
268  /// section names using the default convention of '?' to
269  /// join the components.
271  UT_String &source_section_path,
272  const char *index_file_path,
273  const char *section_name)
274  {
275  return false;
276  }
277 };
278 
279 #endif
280 
bool isGood() const
This function is used to check if the file was successfully opened.
Definition: FS_Reader.h:67
Class for reading files.
Definition: FS_Reader.h:33
static void addReaderHelper(FS_ReaderHelper *helper)
void close() override
virtual ~FS_ReaderHelper()
Definition: FS_Reader.h:185
GLfloat f
Definition: glcorearb.h:1926
static void removeReaderHelper(FS_ReaderHelper *helper)
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
long long int64
Definition: SYS_Types.h:116
A map of string to various well defined value types.
Definition: UT_Options.h:84
#define FS_API
Definition: FS_API.h:10
virtual bool combineIndexFileSectionPath(UT_String &source_section_path, const char *index_file_path, const char *section_name)
Definition: FS_Reader.h:270