Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | 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 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 &parameters) 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) // GCC workaround: 2.95.2 doesn't have char_traits<char>::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 // TODO: figure out what happens on cin 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; // don't try to seek beyond the end of file 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 &parameters) 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

Generated on Wed Jul 21 19:15:24 2004 for Crypto++ by doxygen 1.3.7-20040704