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