PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/mordor/streams/limited.cpp

http://github.com/mozy/mordor
C++ | 90 lines | 75 code | 13 blank | 2 comment | 16 complexity | 1412b69e0bcd7408763b094b42bffd01 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. // Copyright (c) 2009 - Mozy, Inc.
  2. #include "limited.h"
  3. #include <stdexcept>
  4. #include "mordor/assert.h"
  5. namespace Mordor {
  6. LimitedStream::LimitedStream(Stream::ptr parent, long long size, bool own)
  7. : MutatingFilterStream(parent, own),
  8. m_pos(0),
  9. m_size(size),
  10. m_strict(false)
  11. {
  12. MORDOR_ASSERT(size >= 0);
  13. }
  14. size_t
  15. LimitedStream::read(Buffer &b, size_t len)
  16. {
  17. if (m_pos >= m_size)
  18. return 0;
  19. len = (size_t)std::min<long long>(len, m_size - m_pos);
  20. size_t result = parent()->read(b, len);
  21. if (result == 0 && m_strict)
  22. MORDOR_THROW_EXCEPTION(UnexpectedEofException());
  23. m_pos += result;
  24. return result;
  25. }
  26. size_t
  27. LimitedStream::write(const Buffer &b, size_t len)
  28. {
  29. if (m_pos >= m_size)
  30. MORDOR_THROW_EXCEPTION(WriteBeyondEofException());
  31. len = (size_t)std::min<long long>(len, m_size - m_pos);
  32. size_t result = parent()->write(b, len);
  33. m_pos += result;
  34. return result;
  35. }
  36. long long
  37. LimitedStream::seek(long long offset, Anchor anchor)
  38. {
  39. if (anchor == END) {
  40. offset += size();
  41. anchor = BEGIN;
  42. }
  43. if (anchor == BEGIN && offset == m_pos) {
  44. anchor = CURRENT;
  45. offset = 0;
  46. }
  47. // If the parent doesn't support seek, we only support tell
  48. if (!parent()->supportsSeek()) {
  49. MORDOR_ASSERT(anchor == CURRENT && offset == 0);
  50. return m_pos;
  51. }
  52. return m_pos = parent()->seek(offset, anchor);
  53. }
  54. long long
  55. LimitedStream::size()
  56. {
  57. if (!parent()->supportsSize()) {
  58. return m_size;
  59. }
  60. try {
  61. return (std::min)(m_size, parent()->size());
  62. } catch (const std::runtime_error&) {
  63. return m_size;
  64. }
  65. }
  66. void
  67. LimitedStream::truncate(long long size)
  68. {
  69. MORDOR_NOTREACHED();
  70. }
  71. void
  72. LimitedStream::unread(const Buffer &b, size_t len)
  73. {
  74. parent()->unread(b, len);
  75. m_pos -= len;
  76. }
  77. }