open_toontown_panda3d/dtool/src/prc/streamWrapper.h

133 lines
4.5 KiB
C++

// Filename: streamWrapper.h
// Created by: drose (11Nov08)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef STREAMWRAPPER_H
#define STREAMWRAPPER_H
#include "dtoolbase.h"
#include "mutexImpl.h"
////////////////////////////////////////////////////////////////////
// Class : StreamWrapperBase
// Description : The base class for both IStreamWrapper and
// OStreamWrapper, this provides the common locking
// interface.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG StreamWrapperBase {
protected:
INLINE StreamWrapperBase();
PUBLISHED:
INLINE void acquire();
INLINE void release();
private:
MutexImpl _lock;
#ifdef SIMPLE_THREADS
// In the SIMPLE_THREADS case, we need to use a bool flag, because
// MutexImpl defines to nothing in this case--but we still need to
// achieve a form of locking, since I/O operations can cause the
// thread to swap without warning.
bool _lock_flag;
#endif
};
////////////////////////////////////////////////////////////////////
// Class : IStreamWrapper
// Description : This class provides a locking wrapper around an
// arbitrary istream pointer. A thread may use this
// class to perform an atomic seek/read/gcount
// operation.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG IStreamWrapper : virtual public StreamWrapperBase {
public:
INLINE IStreamWrapper(istream *stream, bool owns_pointer);
PUBLISHED:
INLINE IStreamWrapper(istream &stream);
~IStreamWrapper();
INLINE istream *get_istream() const;
public:
void read(char *buffer, streamsize num_bytes);
void read(char *buffer, streamsize num_bytes, streamsize &read_bytes);
void read(char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof);
void seek_read(streamsize pos, char *buffer, streamsize num_bytes, streamsize &read_bytes, bool &eof);
INLINE int get();
streamsize seek_gpos_eof();
private:
istream *_istream;
bool _owns_pointer;
};
////////////////////////////////////////////////////////////////////
// Class : OStreamWrapper
// Description : This class provides a locking wrapper around an
// arbitrary ostream pointer. A thread may use this
// class to perform an atomic seek/write operation.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG OStreamWrapper : virtual public StreamWrapperBase {
public:
INLINE OStreamWrapper(ostream *stream, bool owns_pointer, bool stringstream_hack = false);
PUBLISHED:
INLINE OStreamWrapper(ostream &stream);
~OStreamWrapper();
INLINE ostream *get_ostream() const;
public:
void write(const char *buffer, streamsize num_bytes);
void write(const char *buffer, streamsize num_bytes, bool &fail);
void seek_write(streamsize pos, const char *buffer, streamsize num_bytes, bool &fail);
void seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail);
INLINE bool put(char c);
streamsize seek_ppos_eof();
private:
ostream *_ostream;
bool _owns_pointer;
// This flag is necessary to work around a weird quirk in the MSVS
// C++ runtime library: an empty stringstream cannot successfully
// seekp(0), until some data has been written to the stream. When
// this flag is set true, we know we have a possibly-empty
// stringstream, so we allow seekp(0) to fail silently, knowing that
// there's no harm in this case.
bool _stringstream_hack;
};
////////////////////////////////////////////////////////////////////
// Class : StreamWrapper
// Description : This class provides a locking wrapper around a
// combination ostream/istream pointer.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOLCONFIG StreamWrapper : public IStreamWrapper, public OStreamWrapper {
public:
INLINE StreamWrapper(iostream *stream, bool owns_pointer, bool stringstream_hack = false);
PUBLISHED:
INLINE StreamWrapper(iostream &stream);
~StreamWrapper();
INLINE iostream *get_iostream() const;
private:
iostream *_iostream;
bool _owns_pointer;
};
#include "streamWrapper.I"
#endif