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 protected:
86  // write one character
87  int_type overflow(int_type c) override;
88 
89  // In order to allow tellg to work, we need to provide seekoff.
90  pos_type seekoff(off_type _Off,
91  std::ios_base::seekdir _Way,
92  std::ios_base::openmode
93  _Mode = std::ios::out) override;
94  pos_type seekpos(pos_type _Off,
95  std::ios_base::openmode
96  _Mode = std::ios::out) override;
97 
98  // write multiple characters
99  std::streamsize xsputn(const char* s, std::streamsize num) override;
100 
101 public:
102  // Crappy strstreambuf equivalent functions
103  char *str()
104  {
105  freeze(true);
106  return myBuf;
107  }
108 
109  void freeze(bool isfrozen)
110  {
111  myOwnBuf = !isfrozen;
112  }
113 
114  // Note this is the current put position, not the entries!
115  exint pcount() const
116  {
117  return myOffset;
118  }
119 
120 protected:
121  bool resizeBuf(exint minnewsize);
122 
123  exint mySize, myEntries, myOffset;
124  bool myOwnBuf;
125  char *myBuf;
126 };
127 
128 /// Our portable and much improved strstream
129 /// Uses an exint buffer to allow greater than 2gb streams.
130 class UT_API UT_OStrStream : public std::ostream
131 {
132 public:
134  UT_OStrStream();
135 
137  explicit UT_OStrStream(exint initialsize);
138 
139  /// The stream does *not* gain ownership of this buffer!
140  /// This means it will not resize if it overflows this buffer.
141 #if !defined(WIN32)
143  UT_OStrStream(char *pch, exint nLength,
144  std::ios::openmode = std::ios::out);
145 #else
147  UT_OStrStream(char *pch, exint nLength, int nMode = std::ios::out);
148 #endif
149 
150  /// Note: This is old-school streams!
151  /// You own the result of str() and must either free() it or invoke
152  /// freeze(false)!
153  char *str() { return myBuf.str(); }
154  void freeze(bool isfrozen) { myBuf.freeze(isfrozen); }
155 
156  exint pcount() const
157  {
158  return myBuf.pcount();
159  }
160 
161  // Return this properly cast so people can get at our freeze, etc.
162  UT_OStrStreamBuf *rdbuf() { return &myBuf; }
163 
164  ~UT_OStrStream() override {}
165 
166 private:
167  UT_OStrStreamBuf myBuf;
168 };
169 
170 // A temporary stream that uses UT_OStrStream by default unless the buffer
171 // size is so big that it should be saved on disk. Tries to balance
172 // performance with the practicality of having large buffers stored
173 // in memory.
174 //
175 // NOTE: this class is not thread safe
176 //
178 {
179 public:
180  // construct a temporary stream
181  // size_estimate - apporximate anticipated size of the buffer. This
182  // value is used to determine whether the buffer shaould be
183  // kept in memory or saved to hard drive.
184  UT_TempStream(exint size_estimate);
185  ~UT_TempStream();
186 
187  // accesses the output stream for writing to the stream
188  std::ostream &getStream();
189 
190  // writes out the temp stream to an out stream
191  void copyStream( std::ostream &out );
192 
193 private:
194  // TODO: implement a default constructor that uses UT_OStrStream
195  // by default and automatically switches to file streams
196  UT_TempStream();
197 
198 private:
199 
200  UT_OStringStream *myStrStream; // memory buffer delegate
201  std::fstream *myFileStream; // file buffer delegate
202  UT_String *myFileName; // name of the temp file
203 };
204 
205 #define DECLARE_PORTABLE_RW(type) \
206  UT_API UT_OStream &UTwrite( \
207  UT_OStream &os, const type *src, int64 numelem = 1); \
208  UT_API std::ostream &UTwrite( \
209  std::ostream &os, const type *src, int64 numelem = 1); \
210  UT_API int64 UTfread( FILE *f, type *dest, int64 numelem = 1 ); \
211  UT_API int64 UTfwrite( FILE *f, const type *src, int64 numelem = 1 ); \
212 /**/
214 DECLARE_PORTABLE_RW(unsigned char)
215 DECLARE_PORTABLE_RW(signed char)
216 DECLARE_PORTABLE_RW(short)
217 DECLARE_PORTABLE_RW(unsigned short)
219 DECLARE_PORTABLE_RW(unsigned int)
222 #undef DECLARE_PORTABLE_RW
223 
224 /// Write a floating point value to given destination type, performing a
225 /// conversion as necessary.
226 // @{
227 #define DECLARE_CONVERTIBLE_RW(T) \
228  template <typename DEST_TYPE> UT_API \
229  UT_OStream & UTwrite(UT_OStream &os, const T *src, int64 cnt = 1); \
230  template <typename DEST_TYPE> UT_API \
231  std::ostream & UTwrite(std::ostream &os, const T *src, int64 cnt = 1); \
232  template <typename DEST_TYPE> UT_API \
233  int64 UTfread(FILE *f, T *dest, int64 cnt = 1); \
234  template <typename DEST_TYPE> UT_API \
235  int64 UTfwrite(FILE *f, const T *src, int64 cnt = 1); \
236 /**/
242 // @}
243 
244 // Save a chunk of binary data that may contain null characters. Use
245 // UT_IStream::readBinaryData or UT_IStream::read(std::string &) to load
246 // it back in.
248  UT_OStream &os, const char *data, int64 size,
251  std::ostream &os, const char *data, int64 size,
252  UT_STRING_BINARY_IO minbits=UT_STRING_16BIT_IO);
253 static inline void UTsaveDataBinary(
254  std::ostream &os, const std::string &data,
255  UT_STRING_BINARY_IO minbits=UT_STRING_16BIT_IO)
256 { UTsaveDataBinary(os, data.c_str(), data.size(), minbits); }
257 static inline void UTsaveDataBinary(
258  std::ostream &os, const UT_StringHolder &data,
260 { UTsaveDataBinary(os, data.c_str(), data.length(), minbits); }
261 
262 // Save a string in a binary format.
264  std::ostream &os, const char *str, UT_STRING_BINARY_IO minbits);
266  UT_OStream &os, const char *str, UT_STRING_BINARY_IO minbits);
267 
268 // Return the number of bytes required by UTsaveStringBinary() to save a string
269 // of the specified length.
271  uint64 stringlength, UT_STRING_BINARY_IO minbits);
272 
273 UT_API void UTbuildDOSCommandLine(char *dest, const char * const *args);
274 UT_API void UTbuildDOSCommandLine(UT_WorkBuffer &buf, const char * const *args);
275 
276 // Abstract base class for filtering the data before it is sent to the output
277 // stream.
279 {
280 public:
281  // virtual destructor for derived classes
283  {};
284 
285  // Often the filtering can efficently be performed only in multiple-byte
286  // chunks, or the data may grow as a result of the filtering requiring that
287  // the data is passed in smaller chunks than the actual buffer allocation
288  // size.
289  // This method returns the the maximum input size (no larger than the
290  // specified buffer size) with which the filter can work, given the buffer
291  // size (sizes in bytes).
292  virtual int getDataChunkLength( int buffer_size )
293  { return buffer_size; }
294 
295  // Before the the data is sent to a filter, the filter may need to
296  // initialize itself and/or write out some preamble.
297  // This method lets the filter write the preamble data to the
298  // buffer (up to a buffer_size), and return the data size actually written.
299  // The stream_size is the total size of the stream that is going to be
300  // filtered chunk by chunk.
301  virtual int beginFilter(char * /*buffer*/, int /*buffer_size*/,
302  int /*stream_size*/)
303  { return 0; }
304 
305  // Performs the filtering of the data in the buffer. The data size is
306  // 'data_size' which may grow, shrink, or stay the same after filtering.
307  // The filtered data length is returned by the method.
308  virtual int doFilterChunk( char *buffer, int data_size,
309  int buffer_size ) = 0;
310 
311  // After all the data has been sent to a filter, the filter may need
312  // to return some remaining filtered data, which it did not have a chance
313  // to process.
314  // This method lets the filter write the filtered data to the
315  // buffer (up to a buffer_size), and return the data size actually written.
316  virtual int endFilter( char * /*buffer*/, int /*buffer_size*/ )
317  { return 0; }
318 };
319 
320 // Writes out the buffer to the output stream, but before it is written out
321 // the buffer is filtered using the given filter. The 'size' specifies the
322 // length of the data to be filtered and written out.
323 UT_API bool UTwriteFiltered( std::ostream &os, const char *data, int size,
325 
326 // Copies the entire contents of the input stream into the output stream.
327 // Up to 'maxlen' bytes are read from the input stream. If the filter is
328 // specified, then the bytes read from the input stream are filtered before
329 // writing them to the output stream. If the filter is applied then the number
330 // of written bytes may be different than the number of bytes read.
331 UT_API bool UTcopyStreamToStream(std::istream &is, std::ostream &os,
332  size_t maxlen = ((size_t)-1),
333  UT_StreamBufferFilter * filter = NULL);
334 UT_API bool UTcopyStreamToStream(UT_IStream &is, std::ostream &os,
335  size_t maxlen = ((size_t)-1),
336  UT_StreamBufferFilter * filter = NULL);
337 
338 // Creates a unique temp file name. This name may conflict with an existing
339 // file, but the name will be unique among all _running_ Houdinis. In other
340 // words, it is safe to mindlessly overwrite the file with the given name.
341 // NOTE: The existence of the full path that is returned is not guaranteed
342 UT_API void UTcreateTempFileName(UT_String &tempfile, const char *matchExt = 0);
343 UT_API void UTcreateTempFileName(UT_WorkBuffer &tempfile, const char *matchExt = 0);
344 UT_API void UTcreateTempFileName(UT_StringHolder &tempfile, const char *matchExt = 0);
345 // The temp folder that is used to place the temp file is not guaranteed to
346 // exist. Specify that you want this function to create the path if
347 // existance is required.
348 // NOTE: if making the path fails, 'tempfile' will be empty.
349 UT_API void UTcreateTempFileName(UT_String& tempfile, bool ensure_directory_exists, const char*matchExt = 0);
350 UT_API void UTcreateTempFileName(UT_WorkBuffer& tempfile, bool ensure_directory_exists, const char* matchExt = 0);
351 UT_API void UTcreateTempFileName(UT_StringHolder& tempfile, bool ensure_directory_exists, const char* matchExt = 0);
352 
353 // Tries to create the directory that will be required to hold the specified
354 // file. Returns true if the dirctory exists of was created.
355 UT_API bool UTcreateDirectoryForFile(const char *filename);
356 
357 // This function tells you whether or not you would block if you tried to
358 // read data from a file descriptor/the standard input.
359 UT_API bool UTisDataAvailableOnFD(int fd);
361 UT_API bool UTisStdinValid();
362 
363 // This function will wait until either data is available on a file descriptor
364 // /stdin or until the specified timeout has passed. The type of argument to
365 // the timeout is the same as the type of argument to sginap (10ms per clock
366 // tick).
367 UT_API void UTwaitForTimeoutOrDataOnFD(long clock_ticks, int fd);
368 UT_API void UTwaitForTimeoutOrDataOnStdin(long clock_ticks);
369 
370 #endif // __UT_NTStreamUtil_H__
GLdouble s
Definition: glew.h:1390
UT_API void UTbuildDOSCommandLine(char *dest, const char *const *args)
UT_API void UTcreateTempFileName(UT_String &tempfile, const char *matchExt=0)
void freeze(bool isfrozen)
GT_API const UT_StringHolder filename
GLsizeiptr size
Definition: glew.h:1681
int int32
Definition: SYS_Types.h:39
GLuint const GLchar * name
Definition: glew.h:1814
UT_OStrStreamBuf * rdbuf()
UT_API bool UTisDataAvailableOnStdin()
virtual int getDataChunkLength(int buffer_size)
GLenum mode
Definition: glew.h:2163
const Args & args
Definition: printf.h:628
exint pcount() const
virtual int endFilter(char *, int)
void freeze(bool isfrozen)
int64 exint
Definition: SYS_Types.h:125
An output stream object that owns its own string buffer storage.
#define UT_API
Definition: UT_API.h:13
virtual ~UT_StreamBufferFilter()
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)
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:2981
UT_API bool UTisDataAvailableOnFD(int fd)
int UT_EnumType
#define DECLARE_CONVERTIBLE_RW(T)
GLclampf f
Definition: glew.h:3499
exint length() const
GLuint in
Definition: glew.h:11510
GLuint buffer
Definition: glew.h:1680
GLint GLenum GLsizei GLint GLsizei const void * data
Definition: glew.h:1379
UT_API void UTsaveStringBinary(std::ostream &os, const char *str, UT_STRING_BINARY_IO minbits)
UT_API void UTwaitForTimeoutOrDataOnFD(long clock_ticks, int fd)
const GLfloat * c
Definition: glew.h:16296
long long int64
Definition: SYS_Types.h:116
SYS_FORCE_INLINE const char * c_str() const
UT_STRING_BINARY_IO
UT_API void UTsaveDataBinary(UT_OStream &os, const char *data, int64 size, UT_STRING_BINARY_IO minbits=UT_STRING_16BIT_IO)
GLuint num
Definition: glew.h:2690
#define DECLARE_PORTABLE_RW(type)
~UT_OStrStream() override
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)
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2580
UT_API void UTwaitForTimeoutOrDataOnStdin(long clock_ticks)
UT_API bool UTwriteFiltered(std::ostream &os, const char *data, int size, UT_StreamBufferFilter *filter)
GLenum GLsizei len
Definition: glew.h:7752