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