diff options
author | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2009-07-11 01:48:12 +0000 |
---|---|---|
committer | weidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0> | 2009-07-11 01:48:12 +0000 |
commit | 4b53fa6f2956ccf4b0cdb98adeceeaf66b67612b (patch) | |
tree | 4315ffeaf27d7ecbe96c9cf2bf595ecdfb748900 | |
parent | bef47e9f5658b05b600bd6b873687ab80d39dd2e (diff) | |
download | cryptopp-4b53fa6f2956ccf4b0cdb98adeceeaf66b67612b.tar.gz |
handle Unicode filenames
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@472 57ff6487-cd31-0410-9ec3-f628ee90f5f0
-rw-r--r-- | argnames.h | 2 | ||||
-rw-r--r-- | files.cpp | 73 | ||||
-rw-r--r-- | files.h | 17 | ||||
-rw-r--r-- | misc.h | 18 |
4 files changed, 99 insertions, 11 deletions
@@ -50,9 +50,11 @@ CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) //!< word32 CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) //!< ByteArrayParameter CRYPTOPP_DEFINE_NAME_STRING(InputFileName) //!< const char * +CRYPTOPP_DEFINE_NAME_STRING(InputFileNameWide) //!< const wchar_t * CRYPTOPP_DEFINE_NAME_STRING(InputStreamPointer) //!< std::istream * CRYPTOPP_DEFINE_NAME_STRING(InputBinaryMode) //!< bool CRYPTOPP_DEFINE_NAME_STRING(OutputFileName) //!< const char * +CRYPTOPP_DEFINE_NAME_STRING(OutputFileNameWide) //!< const wchar_t * CRYPTOPP_DEFINE_NAME_STRING(OutputStreamPointer) //!< std::ostream * CRYPTOPP_DEFINE_NAME_STRING(OutputBinaryMode) //!< bool CRYPTOPP_DEFINE_NAME_STRING(EncodingParameters) //!< ConstByteArrayParameter @@ -12,31 +12,58 @@ NAMESPACE_BEGIN(CryptoPP) using namespace std; +#ifndef NDEBUG void Files_TestInstantiations() { FileStore f0; FileSource f1; FileSink f2; } +#endif void FileStore::StoreInitialize(const NameValuePairs ¶meters) { - m_file.reset(new std::ifstream); + m_waiting = false; + m_stream = NULL; + m_file.release(); + const char *fileName; + const wchar_t *fileNameWide; +#ifdef CRYPTOPP_UNIX_AVAILABLE + std::string narrowed; +#endif + if (parameters.GetValue(Name::InputFileName(), fileName)) { +#ifdef CRYPTOPP_UNIX_AVAILABLE +narrowName: +#endif ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0); + m_file.reset(new std::ifstream); m_file->open(fileName, ios::in | binary); if (!*m_file) throw OpenErr(fileName); m_stream = m_file.get(); } - else +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + else if (parameters.GetValue(Name::InputFileNameWide(), fileNameWide)) { - m_stream = NULL; - parameters.GetValue(Name::InputStreamPointer(), m_stream); + #if _MSC_VER >= 1400 + ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0); + m_file.reset(new std::ifstream); + m_file->open(fileNameWide, ios::in | binary); + if (!*m_file) + throw OpenErr(StringNarrow(fileNameWide)); + m_stream = m_file.get(); + #else + narrowed = StringNarrow(fileNameWide); + fileName = narrowed.c_str(); + goto narrowName; + #endif } - m_waiting = false; +#endif + else + parameters.GetValue(Name::InputStreamPointer(), m_stream); } lword FileStore::MaxRetrievable() const @@ -144,6 +171,9 @@ size_t FileStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lwo lword FileStore::Skip(lword skipMax) { + if (!m_stream) + return 0; + lword oldPos = m_stream->tellg(); std::istream::off_type offset; if (!SafeConvert(skipMax, offset)) @@ -154,21 +184,46 @@ lword FileStore::Skip(lword skipMax) void FileSink::IsolatedInitialize(const NameValuePairs ¶meters) { - m_file.reset(new std::ofstream); + m_stream = NULL; + m_file.release(); + const char *fileName; + const wchar_t *fileNameWide; +#ifdef CRYPTOPP_UNIX_AVAILABLE + std::string narrowed; +#endif + if (parameters.GetValue(Name::OutputFileName(), fileName)) { +#ifdef CRYPTOPP_UNIX_AVAILABLE +narrowName: +#endif ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0); + m_file.reset(new std::ofstream); m_file->open(fileName, ios::out | ios::trunc | binary); if (!*m_file) throw OpenErr(fileName); m_stream = m_file.get(); } - else +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + else if (parameters.GetValue(Name::OutputFileNameWide(), fileNameWide)) { - m_stream = NULL; - parameters.GetValue(Name::OutputStreamPointer(), m_stream); + #if _MSC_VER >= 1400 + ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0); + m_file.reset(new std::ofstream); + m_file->open(fileNameWide, ios::out | ios::trunc | binary); + if (!*m_file) + throw OpenErr(StringNarrow(fileNameWide)); + m_stream = m_file.get(); + #else + narrowed = StringNarrow(fileNameWide); + fileName = narrowed.c_str(); + goto narrowName; + #endif } +#endif + else + parameters.GetValue(Name::OutputStreamPointer(), m_stream); } bool FileSink::IsolatedFlush(bool hardFlush, bool blocking) @@ -27,6 +27,11 @@ public: {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));} FileStore(const char *filename) {StoreInitialize(MakeParameters(Name::InputFileName(), filename));} +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + //! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called. + FileStore(const wchar_t *filename) + {StoreInitialize(MakeParameters(Name::InputFileNameWide(), filename));} +#endif std::istream* GetStream() {return m_stream;} @@ -59,6 +64,11 @@ public: : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputStreamPointer(), &in));} FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true) : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileName(), filename)(Name::InputBinaryMode(), binary));} +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + //! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called. + FileSource(const wchar_t *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true) + : SourceTemplate<FileStore>(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileNameWide(), filename)(Name::InputBinaryMode(), binary));} +#endif std::istream* GetStream() {return m_store.GetStream();} }; @@ -79,7 +89,12 @@ public: FileSink(std::ostream &out) {IsolatedInitialize(MakeParameters(Name::OutputStreamPointer(), &out));} FileSink(const char *filename, bool binary=true) - {IsolatedInitialize(MakeParameters(Name::OutputFileName(), filename)("OutputBinaryMode", binary));} + {IsolatedInitialize(MakeParameters(Name::OutputFileName(), filename)(Name::OutputBinaryMode(), binary));} +#if defined(CRYPTOPP_UNIX_AVAILABLE) || _MSC_VER >= 1400 + //! specify file with Unicode name. On non-Windows OS, this function assumes that setlocale() has been called. + FileSink(const wchar_t *filename, bool binary=true) + {IsolatedInitialize(MakeParameters(Name::OutputFileNameWide(), filename)(Name::OutputBinaryMode(), binary));} +#endif std::ostream* GetStream() {return m_stream;} @@ -122,7 +122,7 @@ template <class T, class F, int instance> const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const { static simple_ptr<T> s_pObject; - static char s_objectState = 0; + static volatile char s_objectState = 0; retry: switch (s_objectState) @@ -547,6 +547,22 @@ inline void SecureWipeArray(T *buf, size_t n) SecureWipeBuffer((byte *)buf, n * sizeof(T)); } +// this function uses wcstombs(), which assumes that setlocale() has been called +static std::string StringNarrow(const wchar_t *str) +{ +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4996) // 'wcstombs': This function or variable may be unsafe. +#endif + size_t size = wcstombs(NULL, str, 0); + std::string result(size, 0); + wcstombs(&result[0], str, size); + return result; +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + // ************** rotate functions *************** template <class T> inline T rotlFixed(T x, unsigned int y) |