Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

files.cpp

00001 // files.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "files.h"
00005 
00006 NAMESPACE_BEGIN(CryptoPP)
00007 
00008 using namespace std;
00009 
00010 void Files_TestInstantiations()
00011 {
00012         FileStore f0;
00013         FileSource f1;
00014         FileSink f2;
00015 }
00016 
00017 void FileStore::StoreInitialize(const NameValuePairs &parameters)
00018 {
00019         const char *fileName;
00020         if (parameters.GetValue("InputFileName", fileName))
00021         {
00022                 ios::openmode binary = parameters.GetValueWithDefault("InputBinaryMode", true) ? ios::binary : ios::openmode(0);
00023                 m_file.open(fileName, ios::in | binary);
00024                 if (!m_file)
00025                         throw OpenErr(fileName);
00026                 m_stream = &m_file;
00027         }
00028         else
00029         {
00030                 m_stream = NULL;
00031                 parameters.GetValue("InputStreamPointer", m_stream);
00032         }
00033         m_waiting = false;
00034 }
00035 
00036 unsigned long FileStore::MaxRetrievable() const
00037 {
00038         if (!m_stream)
00039                 return 0;
00040 
00041         streampos current = m_stream->tellg();
00042         streampos end = m_stream->seekg(0, ios::end).tellg();
00043         m_stream->seekg(current);
00044         return end-current;
00045 }
00046 
00047 unsigned int FileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
00048 {
00049         if (!m_stream)
00050         {
00051                 transferBytes = 0;
00052                 return 0;
00053         }
00054 
00055         unsigned long size=transferBytes;
00056         transferBytes = 0;
00057 
00058         if (m_waiting)
00059                 goto output;
00060 
00061         while (size && m_stream->good())
00062         {
00063                 {
00064                 unsigned int spaceSize = 1024;
00065                 m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize);
00066 
00067                 m_stream->read((char *)m_space, STDMIN(size, (unsigned long)spaceSize));
00068                 }
00069                 m_len = m_stream->gcount();
00070                 unsigned int blockedBytes;
00071 output:
00072                 blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
00073                 m_waiting = blockedBytes > 0;
00074                 if (m_waiting)
00075                         return blockedBytes;
00076                 size -= m_len;
00077                 transferBytes += m_len;
00078         }
00079 
00080         if (!m_stream->good() && !m_stream->eof())
00081                 throw ReadErr();
00082 
00083         return 0;
00084 }
00085 
00086 unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
00087 {
00088         if (!m_stream)
00089                 return 0;
00090 
00091         if (begin == 0 && end == 1)
00092         {
00093                 int result = m_stream->peek();
00094                 if (result == EOF)      // GCC workaround: 2.95.2 doesn't have char_traits<char>::eof()
00095                         return 0;
00096                 else
00097                 {
00098                         unsigned int blockedBytes = target.ChannelPut(channel, byte(result), blocking);
00099                         begin += 1-blockedBytes;
00100                         return blockedBytes;
00101                 }
00102         }
00103 
00104         // TODO: figure out what happens on cin
00105         streampos current = m_stream->tellg();
00106         streampos endPosition = m_stream->seekg(0, ios::end).tellg();
00107         streampos newPosition = current + (streamoff)begin;
00108 
00109         if (newPosition >= endPosition)
00110         {
00111                 m_stream->seekg(current);
00112                 return 0;       // don't try to seek beyond the end of file
00113         }
00114         m_stream->seekg(newPosition);
00115         unsigned long total = 0;
00116         try
00117         {
00118                 assert(!m_waiting);
00119                 unsigned long copyMax = end-begin;
00120                 unsigned int blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
00121                 begin += copyMax;
00122                 if (blockedBytes)
00123                 {
00124                         const_cast<FileStore *>(this)->m_waiting = false;
00125                         return blockedBytes;
00126                 }
00127         }
00128         catch(...)
00129         {
00130                 m_stream->clear();
00131                 m_stream->seekg(current);
00132                 throw;
00133         }
00134         m_stream->clear();
00135         m_stream->seekg(current);
00136 
00137         return 0;
00138 }
00139 
00140 void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
00141 {
00142         const char *fileName;
00143         if (parameters.GetValue("OutputFileName", fileName))
00144         {
00145                 ios::openmode binary = parameters.GetValueWithDefault("OutputBinaryMode", true) ? ios::binary : ios::openmode(0);
00146                 m_file.open(fileName, ios::out | ios::trunc | binary);
00147                 if (!m_file)
00148                         throw OpenErr(fileName);
00149                 m_stream = &m_file;
00150         }
00151         else
00152         {
00153                 m_stream = NULL;
00154                 parameters.GetValue("OutputStreamPointer", m_stream);
00155         }
00156 }
00157 
00158 bool FileSink::IsolatedFlush(bool hardFlush, bool blocking)
00159 {
00160         if (!m_stream)
00161                 throw Err("FileSink: output stream not opened");
00162 
00163         m_stream->flush();
00164         if (!m_stream->good())
00165                 throw WriteErr();
00166 
00167         return false;
00168 }
00169 
00170 unsigned int FileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00171 {
00172         if (!m_stream)
00173                 throw Err("FileSink: output stream not opened");
00174 
00175         m_stream->write((const char *)inString, length);
00176 
00177         if (messageEnd)
00178                 m_stream->flush();
00179 
00180         if (!m_stream->good())
00181                 throw WriteErr();
00182 
00183         return 0;
00184 }
00185 
00186 NAMESPACE_END

Generated on Sun Mar 14 20:44:25 2004 for Crypto++ by doxygen 1.3.6-20040222