PageRenderTime 15ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/mordor/streams/duplex.h

http://github.com/mozy/mordor
C Header | 94 lines | 79 code | 10 blank | 5 comment | 15 complexity | f1450de792242278192a9e52f5e1bf2a MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #ifndef __MORDOR_DUPLEX_STREAM_H__
  2. #define __MORDOR_DUPLEX_STREAM_H__
  3. // Copyright (c) 2009 - Mozy, Inc.
  4. #include "stream.h"
  5. namespace Mordor {
  6. // A DuplexStream combines a read and a write stream to form a stream that can
  7. // be read and written to. It *disables* seek(), size(), and truncate(),
  8. // because the parent streams are disparate, and those concepts are supposed
  9. // to be shared
  10. class DuplexStream : public Stream
  11. {
  12. public:
  13. DuplexStream(Stream::ptr readParent, Stream::ptr writeParent,
  14. bool own = true)
  15. : m_readParent(readParent),
  16. m_writeParent(writeParent),
  17. m_own(own)
  18. {
  19. MORDOR_ASSERT(readParent);
  20. MORDOR_ASSERT(writeParent);
  21. MORDOR_ASSERT(readParent->supportsRead());
  22. MORDOR_ASSERT(writeParent->supportsWrite());
  23. }
  24. Stream::ptr readParent() { return m_readParent; }
  25. Stream::ptr writeParent() { return m_writeParent; }
  26. bool ownsParents() { return m_own; }
  27. bool supportsHalfClose() { return true; }
  28. bool supportsRead() { return true; }
  29. bool supportsWrite() { return true; }
  30. bool supportsFind() { return m_readParent && m_readParent->supportsFind(); }
  31. bool supportsUnread() { return m_readParent && m_readParent->supportsUnread(); }
  32. void close(CloseType type = BOTH)
  33. {
  34. if (m_own) {
  35. if ((type & READ) && m_readParent)
  36. m_readParent->close(m_readParent->supportsHalfClose() ? READ : BOTH);
  37. if ((type & WRITE) && m_writeParent)
  38. m_writeParent->close(m_writeParent->supportsHalfClose() ? WRITE : BOTH);
  39. }
  40. if (type & READ)
  41. m_readParent.reset();
  42. if (type & WRITE)
  43. m_writeParent.reset();
  44. }
  45. using Stream::read;
  46. size_t read(Buffer &b, size_t len)
  47. {
  48. if (!m_readParent) MORDOR_THROW_EXCEPTION(BrokenPipeException());
  49. return m_readParent->read(b, len);
  50. }
  51. using Stream::write;
  52. size_t write(const Buffer &b, size_t len)
  53. {
  54. if (!m_writeParent) MORDOR_THROW_EXCEPTION(BrokenPipeException());
  55. return m_writeParent->write(b, len);
  56. }
  57. void flush(bool flushParent = true)
  58. {
  59. if (!m_writeParent) MORDOR_THROW_EXCEPTION(BrokenPipeException());
  60. m_writeParent->flush();
  61. }
  62. using Stream::find;
  63. ptrdiff_t find(char delim)
  64. {
  65. if (!m_readParent) MORDOR_THROW_EXCEPTION(BrokenPipeException());
  66. return m_readParent->find(delim);
  67. }
  68. ptrdiff_t find(const std::string &str, size_t sanitySize = ~0, bool throwOnNotFound = true)
  69. {
  70. if (!m_readParent) MORDOR_THROW_EXCEPTION(BrokenPipeException());
  71. return m_readParent->find(str, sanitySize, throwOnNotFound);
  72. }
  73. void unread(const Buffer &b, size_t len) {
  74. if (!m_readParent) MORDOR_THROW_EXCEPTION(BrokenPipeException());
  75. return m_readParent->unread(b, len);
  76. }
  77. protected:
  78. void ownsParents(bool own) { m_own = own; }
  79. private:
  80. Stream::ptr m_readParent, m_writeParent;
  81. bool m_own;
  82. };
  83. }
  84. #endif