00001
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 ¶meters)
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
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;
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 ¶meters)
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