PageRenderTime 122ms CodeModel.GetById 40ms app.highlight 40ms RepoModel.GetById 41ms app.codeStats 0ms

/mordor/streams/notify.h

http://github.com/mozy/mordor
C Header | 101 lines | 84 code | 16 blank | 1 comment | 11 complexity | 9c807af314059ba64e3fb8da85c414de MD5 | raw file
  1#ifndef __MORDOR_NOTIFY_STREAM_H__
  2#define __MORDOR_NOTIFY_STREAM_H__
  3// Copyright (c) 2009 - Mozy, Inc.
  4
  5#include <boost/function.hpp>
  6
  7#include "filter.h"
  8
  9namespace Mordor {
 10
 11class NotifyStream : public FilterStream
 12{
 13public:
 14    typedef boost::shared_ptr<NotifyStream> ptr;
 15public:
 16    NotifyStream(Stream::ptr parent, bool own = true)
 17        : FilterStream(parent, own)
 18    {}
 19
 20    boost::function<void ()> notifyOnFlush;
 21    boost::function<void ()> notifyOnEof;
 22    boost::function<void ()> notifyOnException;
 23
 24    void close(CloseType type = BOTH)
 25    {
 26        try {
 27            if (ownsParent())
 28                parent()->close(type);
 29        } catch (...) {
 30            if (notifyOnException)
 31                notifyOnException();
 32            throw;
 33        }
 34        if (m_notifyOnClose)
 35            m_notifyOnClose(type);
 36    }
 37
 38    using FilterStream::read;
 39    size_t read(Buffer &b, size_t len)
 40    {
 41        size_t result;
 42        try {
 43            result = parent()->read(b, len);
 44        } catch(...) {
 45            if (notifyOnException)
 46                notifyOnException();
 47            throw;
 48        }
 49        if (result == 0 && notifyOnEof)
 50            notifyOnEof();
 51        return result;
 52    }
 53
 54    using FilterStream::write;
 55    size_t write(const Buffer &b, size_t len)
 56    {
 57        try {
 58            return parent()->write(b, len);
 59        } catch(...) {
 60            if (notifyOnException)
 61                notifyOnException();
 62            throw;
 63        }
 64    }
 65
 66    void flush(bool flushParent = true)
 67    {
 68        try {
 69            parent()->flush(flushParent);
 70        } catch(...) {
 71            if (notifyOnException)
 72                notifyOnException();
 73            throw;
 74        }
 75        if (notifyOnFlush)
 76            notifyOnFlush();
 77    }
 78
 79    void notifyOnClose(boost::function<void ()> dg = NULL)
 80    {
 81        if (dg)
 82            notifyOnClose2(boost::bind(&NotifyStream::onCloseAdapter, dg, _1));
 83        else
 84            notifyOnClose2(NULL);
 85    }
 86
 87    void notifyOnClose2(boost::function<void (CloseType)> dg)
 88    { m_notifyOnClose = dg; }
 89
 90private:
 91    static void onCloseAdapter(boost::function<void ()> dg, CloseType type)
 92    { dg(); }
 93
 94private:
 95    boost::function<void (CloseType)> m_notifyOnClose;
 96
 97};
 98
 99}
100
101#endif