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 
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

Generated on Tue Aug 16 08:38:41 2005 for Crypto++ by  doxygen 1.3.9.1