HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_NTStreamUtil.h
Go to the documentation of this file.
1 
2 #ifndef __UT_NTStreamUtil_H__
3 #define __UT_NTStreamUtil_H__
4 
5 #include "UT_API.h"
6 #include "UT_Assert.h"
7 #include "UT_StringHolder.h"
8 #include "UT_TmpDir.h"
9 #include <SYS/SYS_Deprecated.h>
10 #include <SYS/SYS_Types.h>
11 #include <SYS/SYS_Math.h>
12 #include <stdio.h>
13 #include <fstream>
14 #include <iosfwd>
15 
16 class UT_OStream;
17 class UT_OStringStream;
18 class UT_WorkBuffer;
19 class UT_String;
20 class UT_IStream;
21 
22 
23 #ifdef WIN32
24  #define NTBinaryMode std::ios::binary
25 #else
26  #define NTBinaryMode ((std::ios::openmode)0)
27 #endif // WIN32
28 
29 #define UT_NoCreate ((std::ios::openmode)0)
30 
31 
32 typedef enum {
38 
39 typedef int UT_EnumType;
40 
41 
42 #ifdef WIN32
43 
44  void *getNewNamedPipe( char *pipeName );
45 
46  UT_API FILE *UnixPWrite( const char *cmd, const char *file );
47  UT_API FILE *UnixPOpen( const char *file, const char *mode );
48  UT_API void *UnixPOpen( const char *file, void **in, void **out,
49  void **err );
50  UT_API int UnixPClose( FILE *file, int block );
51  inline FILE *popen( const char *name, const char *mode )
52  { return UnixPOpen( name, mode ); }
53  inline int pclose( FILE *f, int block = 1 )
54  { return UnixPClose( f, block ); }
55 
56  UT_API const char *UTgetSocketErrorString(int err);
57 
58  UT_API bool UTconvertShellToWindowsProcessCommand(
59  UT_WorkBuffer &cmd, const char *shell_cmd);
60 
61 #endif // WIN32
62 
63 
64 ///
65 /// We build our own stream buffer to work around a shortcoming
66 /// in the C++ standard. pbump() and pcount() are defined to use
67 /// int, not streamsize, so much sadness occurs as you cross 2gb
68 /// boundaries. See Bug: 45419
69 ///
70 /// Note this isn't a buffered implementation - we don't invoke setpbuf
71 /// to update pbase, etc. The logic is that may bring us back to the
72 /// broken pbump land. Hopefully implementations use xsputn anyways.
73 ///
74 /// exints are chosen rather than streamsize or int_type or pos_type
75 /// because I have lost all faith in how those are defined.
76 ///
77 class UT_API UT_OStrStreamBuf : public std::streambuf
78 {
79 public:
81  explicit UT_OStrStreamBuf(exint initialsize);
82  UT_OStrStreamBuf(char *pch, exint len);
83  ~UT_OStrStreamBuf() override;
84 
85  UT_OStrStreamBuf(const UT_OStrStreamBuf &) = delete;
86  UT_OStrStreamBuf operator=(const UT_OStrStreamBuf &) = delete;
87 
88 protected:
89  // write one character
90  int_type overflow(int_type c) override;
91 
92  // In order to allow tellg to work, we need to provide seekoff.
93  pos_type seekoff(off_type _Off,
94  std::ios_base::seekdir _Way,
95  std::ios_base::openmode
96  _Mode = std::ios::out) override;
97  pos_type seekpos(pos_type _Off,
98  std::ios_base::openmode
99  _Mode = std::ios::out) override;
100 
101  // write multiple characters
102  std::streamsize xsputn(const char* s, std::streamsize num) override;
103 
104 public:
105  // Crappy strstreambuf equivalent functions
106  char *str()
107  {
108  freeze(true);
109  return myBuf;
110  }
111 
112  void freeze(bool isfrozen)
113  {
114  myOwnBuf = !isfrozen;
115  }
116 
117  // Note this is the current put position, not the entries!
118  exint pcount() const
119  {
120  return myOffset;
121  }
122 
123 protected:
124  bool resizeBuf(exint minnewsize);
125 
126  exint mySize, myEntries, myOffset;
127  bool myOwnBuf;
128  char *myBuf;
129 };
130 
131 /// Our portable and much improved strstream
132 /// Uses an exint buffer to allow greater than 2gb streams.
133 class UT_API UT_OStrStream : public std::ostream
134 {
135 public:
137  UT_OStrStream();
138 
140  explicit UT_OStrStream(exint initialsize);
141 
142  /// The stream does *not* gain ownership of this buffer!
143  /// This means it will not resize if it overflows this buffer.
144 #if !defined(WIN32)
146  UT_OStrStream(char *pch, exint nLength,
147  std::ios::openmode = std::ios::out);
148 #else
150  UT_OStrStream(char *pch, exint nLength, int nMode = std::ios::out);
151 #endif
152 
153  UT_OStrStream(const UT_OStrStream &) = delete;
154  UT_OStrStream operator=(const UT_OStrStream &) = delete;
155 
156  /// Note: This is old-school streams!
157  /// You own the result of str() and must either free() it or invoke
158  /// freeze(false)!
159  char *str() { return myBuf.str(); }
160  void freeze(bool isfrozen) { myBuf.freeze(isfrozen); }
161 
162  exint pcount() const
163  {
164  return myBuf.pcount();
165  }
166 
167  // Return this properly cast so people can get at our freeze, etc.
168  UT_OStrStreamBuf *rdbuf() { return &myBuf; }
169 
170 private:
171  UT_OStrStreamBuf myBuf;
172 };
173 
174 // A temporary stream that uses UT_OStrStream by default unless the buffer
175 // size is so big that it should be saved on disk. Tries to balance
176 // performance with the practicality of having large buffers stored
177 // in memory.
178 //
179 // NOTE: this class is not thread safe
180 //
182 {
183 public:
184  // construct a temporary stream
185  // size_estimate - apporximate anticipated size of the buffer. This
186  // value is used to determine whether the buffer shaould be
187  // kept in memory or saved to hard drive.
188  UT_TempStream(exint size_estimate);
189  ~UT_TempStream();
190 
191  UT_TempStream(const UT_TempStream &) = delete;
192  UT_TempStream &operator=(const UT_TempStream &) = delete;
193 
194  // accesses the output stream for writing to the stream
195  std::ostream &getStream();
196 
197  // writes out the temp stream to an out stream
198  void copyStream( std::ostream &out );
199 
200 private:
201  // TODO: implement a default constructor that uses UT_OStrStream
202  // by default and automatically switches to file streams
203  UT_TempStream();
204 
205 private:
206 
207  UT_OStringStream *myStrStream; // memory buffer delegate
208  std::fstream *myFileStream; // file buffer delegate
209  UT_String *myFileName; // name of the temp file
210 };
211 
212 #define DECLARE_PORTABLE_RW(type) \
213  UT_API UT_OStream &UTwrite( \
214  UT_OStream &os, const type *src, int64 numelem = 1); \
215  UT_API std::ostream &UTwrite( \
216  std::ostream &os, const type *src, int64 numelem = 1); \
217  UT_API int64 UTfread( FILE *f, type *dest, int64 numelem = 1 ); \
218  UT_API int64 UTfwrite( FILE *f, const type *src, int64 numelem = 1 ); \
219 /**/
221 DECLARE_PORTABLE_RW(unsigned char)
222 DECLARE_PORTABLE_RW(signed char)
223 DECLARE_PORTABLE_RW(short)
224 DECLARE_PORTABLE_RW(unsigned short)
226 DECLARE_PORTABLE_RW(unsigned int)
229 #undef DECLARE_PORTABLE_RW
230 
231 /// Write a floating point value to given destination type, performing a
232 /// conversion as necessary.
233 // @{
234 #define DECLARE_CONVERTIBLE_RW(T) \
235  template <typename DEST_TYPE> UT_API \
236  UT_OStream & UTwrite(UT_OStream &os, const T *src, int64 cnt = 1); \
237  template <typename DEST_TYPE> UT_API \
238  std::ostream & UTwrite(std::ostream &os, const T *src, int64 cnt = 1); \
239  template <typename DEST_TYPE> UT_API \
240  int64 UTfread(FILE *f, T *dest, int64 cnt = 1); \
241  template <typename DEST_TYPE> UT_API \
242  int64 UTfwrite(FILE *f, const T *src, int64 cnt = 1); \
243 /**/
249 // @}
250 
251 // Save a chunk of binary data that may contain null characters. Use
252 // UT_IStream::readBinaryData or UT_IStream::read(std::string &) to load
253 // it back in.
255  UT_OStream &os, const char *data, int64 size,
258  std::ostream &os, const char *data, int64 size,
259  UT_STRING_BINARY_IO minbits=UT_STRING_16BIT_IO);
260 static inline void UTsaveDataBinary(
261  std::ostream &os, const std::string &data,
262  UT_STRING_BINARY_IO minbits=UT_STRING_16BIT_IO)
263 { UTsaveDataBinary(os, data.c_str(), data.size(), minbits); }
264 static inline void UTsaveDataBinary(
265  std::ostream &os, const UT_StringHolder &data,
267 { UTsaveDataBinary(os, data.c_str(), data.length(), minbits); }
268 
269 // Save a string in a binary format.
271  std::ostream &os, const char *str, UT_STRING_BINARY_IO minbits);
273  UT_OStream &os, const char *str, UT_STRING_BINARY_IO minbits);
274 
275 // Return the number of bytes required by UTsaveStringBinary() to save a string
276 // of the specified length.
278  uint64 stringlength, UT_STRING_BINARY_IO minbits);
279 
280 UT_API void UTbuildDOSCommandLine(char *dest, const char * const *args);
281 UT_API void UTbuildDOSCommandLine(UT_WorkBuffer &buf, const char * const *args);
282 
283 // Abstract base class for filtering the data before it is sent to the output
284 // stream.
286 {
287 public:
288  // virtual destructor for derived classes
289  UT_StreamBufferFilter() = default;
290  virtual ~UT_StreamBufferFilter() = default;
291 
293  UT_StreamBufferFilter &operator=(const UT_StreamBufferFilter &) = delete;
294 
295  // Often the filtering can efficently be performed only in multiple-byte
296  // chunks, or the data may grow as a result of the filtering requiring that
297  // the data is passed in smaller chunks than the actual buffer allocation
298  // size.
299  // This method returns the the maximum input size (no larger than the
300  // specified buffer size) with which the filter can work, given the buffer
301  // size (sizes in bytes).
302  virtual int getDataChunkLength( int buffer_size )
303  { return buffer_size; }
304 
305  // Before the the data is sent to a filter, the filter may need to
306  // initialize itself and/or write out some preamble.
307  // This method lets the filter write the preamble data to the
308  // buffer (up to a buffer_size), and return the data size actually written.
309  // The stream_size is the total size of the stream that is going to be
310  // filtered chunk by chunk.
311  virtual int beginFilter(char * /*buffer*/, int /*buffer_size*/,
312  int /*stream_size*/)
313  { return 0; }
314 
315  // Performs the filtering of the data in the buffer. The data size is
316  // 'data_size' which may grow, shrink, or stay the same after filtering.
317  // The filtered data length is returned by the method.
318  virtual int doFilterChunk( char *buffer, int data_size,
319  int buffer_size ) = 0;
320 
321  // After all the data has been sent to a filter, the filter may need
322  // to return some remaining filtered data, which it did not have a chance
323  // to process.
324  // This method lets the filter write the filtered data to the
325  // buffer (up to a buffer_size), and return the data size actually written.
326  virtual int endFilter( char * /*buffer*/, int /*buffer_size*/ )
327  { return 0; }
328 };
329 
330 // Writes out the buffer to the output stream, but before it is written out
331 // the buffer is filtered using the given filter. The 'size' specifies the
332 // length of the data to be filtered and written out.
333 UT_API bool UTwriteFiltered( std::ostream &os, const char *data, int size,
335 
336 // Copies the entire contents of the input stream into the output stream.
337 // Up to 'maxlen' bytes are read from the input stream. If the filter is
338 // specified, then the bytes read from the input stream are filtered before
339 // writing them to the output stream. If the filter is applied then the number
340 // of written bytes may be different than the number of bytes read.
341 UT_API bool UTcopyStreamToStream(std::istream &is, std::ostream &os,
342  size_t maxlen = ((size_t)-1),
343  UT_StreamBufferFilter * filter = NULL);
344 UT_API bool UTcopyStreamToStream(UT_IStream &is, std::ostream &os,
345  size_t maxlen = ((size_t)-1),
346  UT_StreamBufferFilter * filter = NULL);
347 
348 // Creates a unique temp file name. This name may conflict with an existing
349 // file, but the name will be unique among all _running_ Houdinis. In other
350 // words, it is safe to mindlessly overwrite the file with the given name.
351 // NOTE: The existence of the full path that is returned is not guaranteed
352 UT_API void UTcreateTempFileName(UT_String &tempfile, const char *matchExt = 0);
353 UT_API void UTcreateTempFileName(UT_WorkBuffer &tempfile, const char *matchExt = 0);
354 UT_API void UTcreateTempFileName(UT_StringHolder &tempfile, const char *matchExt = 0);
355 // The temp folder that is used to place the temp file is not guaranteed to
356 // exist. Specify that you want this function to create the path if
357 // existance is required.
358 // NOTE: if making the path fails, 'tempfile' will be empty.
359 UT_API void UTcreateTempFileName(UT_String& tempfile, bool ensure_directory_exists, const char*matchExt = 0);
360 UT_API void UTcreateTempFileName(UT_WorkBuffer& tempfile, bool ensure_directory_exists, const char* matchExt = 0);
361 UT_API void UTcreateTempFileName(UT_StringHolder& tempfile, bool ensure_directory_exists, const char* matchExt = 0);
362 
363 // Tries to create the directory that will be required to hold the specified
364 // file. Returns true if the dirctory exists of was created.
365 UT_API bool UTcreateDirectoryForFile(const char *filename);
366 
367 // This function tells you whether or not you would block if you tried to
368 // read data from a file descriptor/the standard input.
371 UT_API bool UTisStdinValid();
372 
373 // This function will wait until either data is available on a file descriptor
374 // /stdin or until the specified timeout has passed. The type of argument to
375 // the timeout is the same as the type of argument to sginap (10ms per clock
376 // tick).
377 UT_API void UTwaitForTimeoutOrDataOnFD(long clock_ticks, int fd);
378 UT_API void UTwaitForTimeoutOrDataOnStdin(long clock_ticks);
379 
380 #endif // __UT_NTStreamUtil_H__
UT_API void UTbuildDOSCommandLine(char *dest, const char *const *args)
UT_API void UTcreateTempFileName(UT_String &tempfile, const char *matchExt=0)
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2540
void freeze(bool isfrozen)
GT_API const UT_StringHolder filename
int int32
Definition: SYS_Types.h:39
UT_OStrStreamBuf * rdbuf()
UT_API bool UTisDataAvailableOnStdin()
virtual int getDataChunkLength(int buffer_size)
exint pcount() const
virtual int endFilter(char *, int)
void freeze(bool isfrozen)
int64 exint
Definition: SYS_Types.h:125
GLdouble s
Definition: glad.h:3009
An output stream object that owns its own string buffer storage.
#define UT_API
Definition: UT_API.h:14
unsigned long long uint64
Definition: SYS_Types.h:117
UT_API bool UTisStdinValid()
float fpreal32
Definition: SYS_Types.h:200
virtual int beginFilter(char *, int, int)
double fpreal64
Definition: SYS_Types.h:201
#define SYS_DEPRECATED_REPLACE(__V__, __R__)
UT_API bool UTcopyStreamToStream(std::istream &is, std::ostream &os, size_t maxlen=((size_t)-1), UT_StreamBufferFilter *filter=NULL)
GLfloat f
Definition: glcorearb.h:1926
UT_API bool UTisDataAvailableOnFD(int fd)
int UT_EnumType
Definition: core.h:760
#define DECLARE_CONVERTIBLE_RW(T)
exint length() const
UT_API void UTsaveStringBinary(std::ostream &os, const char *str, UT_STRING_BINARY_IO minbits)
UT_API void UTwaitForTimeoutOrDataOnFD(long clock_ticks, int fd)
long long int64
Definition: SYS_Types.h:116
SYS_FORCE_INLINE const char * c_str() const
GLuint const GLchar * name
Definition: glcorearb.h:786
GLenum mode
Definition: glcorearb.h:99
UT_STRING_BINARY_IO
GLsizeiptr size
Definition: glcorearb.h:664
UT_API void UTsaveDataBinary(UT_OStream &os, const char *data, int64 size, UT_STRING_BINARY_IO minbits=UT_STRING_16BIT_IO)
**If you just want to fire and args
Definition: thread.h:609
#define DECLARE_PORTABLE_RW(type)
UT_API bool UTcreateDirectoryForFile(const char *filename)
#define const
Definition: zconf.h:214
exint pcount() const
UT_API uint64 UTgetNBytesToSaveStringBinary(uint64 stringlength, UT_STRING_BINARY_IO minbits)
GLuint64 GLenum GLint fd
Definition: RE_OGL.h:262
Definition: format.h:895
UT_API void UTwaitForTimeoutOrDataOnStdin(long clock_ticks)
UT_API bool UTwriteFiltered(std::ostream &os, const char *data, int size, UT_StreamBufferFilter *filter)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1297