diff --git a/coding/coding.pro b/coding/coding.pro index 6b615e55fd..4f93b1b8c7 100644 --- a/coding/coding.pro +++ b/coding/coding.pro @@ -11,6 +11,7 @@ include($$ROOT_DIR/common.pri) INCLUDEPATH += ../3party/tomcrypt/src/headers SOURCES += \ + internal/file_data.cpp \ hex.cpp \ file_reader.cpp \ file_writer.cpp \ diff --git a/coding/file_reader.cpp b/coding/file_reader.cpp index 4786cf7471..270d24f675 100644 --- a/coding/file_reader.cpp +++ b/coding/file_reader.cpp @@ -13,11 +13,13 @@ namespace { - class FileDataWithCachedSize : public FileData + class FileDataWithCachedSize : public my::FileData { + typedef my::FileData base_t; + public: explicit FileDataWithCachedSize(string const & fileName) - : FileData(fileName, FileData::OP_READ), m_Size(FileData::Size()) {} + : base_t(fileName, FileData::OP_READ), m_Size(FileData::Size()) {} uint64_t Size() const { return m_Size; } diff --git a/coding/file_writer.cpp b/coding/file_writer.cpp index 390dc9756f..bec2f10d4c 100644 --- a/coding/file_writer.cpp +++ b/coding/file_writer.cpp @@ -1,9 +1,6 @@ #include "file_writer.hpp" #include "internal/file_data.hpp" -#include "../std/cstdlib.hpp" -#include "../std/string.hpp" - #include "../../base/start_mem_debug.hpp" @@ -13,7 +10,7 @@ FileWriter::FileWriter(FileWriter const & rhs) : Writer(*this) } FileWriter::FileWriter(string const & fileName, FileWriter::Op op) - : m_pFileData(new FileData(fileName, static_cast(op))) + : m_pFileData(new fdata_t(fileName, static_cast(op))) { } @@ -42,26 +39,6 @@ string FileWriter::GetName() const return m_pFileData->GetName(); } -void FileWriter::DeleteFileX(string const & fileName) -{ -#ifdef OMIM_OS_BADA - Osp::Io::File::Remove(fileName.c_str()); -#else - - // Erase file. - if (0 != remove(fileName.c_str())) - { - // additional check if file really was removed correctly - FILE * f = fopen(fileName.c_str(), "r"); - if (f) - { - fclose(f); - LOG(LERROR, ("File exists but can't be deleted. Sharing violation?", fileName)); - } - } -#endif -} - uint64_t FileWriter::Size() const { return m_pFileData->Size(); @@ -71,3 +48,9 @@ void FileWriter::Flush() { m_pFileData->Flush(); } + +void FileWriter::DeleteFileX(string const & fName) +{ + my::DeleteFileX(fName); +} + diff --git a/coding/file_writer.hpp b/coding/file_writer.hpp index 7ddfb40572..0c1b9302b8 100644 --- a/coding/file_writer.hpp +++ b/coding/file_writer.hpp @@ -3,7 +3,7 @@ #include "../base/base.hpp" #include "../std/scoped_ptr.hpp" -class FileData; +namespace my { class FileData; } // FileWriter, not thread safe. class FileWriter : public Writer @@ -36,10 +36,11 @@ public: uint64_t Size() const; void Flush(); + static void DeleteFileX(string const & fName); + string GetName() const; - static void DeleteFileX(string const & fileName); - private: - scoped_ptr m_pFileData; + typedef my::FileData fdata_t; + scoped_ptr m_pFileData; }; diff --git a/coding/internal/file_data.cpp b/coding/internal/file_data.cpp new file mode 100644 index 0000000000..da7a2d4bad --- /dev/null +++ b/coding/internal/file_data.cpp @@ -0,0 +1,196 @@ +#include "file_data.hpp" + +#include "../reader.hpp" // For Reader exceptions. +#include "../writer.hpp" // For Writer exceptions. + +#include "../../base/exception.hpp" +#include "../../base/logging.hpp" + +#include "../../base/start_mem_debug.hpp" + + +namespace my { + +FileData::FileData(string const & fileName, Op op) + : m_FileName(fileName), m_Op(op) +{ + char const * const modes [] = {"rb", "wb", "r+b", "ab"}; +#ifdef OMIM_OS_BADA + result error = m_File.Construct(fileName.c_str(), modes[op]); + if (error == E_SUCCESS) + return; +#else + m_File = fopen(fileName.c_str(), modes[op]); + int error = m_File ? ferror(m_File) : 0; + if (m_File && !error) + return; + if (op == OP_WRITE_EXISTING) + { + // Special case, since "r+b" fails if file doesn't exist. + if (m_File) + fclose(m_File); + m_File = fopen(fileName.c_str(), "wb"); + error = m_File ? ferror(m_File) : 0; + } + if (m_File && !error) + return; +#endif + // if we're here - something bad is happened + if (m_Op) + MYTHROW(Writer::OpenException, (fileName, error)); + else + MYTHROW(Reader::OpenException, (fileName, error)); +} + +FileData::~FileData() +{ +#ifndef OMIM_OS_BADA + if (int error = fclose(m_File)) + { + LOG(LWARNING, ("Error closing file", m_FileName, m_Op, error)); + } +#endif +} + +uint64_t FileData::Size() const +{ +#ifdef OMIM_OS_BADA + Osp::Io::FileAttributes attr; + result error = Osp::Io::File::GetAttributes(m_FileName.c_str(), attr); + if (IsFailed(error)) + MYTHROW(Reader::OpenException, (m_FileName, m_Op, error)); + return attr.GetFileSize(); +#else + uint64_t const pos = Pos(); + fseek64(m_File, 0, SEEK_END); + if (int error = ferror(m_File)) + MYTHROW(Reader::OpenException, (m_FileName, m_Op, error)); + uint64_t size = ftell64(m_File); + if (int error = ferror(m_File)) + MYTHROW(Reader::OpenException, (m_FileName, m_Op, error)); + fseek64(m_File, pos, SEEK_SET); + if (int error = ferror(m_File)) + MYTHROW(Writer::SeekException, (m_FileName, m_Op, error, pos)); + return size; +#endif +} + +void FileData::Read(uint64_t pos, void * p, size_t size) +{ +#ifdef OMIM_OS_BADA + result error = m_File.Seek(Osp::Io::FILESEEKPOSITION_BEGIN, pos); + if (IsFailed(error)) + MYTHROW(Reader::ReadException, (error, pos)); + int bytesRead = m_File.Read(p, size); + error = GetLastResult(); + if (static_cast(bytesRead) != size || IsFailed(error)) + MYTHROW(Reader::ReadException, (m_FileName, m_Op, error, bytesRead, pos, size)); +#else + fseek64(m_File, pos, SEEK_SET); + if (int error = ferror(m_File)) + MYTHROW(Reader::ReadException, (error, pos)); + size_t bytesRead = fread(p, 1, size, m_File); + int error = ferror(m_File); + if (bytesRead != size || error) + MYTHROW(Reader::ReadException, (m_FileName, m_Op, error, bytesRead, pos, size)); +#endif +} + +uint64_t FileData::Pos() const +{ +#ifdef OMIM_OS_BADA + int pos = m_File.Tell(); + result error = GetLastResult(); + if (IsFailed(error)) + MYTHROW(Writer::PosException, (m_FileName, m_Op, error, pos)); + return pos; +#else + uint64_t result = ftell64(m_File); + if (int error = ferror(m_File)) + MYTHROW(Writer::PosException, (m_FileName, m_Op, error, result)); + return result; +#endif +} + +void FileData::Seek(uint64_t pos) +{ + ASSERT_NOT_EQUAL(m_Op, OP_APPEND, (m_FileName, m_Op, pos)); +#ifdef OMIM_OS_BADA + result error = m_File.Seek(Osp::Io::FILESEEKPOSITION_BEGIN, pos); + if (IsFailed(error)) + MYTHROW(Writer::SeekException, (m_FileName, m_Op, error, pos)); +#else + fseek64(m_File, pos, SEEK_SET); + if (int error = ferror(m_File)) + MYTHROW(Writer::SeekException, (m_FileName, m_Op, error, pos)); +#endif +} + +void FileData::Write(void const * p, size_t size) +{ +#ifdef OMIM_OS_BADA + result error = m_File.Write(p, size); + if (IsFailed(error)) + MYTHROW(Writer::WriteException, (m_FileName, m_Op, error, size)); +#else + size_t bytesWritten = fwrite(p, 1, size, m_File); + int error = ferror(m_File); + if (bytesWritten != size || error) + MYTHROW(Writer::WriteException, (m_FileName, m_Op, error, bytesWritten, size)); +#endif +} + +void FileData::Flush() +{ +#ifdef OMIM_OS_BADA + result error = m_File.Flush(); + if (IsFailed(error)) + MYTHROW(Writer::WriteException, (m_FileName, m_Op, error)); +#else + fflush(m_File); + if (int error = ferror(m_File)) + MYTHROW(Writer::WriteException, (m_FileName, m_Op, error)); +#endif +} + +bool GetFileSize(string const & fName, uint64_t & sz) +{ + try + { + typedef my::FileData fdata_t; + fdata_t f(fName, fdata_t::OP_READ); + sz = f.Size(); + return true; + } + catch (Writer::SeekException const &) + { + return false; + } + catch (Reader::OpenException const &) + { + return false; + } +} + + +void DeleteFileX(string const & fName) +{ +#ifdef OMIM_OS_BADA + Osp::Io::File::Remove(fName.c_str()); +#else + + // Erase file. + if (0 != remove(fName.c_str())) + { + // additional check if file really was removed correctly + FILE * f = fopen(fName.c_str(), "r"); + if (f) + { + fclose(f); + LOG(LERROR, ("File exists but can't be deleted. Sharing violation?", fName)); + } + } +#endif +} + +} diff --git a/coding/internal/file_data.hpp b/coding/internal/file_data.hpp index 3930a7780e..7da8fe210c 100644 --- a/coding/internal/file_data.hpp +++ b/coding/internal/file_data.hpp @@ -1,161 +1,33 @@ #pragma once #include "file64_api.hpp" -#include "../reader.hpp" // For Reader exceptions. -#include "../writer.hpp" // For Writer exceptions. + #include "../../base/base.hpp" -#include "../../base/exception.hpp" -#include "../../base/logging.hpp" + #include "../../std/string.hpp" #ifdef OMIM_OS_BADA #include #endif + +namespace my { + class FileData { public: enum Op { OP_READ = 0, OP_WRITE_TRUNCATE = 1, OP_WRITE_EXISTING = 2, OP_APPEND}; - FileData(string const & fileName, Op op) : m_FileName(fileName), m_Op(op) - { - char const * const modes [] = {"rb", "wb", "r+b", "ab"}; -#ifdef OMIM_OS_BADA - result error = m_File.Construct(fileName.c_str(), modes[op]); - if (error == E_SUCCESS) - return; -#else - m_File = fopen(fileName.c_str(), modes[op]); - int error = m_File ? ferror(m_File) : 0; - if (m_File && !error) - return; - if (op == OP_WRITE_EXISTING) - { - // Special case, since "r+b" fails if file doesn't exist. - if (m_File) - fclose(m_File); - m_File = fopen(fileName.c_str(), "wb"); - error = m_File ? ferror(m_File) : 0; - } - if (m_File && !error) - return; -#endif - // if we're here - something bad is happened - if (m_Op) - MYTHROW(Writer::OpenException, (fileName, error)); - else - MYTHROW(Reader::OpenException, (fileName, error)); - } + FileData(string const & fileName, Op op); + ~FileData(); - ~FileData() - { -#ifndef OMIM_OS_BADA - if (int error = fclose(m_File)) - { - LOG(LWARNING, ("Error closing file", m_FileName, m_Op, error)); - } -#endif - } + uint64_t Size() const; + uint64_t Pos() const; - uint64_t Size() const - { -#ifdef OMIM_OS_BADA - Osp::Io::FileAttributes attr; - result error = Osp::Io::File::GetAttributes(m_FileName.c_str(), attr); - if (IsFailed(error)) - MYTHROW(Reader::OpenException, (m_FileName, m_Op, error)); - return attr.GetFileSize(); -#else - uint64_t const pos = Pos(); - fseek64(m_File, 0, SEEK_END); - if (int error = ferror(m_File)) - MYTHROW(Reader::OpenException, (m_FileName, m_Op, error)); - uint64_t size = ftell64(m_File); - if (int error = ferror(m_File)) - MYTHROW(Reader::OpenException, (m_FileName, m_Op, error)); - fseek64(m_File, pos, SEEK_SET); - if (int error = ferror(m_File)) - MYTHROW(Writer::SeekException, (m_FileName, m_Op, error, pos)); - return size; -#endif - } + void Seek(uint64_t pos); - void Read(uint64_t pos, void * p, size_t size) - { -#ifdef OMIM_OS_BADA - result error = m_File.Seek(Osp::Io::FILESEEKPOSITION_BEGIN, pos); - if (IsFailed(error)) - MYTHROW(Reader::ReadException, (error, pos)); - int bytesRead = m_File.Read(p, size); - error = GetLastResult(); - if (static_cast(bytesRead) != size || IsFailed(error)) - MYTHROW(Reader::ReadException, (m_FileName, m_Op, error, bytesRead, pos, size)); -#else - fseek64(m_File, pos, SEEK_SET); - if (int error = ferror(m_File)) - MYTHROW(Reader::ReadException, (error, pos)); - size_t bytesRead = fread(p, 1, size, m_File); - int error = ferror(m_File); - if (bytesRead != size || error) - MYTHROW(Reader::ReadException, (m_FileName, m_Op, error, bytesRead, pos, size)); -#endif - } - - uint64_t Pos() const - { -#ifdef OMIM_OS_BADA - int pos = m_File.Tell(); - result error = GetLastResult(); - if (IsFailed(error)) - MYTHROW(Writer::PosException, (m_FileName, m_Op, error, pos)); - return pos; -#else - uint64_t result = ftell64(m_File); - if (int error = ferror(m_File)) - MYTHROW(Writer::PosException, (m_FileName, m_Op, error, result)); - return result; -#endif - } - - void Seek(uint64_t pos) - { - ASSERT_NOT_EQUAL(m_Op, OP_APPEND, (m_FileName, m_Op, pos)); -#ifdef OMIM_OS_BADA - result error = m_File.Seek(Osp::Io::FILESEEKPOSITION_BEGIN, pos); - if (IsFailed(error)) - MYTHROW(Writer::SeekException, (m_FileName, m_Op, error, pos)); -#else - fseek64(m_File, pos, SEEK_SET); - if (int error = ferror(m_File)) - MYTHROW(Writer::SeekException, (m_FileName, m_Op, error, pos)); -#endif - } - - void Write(void const * p, size_t size) - { -#ifdef OMIM_OS_BADA - result error = m_File.Write(p, size); - if (IsFailed(error)) - MYTHROW(Writer::WriteException, (m_FileName, m_Op, error, size)); -#else - size_t bytesWritten = fwrite(p, 1, size, m_File); - int error = ferror(m_File); - if (bytesWritten != size || error) - MYTHROW(Writer::WriteException, (m_FileName, m_Op, error, bytesWritten, size)); -#endif - } - - void Flush() - { -#ifdef OMIM_OS_BADA - result error = m_File.Flush(); - if (IsFailed(error)) - MYTHROW(Writer::WriteException, (m_FileName, m_Op, error)); -#else - fflush(m_File); - if (int error = ferror(m_File)) - MYTHROW(Writer::WriteException, (m_FileName, m_Op, error)); -#endif - } + void Read(uint64_t pos, void * p, size_t size); + void Write(void const * p, size_t size); + void Flush(); string GetName() const { return m_FileName; } @@ -169,3 +41,8 @@ private: string m_FileName; Op m_Op; }; + +bool GetFileSize(string const & fName, uint64_t & sz); +void DeleteFileX(string const & fName); + +}