- Main Page
- Namespaces
- Classes
- Files

- File List
- 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 #include <limits>
    00010
    00011 NAMESPACE_BEGIN(CryptoPP)
    00012
    00013 using namespace std;
    00014
    00015 void Files_TestInstantiations()
    00016 {
    00017         FileStore f0;
    00018         FileSource f1;
    00019         FileSink f2;
    00020 }
    00021
    00022 void FileStore::StoreInitialize(const NameValuePairs &parameters)
    00023 {
    00024         m_file.reset(new std::ifstream);
    00025         const char *fileName;
    00026         if (parameters.GetValue(Name::InputFileName(), fileName))
    00027         {
    00028                 ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0);
    00029                 m_file->open(fileName, ios::in | binary);
    00030                 if (!*m_file)
    00031                         throw OpenErr(fileName);
    00032                 m_stream = m_file.get();
    00033         }
    00034         else
    00035         {
    00036                 m_stream = NULL;
    00037                 parameters.GetValue(Name::InputStreamPointer(), m_stream);
    00038         }
    00039         m_waiting = false;
    00040 }
    00041
    00042 lword FileStore::MaxRetrievable() const
    00043 {
    00044         if (!m_stream)
    00045                 return 0;
    00046
    00047         streampos current = m_stream->tellg();
    00048         streampos end = m_stream->seekg(0, ios::end).tellg();
    00049         m_stream->seekg(current);
    00050         return end-current;
    00051 }
    00052
    00053 size_t FileStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
    00054 {
    00055         if (!m_stream)
    00056         {
    00057                 transferBytes = 0;
    00058                 return 0;
    00059         }
    00060
    00061         lword size=transferBytes;
    00062         transferBytes = 0;
    00063
    00064         if (m_waiting)
    00065                 goto output;
    00066
    00067         while (size && m_stream->good())
    00068         {
    00069                 {
    00070                 size_t spaceSize = 1024;
    00071                 m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(0)-1, size), spaceSize);
    00072
    00073                 m_stream->read((char *)m_space, (unsigned int)STDMIN(size, (lword)spaceSize));
    00074                 }
    00075                 m_len = m_stream->gcount();
    00076                 size_t blockedBytes;
    00077 output:
    00078                 blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
    00079                 m_waiting = blockedBytes > 0;
    00080                 if (m_waiting)
    00081                         return blockedBytes;
    00082                 size -= m_len;
    00083                 transferBytes += m_len;
    00084         }
    00085
    00086         if (!m_stream->good() && !m_stream->eof())
    00087                 throw ReadErr();
    00088
    00089         return 0;
    00090 }
    00091
    00092 size_t FileStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
    00093 {
    00094         if (!m_stream)
    00095                 return 0;
    00096
    00097         if (begin == 0 && end == 1)
    00098         {
    00099                 int result = m_stream->peek();
    00100                 if (result == char_traits<char>::eof())
    00101                         return 0;
    00102                 else
    00103                 {
    00104                         size_t blockedBytes = target.ChannelPut(channel, byte(result), blocking);
    00105                         begin += 1-blockedBytes;
    00106                         return blockedBytes;
    00107                 }
    00108         }
    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         lword total = 0;
    00122         try
    00123         {
    00124                 assert(!m_waiting);
    00125                 lword copyMax = end-begin;
    00126                 size_t 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 lword FileStore::Skip(lword skipMax)
    00147 {
    00148         lword oldPos = m_stream->tellg();
    00149         std::istream::off_type offset;
    00150         if (!SafeConvert(skipMax, offset))
    00151                 throw InvalidArgument("FileStore: maximum seek offset exceeded");
    00152         m_stream->seekg(offset, ios::cur);
    00153         return (lword)m_stream->tellg() - oldPos;
    00154 }
    00155
    00156 void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
    00157 {
    00158         m_file.reset(new std::ofstream);
    00159         const char *fileName;
    00160         if (parameters.GetValue(Name::OutputFileName(), fileName))
    00161         {
    00162                 ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0);
    00163                 m_file->open(fileName, ios::out | ios::trunc | binary);
    00164                 if (!*m_file)
    00165                         throw OpenErr(fileName);
    00166                 m_stream = m_file.get();
    00167         }
    00168         else
    00169         {
    00170                 m_stream = NULL;
    00171                 parameters.GetValue(Name::OutputStreamPointer(), m_stream);
    00172         }
    00173 }
    00174
    00175 bool FileSink::IsolatedFlush(bool hardFlush, bool blocking)
    00176 {
    00177         if (!m_stream)
    00178                 throw Err("FileSink: output stream not opened");
    00179
    00180         m_stream->flush();
    00181         if (!m_stream->good())
    00182                 throw WriteErr();
    00183
    00184         return false;
    00185 }
    00186
    00187 size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
    00188 {
    00189         if (!m_stream)
    00190                 throw Err("FileSink: output stream not opened");
    00191
    00192         while (length > 0)
    00193         {
    00194                 std::streamsize size;
    00195                 if (!SafeConvert(length, size))
    00196                         size = numeric_limits<std::streamsize>::max();
    00197                 m_stream->write((const char *)inString, size);
    00198                 inString += size;
    00199                 length -= size;
    00200         }
    00201
    00202         if (messageEnd)
    00203                 m_stream->flush();
    00204
    00205         if (!m_stream->good())
    00206                 throw WriteErr();
    00207
    00208         return 0;
    00209 }
    00210
    00211 NAMESPACE_END
    00212
    00213 #endif