From a963ee08e3480f8da153c63f74cbc67950b790d5 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Thu, 13 May 2004 21:32:48 +0000 Subject: [PATCH] CryptHelpers.* --- stepmania/src/CryptHelpers.cpp | 180 +++++++++++++++++++++++++++++++++ stepmania/src/CryptHelpers.h | 83 +++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 stepmania/src/CryptHelpers.cpp create mode 100644 stepmania/src/CryptHelpers.h diff --git a/stepmania/src/CryptHelpers.cpp b/stepmania/src/CryptHelpers.cpp new file mode 100644 index 0000000000..ecf00dc35c --- /dev/null +++ b/stepmania/src/CryptHelpers.cpp @@ -0,0 +1,180 @@ +#include "global.h" +#include "CryptHelpers.h" + +// crypt headers +#include "crypto51/files.h" + + + + + + + + +void RageFileStore::StoreInitialize(const NameValuePairs ¶meters) +{ + const char *fileName; + if (parameters.GetValue("InputFileName", fileName)) + { + if( !m_file.Open(fileName, RageFile::READ) ) + throw OpenErr(fileName); + } + else + { + ASSERT(0); + } + m_waiting = false; +} + +unsigned long RageFileStore::MaxRetrievable() const +{ + if( !m_file.IsOpen() ) + return 0; + + return m_file.GetFileSize() - m_file.Tell(); +} + +unsigned int RageFileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking) +{ + if( !m_file.IsOpen() ) + { + transferBytes = 0; + return 0; + } + + unsigned long size=transferBytes; + transferBytes = 0; + + if (m_waiting) + goto output; + + while( size && !m_file.AtEOF() ) + { + { + unsigned int spaceSize = 1024; + m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize); + + m_len = m_file.Read( (char *)m_space, STDMIN(size, (unsigned long)spaceSize)); + } + unsigned int blockedBytes; +output: + blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking); + m_waiting = blockedBytes > 0; + if (m_waiting) + return blockedBytes; + size -= m_len; + transferBytes += m_len; + } + + if (!m_file.AtEOF()) + throw ReadErr(); + + return 0; +} + + +unsigned int RageFileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const +{ + if( !m_file.IsOpen() ) + return 0; + + if (begin == 0 && end == 1) + { + int current = m_file.Tell(); + byte result; + m_file.Read( &result, 1 ); + if (m_file.AtEOF()) // GCC workaround: 2.95.2 doesn't have char_traits::eof() + { + m_file.Seek( current ); + return 0; + } + else + { + unsigned int blockedBytes = target.ChannelPut(channel, byte(result), blocking); + begin += 1-blockedBytes; + m_file.Seek( current ); + return blockedBytes; + } + m_file.Seek( current ); + } + + // TODO: figure out what happens on cin + int current = m_file.Tell(); + int endPosition = m_file.GetFileSize(); + m_file.Seek( endPosition ); + int newPosition = current + (streamoff)begin; + + if (newPosition >= endPosition) + { + m_file.Seek(current); + return 0; // don't try to seek beyond the end of file + } + m_file.Seek(newPosition); + unsigned long total = 0; + try + { + assert(!m_waiting); + unsigned long copyMax = end-begin; + unsigned int blockedBytes = const_cast(this)->TransferTo2(target, copyMax, channel, blocking); + begin += copyMax; + if (blockedBytes) + { + const_cast(this)->m_waiting = false; + return blockedBytes; + } + } + catch(...) + { + m_file.ClearError(); + m_file.Seek(current); + throw; + } + m_file.ClearError(); + m_file.Seek(current); + + return 0; +} + +void RageFileSink::IsolatedInitialize(const NameValuePairs ¶meters) +{ + const char *fileName; + if (parameters.GetValue("OutputFileName", fileName)) + { + ios::openmode binary = parameters.GetValueWithDefault("OutputBinaryMode", true) ? ios::binary : ios::openmode(0); + if( !m_file.Open( fileName, RageFile::WRITE ) ) // trucates existing data + throw OpenErr(fileName); + } + else + { + ASSERT(0); + } +} + +bool RageFileSink::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!m_file.IsOpen()) + throw Err("FileSink: output stream not opened"); + + m_file.Flush(); + if( !m_file.GetError().empty() ) + throw WriteErr(); + + return false; +} + +unsigned int RageFileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking) +{ + if (!m_file.IsOpen()) + throw Err("FileSink: output stream not opened"); + + m_file.Write((const char *)inString, length); + + if (messageEnd) + m_file.Flush(); + + if( !m_file.GetError().empty() ) + throw WriteErr(); + + return 0; +} + diff --git a/stepmania/src/CryptHelpers.h b/stepmania/src/CryptHelpers.h new file mode 100644 index 0000000000..cbb45d68b9 --- /dev/null +++ b/stepmania/src/CryptHelpers.h @@ -0,0 +1,83 @@ +#ifndef CryptHelpers_H +#define CryptHelpers_H + +#include "RageFile.h" + +// crypt headers +#include "crypto51/files.h" +#include "crypto51/filters.h" +#include "crypto51/cryptlib.h" + +using namespace CryptoPP; + +//! . +class RageFileStore : public Store, private FilterPutSpaceHelper +{ +public: + class Err : public Exception + { + public: + Err(const std::string &s) : Exception(IO_ERROR, s) {} + }; + class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}}; + class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}}; + + RageFileStore() {} + RageFileStore(const char *filename) + {StoreInitialize(MakeParameters("InputFileName", filename));} + + unsigned long MaxRetrievable() const; + unsigned int TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + unsigned int CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end=ULONG_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + +private: + void StoreInitialize(const NameValuePairs ¶meters); + + mutable RageFile m_file; // mutable so that we can call RageFile::GetFileSize() + byte *m_space; + unsigned int m_len; + bool m_waiting; +}; + +//! . +class RageFileSource : public SourceTemplate +{ +public: + typedef FileStore::Err Err; + typedef FileStore::OpenErr OpenErr; + typedef FileStore::ReadErr ReadErr; + + RageFileSource(BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {} + RageFileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputStreamPointer", &in));} + RageFileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputFileName", filename)("InputBinaryMode", binary));} +}; + + +//! . +class RageFileSink : public Sink +{ +public: + class Err : public Exception + { + public: + Err(const std::string &s) : Exception(IO_ERROR, s) {} + }; + class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileSink: error opening file for writing: " + filename) {}}; + class WriteErr : public Err {public: WriteErr() : Err("FileSink: error writing file") {}}; + + RageFileSink() {} + RageFileSink(const char *filename, bool binary=true) + {IsolatedInitialize(MakeParameters("OutputFileName", filename)("OutputBinaryMode", binary));} + + void IsolatedInitialize(const NameValuePairs ¶meters); + unsigned int Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking); + bool IsolatedFlush(bool hardFlush, bool blocking); + +private: + RageFile m_file; +}; + +#endif