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