• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • 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 #include <limits>
00010 
00011 NAMESPACE_BEGIN(CryptoPP)
00012 
00013 using namespace std;
00014 
00015 #ifndef NDEBUG
00016 void Files_TestInstantiations()
00017 {
00018         FileStore f0;
00019         FileSource f1;
00020         FileSink f2;
00021 }
00022 #endif
00023 
00024 void FileStore::StoreInitialize(const NameValuePairs &parameters)
00025 {
00026         m_waiting = false;
00027         m_stream = NULL;
00028         m_file.release();
00029 
00030         const char *fileName = NULL;
00031 #if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400
00032         const wchar_t *fileNameWide = NULL;
00033         if (!parameters.GetValue(Name::InputFileNameWide(), fileNameWide))
00034 #endif
00035                 if (!parameters.GetValue(Name::InputFileName(), fileName))
00036                 {
00037                         parameters.GetValue(Name::InputStreamPointer(), m_stream);
00038                         return;
00039                 }
00040 
00041         ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0);
00042         m_file.reset(new std::ifstream);
00043 #ifdef CRYPTOPP_UNIX_AVAILABLE
00044         std::string narrowed;
00045         if (fileNameWide)
00046                 fileName = (narrowed = StringNarrow(fileNameWide)).c_str();
00047 #endif
00048 #if _MSC_VER >= 1400
00049         if (fileNameWide)
00050         {
00051                 m_file->open(fileNameWide, ios::in | binary);
00052                 if (!*m_file)
00053                         throw OpenErr(StringNarrow(fileNameWide, false));
00054         }
00055 #endif
00056         if (fileName)
00057         {
00058                 m_file->open(fileName, ios::in | binary);
00059                 if (!*m_file)
00060                         throw OpenErr(fileName);
00061         }
00062         m_stream = m_file.get();
00063 }
00064 
00065 lword FileStore::MaxRetrievable() const
00066 {
00067         if (!m_stream)
00068                 return 0;
00069 
00070         streampos current = m_stream->tellg();
00071         streampos end = m_stream->seekg(0, ios::end).tellg();
00072         m_stream->seekg(current);
00073         return end-current;
00074 }
00075 
00076 size_t FileStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
00077 {
00078         if (!m_stream)
00079         {
00080                 transferBytes = 0;
00081                 return 0;
00082         }
00083 
00084         lword size=transferBytes;
00085         transferBytes = 0;
00086 
00087         if (m_waiting)
00088                 goto output;
00089 
00090         while (size && m_stream->good())
00091         {
00092                 {
00093                 size_t spaceSize = 1024;
00094                 m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(0)-1, size), spaceSize);
00095 
00096                 m_stream->read((char *)m_space, (unsigned int)STDMIN(size, (lword)spaceSize));
00097                 }
00098                 m_len = (size_t)m_stream->gcount();
00099                 size_t blockedBytes;
00100 output:
00101                 blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking);
00102                 m_waiting = blockedBytes > 0;
00103                 if (m_waiting)
00104                         return blockedBytes;
00105                 size -= m_len;
00106                 transferBytes += m_len;
00107         }
00108 
00109         if (!m_stream->good() && !m_stream->eof())
00110                 throw ReadErr();
00111 
00112         return 0;
00113 }
00114 
00115 size_t FileStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
00116 {
00117         if (!m_stream)
00118                 return 0;
00119 
00120         if (begin == 0 && end == 1)
00121         {
00122                 int result = m_stream->peek();
00123                 if (result == char_traits<char>::eof())
00124                         return 0;
00125                 else
00126                 {
00127                         size_t blockedBytes = target.ChannelPut(channel, byte(result), blocking);
00128                         begin += 1-blockedBytes;
00129                         return blockedBytes;
00130                 }
00131         }
00132 
00133         // TODO: figure out what happens on cin
00134         streampos current = m_stream->tellg();
00135         streampos endPosition = m_stream->seekg(0, ios::end).tellg();
00136         streampos newPosition = current + (streamoff)begin;
00137 
00138         if (newPosition >= endPosition)
00139         {
00140                 m_stream->seekg(current);
00141                 return 0;       // don't try to seek beyond the end of file
00142         }
00143         m_stream->seekg(newPosition);
00144         try
00145         {
00146                 assert(!m_waiting);
00147                 lword copyMax = end-begin;
00148                 size_t blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking);
00149                 begin += copyMax;
00150                 if (blockedBytes)
00151                 {
00152                         const_cast<FileStore *>(this)->m_waiting = false;
00153                         return blockedBytes;
00154                 }
00155         }
00156         catch(...)
00157         {
00158                 m_stream->clear();
00159                 m_stream->seekg(current);
00160                 throw;
00161         }
00162         m_stream->clear();
00163         m_stream->seekg(current);
00164 
00165         return 0;
00166 }
00167 
00168 lword FileStore::Skip(lword skipMax)
00169 {
00170         if (!m_stream)
00171                 return 0;
00172 
00173         lword oldPos = m_stream->tellg();
00174         std::istream::off_type offset;
00175         if (!SafeConvert(skipMax, offset))
00176                 throw InvalidArgument("FileStore: maximum seek offset exceeded");
00177         m_stream->seekg(offset, ios::cur);
00178         return (lword)m_stream->tellg() - oldPos;
00179 }
00180 
00181 void FileSink::IsolatedInitialize(const NameValuePairs &parameters)
00182 {
00183         m_stream = NULL;
00184         m_file.release();
00185 
00186         const char *fileName = NULL;
00187 #if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400
00188         const wchar_t *fileNameWide = NULL;
00189         if (!parameters.GetValue(Name::OutputFileNameWide(), fileNameWide))
00190 #endif
00191                 if (!parameters.GetValue(Name::OutputFileName(), fileName))
00192                 {
00193                         parameters.GetValue(Name::OutputStreamPointer(), m_stream);
00194                         return;
00195                 }
00196 
00197         ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0);
00198         m_file.reset(new std::ofstream);
00199 #ifdef CRYPTOPP_UNIX_AVAILABLE
00200         std::string narrowed;
00201         if (fileNameWide)
00202                 fileName = (narrowed = StringNarrow(fileNameWide)).c_str();
00203 #endif
00204 #if _MSC_VER >= 1400
00205         if (fileNameWide)
00206         {
00207                 m_file->open(fileNameWide, ios::out | ios::trunc | binary);
00208                 if (!*m_file)
00209                         throw OpenErr(StringNarrow(fileNameWide, false));
00210         }
00211 #endif
00212         if (fileName)
00213         {
00214                 m_file->open(fileName, ios::out | ios::trunc | binary);
00215                 if (!*m_file)
00216                         throw OpenErr(fileName);
00217         }
00218         m_stream = m_file.get();
00219 }
00220 
00221 bool FileSink::IsolatedFlush(bool hardFlush, bool blocking)
00222 {
00223         if (!m_stream)
00224                 throw Err("FileSink: output stream not opened");
00225 
00226         m_stream->flush();
00227         if (!m_stream->good())
00228                 throw WriteErr();
00229 
00230         return false;
00231 }
00232 
00233 size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00234 {
00235         if (!m_stream)
00236                 throw Err("FileSink: output stream not opened");
00237 
00238         while (length > 0)
00239         {
00240                 std::streamsize size;
00241                 if (!SafeConvert(length, size))
00242                         size = numeric_limits<std::streamsize>::max();
00243                 m_stream->write((const char *)inString, size);
00244                 inString += size;
00245                 length -= (size_t)size;
00246         }
00247 
00248         if (messageEnd)
00249                 m_stream->flush();
00250 
00251         if (!m_stream->good())
00252                 throw WriteErr();
00253 
00254         return 0;
00255 }
00256 
00257 NAMESPACE_END
00258 
00259 #endif

Generated on Mon Aug 9 2010 15:56:34 for Crypto++ by  doxygen 1.7.1