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         try
00120         {
00121                 assert(!m_waiting);
00122                 unsigned long copyMax = end-begin;
00123                 unsigned int blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
00124                 begin += copyMax;
00125                 if (blockedBytes)
00126                 {
00127                         const_cast<FileStore *>(this)->m_waiting = false;
00128                         return blockedBytes;
00129                 }
00130         }
00131         catch(...)
00132         {
00133                 m_stream->clear();
00134                 m_stream->seekg(current);
00135                 throw;
00136         }
00137         m_stream->clear();
00138         m_stream->seekg(current);
00139 
00140         return 0;
00141 }
00142 
00143 unsigned long FileStore::Skip(unsigned long skipMax)
00144 {
00145         unsigned long oldPos = m_stream->tellg();
00146         m_stream->seekg(skipMax, ios::cur);
00147         return (unsigned long)m_stream->tellg() - oldPos;
00148 }
00149 
00150 void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
00151 {
00152         m_file.reset(new std::ofstream);
00153         const char *fileName;
00154         if (parameters.GetValue(Name::OutputFileName(), fileName))
00155         {
00156                 ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0);
00157                 m_file->open(fileName, ios::out | ios::trunc | binary);
00158                 if (!*m_file)
00159                         throw OpenErr(fileName);
00160                 m_stream = m_file.get();
00161         }
00162         else
00163         {
00164                 m_stream = NULL;
00165                 parameters.GetValue(Name::OutputStreamPointer(), m_stream);
00166         }
00167 }
00168 
00169 bool FileSink::IsolatedFlush(bool hardFlush, bool blocking)
00170 {
00171         if (!m_stream)
00172                 throw Err("FileSink: output stream not opened");
00173 
00174         m_stream->flush();
00175         if (!m_stream->good())
00176                 throw WriteErr();
00177 
00178         return false;
00179 }
00180 
00181 unsigned int FileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00182 {
00183         if (!m_stream)
00184                 throw Err("FileSink: output stream not opened");
00185 
00186         m_stream->write((const char *)inString, length);
00187 
00188         if (messageEnd)
00189                 m_stream->flush();
00190 
00191         if (!m_stream->good())
00192                 throw WriteErr();
00193 
00194         return 0;
00195 }
00196 
00197 NAMESPACE_END
00198 
00199 #endif

Generated on Thu Mar 30 22:11:42 2006 for Crypto++ by  doxygen 1.4.6