📄 axpipe.h
字号:
#pragma once
#ifndef AXPIPE_H
#define AXPIPE_H
/*! \file
\brief Main class declarations, AxPipe::CSource, AxPipe::CPipe, AxPipe::CFilter, AxPipe::CSink, AxPipe::CSplit, AxPipe::CJoin
@(#) $Id: AxPipe.h,v 1.5 2004/06/28 19:39:15 svante Exp $
*/
/*! \page License AxPipe - Multi-Threaded Binary Stream Class Library
Copyright (C) 2003 Svante Seleborg/Axon Data, All rights reserved.
This program is free software; you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program;
if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
The author may be reached at mailto:axpipe@axondata.se and http://axpipe.sourceforge.net
Why is this framework released as GPL and not LGPL?
See http://www.gnu.org/philosophy/why-not-lgpl.html
*/
/*!
\verbatim
AxPipe.h Main class declarations
E-mail YYYY-MM-DD Reason
axpipe@axondata.se 2003-11-23 Initial
\endverbatim
*/
// When AxPipe is made portable, this Windows-stuff must be moved out of here. It's here right now
// to enable code that uses AxPipe to "appear" portable, in that that code at least does not need to
// define and include all this.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN ///< Exclude rarely-used stuff from Windows headers
#endif
// Minimum System Required: Internet Explorer 4.0, Windows 98 and Windows NT 4.0
//
// When this code is released, Windows 95 is almost 1 year after end-of-life announcement
// and the code requires, among other things, fibers which are not supported on Win95.
//
// If previously defined requirements are of a higher version, we reduce them to our level
// otherwise we leave them alone.
//
#if WINVER > 0x0400
#undef WINVER
#endif
#ifndef WINVER
#define WINVER 0x0400 ///< Windows 95 and Windows NT 4.0
#endif
#if _WIN32_IE > 0x0400
#undef _WIN32_IE
#endif
#ifndef _WIN32_IE
#define _WIN32_IE 0x0400 ///< Internet Explorer 4.0
#endif
#if _WIN32_WINNT > 0x0410
#undef _WIN32_WINNT
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0410 ///< Windows 98 and Windows NT 4.0
#endif
// We include all necessary headers to make this an independent header, even if
// they usually will be included anyway.
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <assert.h>
#include <tchar.h>
#include <stdlib.h>
// Common base classes
#include "CError.h"
#include "CSeg.h"
#include "CSync.h"
#include "CThread.h"
#include "CCoContext.h"
#include "AxAssert.h"
#define AXLIB_ASSERT_FILE "AxPipe.h"
/*! \mainpage AxPipe Multi-Threaded Binary Stream Class Library
\version
\htmlinclude Version.txt
\author
Svante Seleborg/Axon Data
\par License:
\ref License "GNU General Public License"
AxPipe is a multi-threading basic binary stream class hierarchy.
It provides all required functionality for push and pull style
processing of data in a stream model, and it also
also enables optimizations
in memory handling, minimizing buffer copying but with full optional multi
threading support, with negligable overhead.
The basic paradigm is taken from the Unix Shell pipe notation, where you might
write:
crypt <file.txt | compress | tar >out.tar
but you can also write, for example,
tar <file.txt | crypt | compress >out.z
The programs above are semi-ficticious, it's just to demonstrate the principle whereby
input sources, such as a file can be redirected into a processing program, which
sends it on, where it can be connected to another processing program, or to a
final destination.
I've frequently wanted to use the same principle for programming purposes in C++,
but with minimal overhead and supporting different programming models. So I
wrote this package.
\see \ref PageIntro "Introduction", \ref PageInstall "Installation", \ref PageSample1 "A First Example",
\ref PageSample2 "A Second Examle",
\ref PageDef "Definitions of Terms", \ref PageStock "Stock Transformations", \ref PageUtil "Utilities and Overrides"
Go to the <A HREF="http://sourceforge.net/projects/axpipe">SourceForge project page</A> for downloads etc.
*/
//
// Use the Windows convention for Unicode/Ansi switcheable code, but if nothing
// is defined, we default to Ansi here. Change as appropriate if necessary.
//
#ifndef _T
#define _T(s) s ///< Default to Ansi. Use tchar.h on Windows.
#define _TCHAR char ///< Default to char. Use tchar.h on Windows.
#endif
/// \namespace AxPipe
/// \brief The main namespace where all identifiers should be.
///
/// Use using AxPipe; or AxPipe:: prefix for all references to identifiers
/// except macros in the framework.
namespace AxPipe {
/// \brief Stock transforms with AxPipe
///
/// Stock, or Standard transformations that are part of the
/// package, but separate from the framework, are collected
/// for convenience in this namespace. They will be classes
/// that are derived from the standard AxPipe classes,
/// implementing specific sources, transformations and sinks.
namespace Stock {
// Dummy, just to get the description of the namespace documented.
}
/// \brief A minimal safe-pointer class
///
/// Define a minimal version of std::auto_ptr, the reason being that
/// the library version may throw, which we do not want to require all
/// AxPipe-programs to support.
template<class T> class my_ptr {
T *m_p; ///< The stored pointer, or NULL
public:
/// \brief Construct from pointer
my_ptr(T *p = NULL) : m_p(p) {}
/// \brief Assign from one object to this, releasing the the source.
/// \return A reference to this pointer object
my_ptr<T>& operator=(my_ptr<T>& rhs) {
reset(rhs.release());
return *this;
}
/// \brief Delete the object pointed to
~my_ptr() {
delete m_p;
}
/// \brief Dereference
/// \return Reference to the pointed to object
T& operator*() const {
return (*get());
}
/// \brief Get pointer
/// \return The pointer
T *operator->() const {
return get();
}
/// \brief Get pointer
/// \return The pointer
T *get() const {
return m_p;
}
/// \brief Get the pointer and release it from us
/// \return The pointer, now unmanaged
T *release() {
T *p = m_p;
m_p = NULL;
return p;
}
/// \brief Store a new poiner, possibly deleting the old
/// \param p The new pointer
void reset(T* p = NULL) {
if (p != m_p) delete m_p;
m_p = p;
}
};
class CSeg;
/// Used to keep track of thread fiber-status for the pull-filter mode classes.
extern DWORD dwTlsIndex;
/// Keep track of how global initialization count.
extern volatile long nGlobalInit;
//
// The error class is a virtual base class to all the others,
// and is used to record errors. Normally, errors are not passed
// by return value, nor are any exceptions thrown.
//
// Use SetError() to indicate an error, and GetError(), to check for one.
/// ERROR_CODE_GENERIC - for most errors, one string argument.
static const _TCHAR *ERROR_MSG_GENERIC = _T("AxPipe:: %s");
/// ERROR_CODE_INTERNAL - for fatal internal errors, one string argument.
static const _TCHAR *ERROR_MSG_INTERNAL = _T("AxPipe:: Internal error %s");
/// ERROR_CODE_NOTOPEN - Sequence error in operations - need open first.
static const _TCHAR *ERROR_MSG_NOTOPEN = _T("AxPipe:: Pipe not Open");
/// \brief AxPipe pre-defined error codes, gettable with GetErrorCode().
enum ERROR_CODE {
ERROR_CODE_SUCCESS = 0, ///< No error
ERROR_CODE_GENERIC, ///< Use for most error, details in the string argument.
ERROR_CODE_INTERNAL, ///< Used for internal framework errors (bugs).
ERROR_CODE_NOTOPEN, ///< Attempt to do something on a pipe that's not open.
ERROR_CODE_STOCK, ///< An error from a stock transformation
ERROR_CODE_DERIVED = 100, ///< Start here for user-derived classes error codes.
};
// Modify according to compiler version. Include appropriate #ifdef's.
typedef __int64 longlong; ///< Substitute for long long which is not always supported
typedef unsigned __int64 ulonglong; ///< Substitute for unsigned long long which is not always supported
/// CSeg's keep track of an opaque segment type meta-data value, which is an int.
/// User-defined must be non-zero, because the default value is zero. These are
/// used to mark the special in-band signals for Open, Close and Plug. When we
/// send CSeg's down the line with a type from this list, the code does special
/// things, such as calling OutOpen(), OutClose() and Plug() respectively.
/// \brief Special segment value types that have meaning in the data pump.
enum eSegType {
eSegTypeOpen = 1, ///< Send signal to open in band
eSegTypeFlush, ///< Send signal to flush in band
eSegTypeClose, ///< Send signal to close in band
eSegTypePlug, ///< Send signal to plug in band
eSegTypeSignal, ///< Send a generic signal. The data is of type CSignal
eSegTypeDerived = 100, ///< Start your own definitions here
};
/// \brief The payload of an eSegTypeSignal in-band signal.
///
/// A container for data intended for sending via in-band signalling. It is propagated by
/// the framework, unless a section stops it. There is potential for race conditions if the
/// data is used outside of the OutSpecial() receiving function, for example storing the contents
/// in the class and using it later. The differents parts of the pipe line may run in different threads.
/// The intention is that a receiver will check the Id and if it matches expectations, pick up
/// the opaque pointer and cast it appropriately for further use. The pointer itself should normally
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -