PageRenderTime 188ms CodeModel.GetById 32ms app.highlight 105ms RepoModel.GetById 18ms app.codeStats 1ms

/mordor/streams/limited.cpp

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