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