00001
00002
00003 #include "pch.h"
00004 #include "files.h"
00005
00006 NAMESPACE_BEGIN(CryptoPP)
00007
00008 using namespace std;
00009
00010 void Files_TestInstantiations()
00011 {
00012 FileStore f0;
00013 FileSource f1;
00014 FileSink f2;
00015 }
00016
00017 void FileStore::StoreInitialize(const NameValuePairs ¶meters)
00018 {
00019 const char *fileName;
00020 if (parameters.GetValue("InputFileName", fileName))
00021 {
00022 ios::openmode binary = parameters.GetValueWithDefault("InputBinaryMode", true) ? ios::binary : ios::openmode(0);
00023 m_file.open(fileName, ios::in | binary);
00024 if (!m_file)
00025 throw OpenErr(fileName);
00026 m_stream = &m_file;
00027 }
00028 else
00029 {
00030 m_stream = NULL;
00031 parameters.GetValue("InputStreamPointer", m_stream);
00032 }
00033 m_waiting = false;
00034 }
00035
00036 unsigned long FileStore::MaxRetrievable() const
00037 {
00038 if (!m_stream)
00039 return 0;
00040
00041 streampos current = m_stream->tellg();
00042 streampos end = m_stream->seekg(0, ios::end).tellg();
00043 m_stream->seekg(current);
00044 return end-current;
00045 }
00046
00047 unsigned int FileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking)
00048 {
00049 if (!m_stream)
00050 {
00051 transferBytes = 0;
00052 return 0;
00053 }
00054
00055 unsigned long size=transferBytes;
00056 transferBytes = 0;
00057
00058 if (m_waiting)
00059 goto output;
00060
00061 while (size && m_stream->good())
00062 {
00063 {
00064 unsigned int spaceSize = 1024;
00065 m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize);
00066
00067 m_stream->read((char *)m_space, STDMIN(size, (unsigned long)spaceSize));
00068 }
00069 m_len = m_stream->gcount();
00070 unsigned int blockedBytes;
00071 output:
00072 blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
00073 m_waiting = blockedBytes > 0;
00074 if (m_waiting)
00075 return blockedBytes;
00076 size -= m_len;
00077 transferBytes += m_len;
00078 }
00079
00080 if (!m_stream->good() && !m_stream->eof())
00081 throw ReadErr();
00082
00083 return 0;
00084 }
00085
00086 unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const
00087 {
00088 if (!m_stream)
00089 return 0;
00090
00091 if (begin == 0 && end == 1)
00092 {
00093 int result = m_stream->peek();
00094 if (result == EOF)
00095 return 0;
00096 else
00097 {
00098 unsigned int blockedBytes = target.ChannelPut(channel, byte(result), blocking);
00099 begin += 1-blockedBytes;
00100 return blockedBytes;
00101 }
00102 }
00103
00104
00105 streampos current = m_stream->tellg();
00106 streampos endPosition = m_stream->seekg(0, ios::end).tellg();
00107 streampos newPosition = current + (streamoff)begin;
00108
00109 if (newPosition >= endPosition)
00110 {
00111 m_stream->seekg(current);
00112 return 0;
00113 }
00114 m_stream->seekg(newPosition);
00115 unsigned long total = 0;
00116 try
00117 {
00118 assert(!m_waiting);
00119 unsigned long copyMax = end-begin;
00120 unsigned int blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
00121 begin += copyMax;
00122 if (blockedBytes)
00123 {
00124 const_cast<FileStore *>(this)->m_waiting = false;
00125 return blockedBytes;
00126 }
00127 }
00128 catch(...)
00129 {
00130 m_stream->clear();
00131 m_stream->seekg(current);
00132 throw;
00133 }
00134 m_stream->clear();
00135 m_stream->seekg(current);
00136
00137 return 0;
00138 }
00139
00140 void FileSink::IsolatedInitialize(const NameValuePairs ¶meters)
00141 {
00142 const char *fileName;
00143 if (parameters.GetValue("OutputFileName", fileName))
00144 {
00145 ios::openmode binary = parameters.GetValueWithDefault("OutputBinaryMode", true) ? ios::binary : ios::openmode(0);
00146 m_file.open(fileName, ios::out | ios::trunc | binary);
00147 if (!m_file)
00148 throw OpenErr(fileName);
00149 m_stream = &m_file;
00150 }
00151 else
00152 {
00153 m_stream = NULL;
00154 parameters.GetValue("OutputStreamPointer", m_stream);
00155 }
00156 }
00157
00158 bool FileSink::IsolatedFlush(bool hardFlush, bool blocking)
00159 {
00160 if (!m_stream)
00161 throw Err("FileSink: output stream not opened");
00162
00163 m_stream->flush();
00164 if (!m_stream->good())
00165 throw WriteErr();
00166
00167 return false;
00168 }
00169
00170 unsigned int FileSink::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking)
00171 {
00172 if (!m_stream)
00173 throw Err("FileSink: output stream not opened");
00174
00175 m_stream->write((const char *)inString, length);
00176
00177 if (messageEnd)
00178 m_stream->flush();
00179
00180 if (!m_stream->good())
00181 throw WriteErr();
00182
00183 return 0;
00184 }
00185
00186 NAMESPACE_END