-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


C++: API C

, 17 2017 . 17:20 +

C++ C. , .


C C++. , . , , . .


C - C++


. Tester-Driven Development.


, Tester-driven development — , , ,

++17. , -:


bool DocumentLoader::MakeDocumentWorkdirCopy()
{
    std::error_code errorCode;
    if (!std::filesystem::exists(m_filepath, errorCode) || errorCode)
    {
        throw DocumentLoadError(DocumentLoadError::NotFound(), m_filepath, errorCode.message());
    }
    else
    {
        // Lock document
        HANDLE fileLock = CreateFileW(m_filepath.c_str(),
                GENERIC_READ,
                0, // Exclusive access
                nullptr, // security attributes
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                nullptr //template file
            );
        if (!fileLock)
        {
            CloseHandle(fileLock);
            throw DocumentLoadError(DocumentLoadError::IsLocked(), m_filepath, "cannot lock file");
        }
        CloseHandle(fileLock);
    }

    std::filesystem::copy_file(m_filepath, m_documentCopyPath);
}

, :


  • , NotFound
  • , , , , , -
  • , IsLocked

, - ?



, , . C C++, .


, :


bool DocumentLoader::MakeDocumentWorkdirCopy()
{
    boost::system::error_code errorCode;
    if (!boost::filesystem::exists(m_filepath, errorCode) || errorCode)
    {
        throw DocumentLoadError(DocumentLoadError::NotFound(), m_filepath,      errorCode.message());
    }
    else if (!utils::ipc::MakeFileLock(m_filepath))
    {
        throw DocumentLoadError(DocumentLoadError::IsLocked(), m_filepath, "cannot lock file");
    }

    fs::copy_file(m_filepath, m_documentCopyPath);
}

C C++ ?


, :


  • C — " ",
  • C++ — " , ", -

C++ . C? , : C fopen . , out- C , C++ . , C++ RAII .


. , , C++ , C++ API C :


  • OpenGL, Vulkan, cairo API
  • CURL
  • winapi, freetype

" "!



ifstream, :


int main()
{
    try
    {
        std::ifstream in;
        in.exceptions(std::ios::failbit);
        in.open("C:/path-that-definitely-not-exist");
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << std::endl;
    }
    try
    {
        std::ifstream in;
        in.exceptions(std::ios::failbit);
        in.open("C:/");
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << std::endl;
    }
}

, , . , . , ?


  fstream


, API C, : . // .. .


//  ,   
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif

int main()
{
    try
    {
        FILE *in = ::fopen("C:/path-that-definitely-not-exist", "r");
        if (!in)
        {
            throw std::runtime_error("open failed");
        }
        // .. ..
        fclose(in);
    }
    catch (const std::exception& ex)
    {
        std::cout << ex.what() << std::endl;
    }
}

, C++17, API C.


?


, . iostream, , , read :


basic_istream& read(char_type* s, std::streamsize count);

iostream, tellg:


//      count   ,      filepath
std::string GetFirstFileBytes(const std::filesystem::path& filepath, size_t count)
{
    assert(count != 0);

    //  ,    
    std::ifstream stream;
    stream.exceptions(std::ifstream::failbit);

    //  : C++17   ifstream
    //     string,    wstring
    stream.open(filepath.native(), std::ios::binary);

    std::string result(count, '\0');
    //    count   
    stream.read(&result[0], count);
    //  ,   ,  .
    result = result.substr(0, static_cast(stream.tellg()));

    return result;
}

C++ , C — fread! , C++ wrapper for X, . : C++17.


: RAII


, RAII . - :


namespace detail
{
// ,   
struct FileDeleter
{
    void operator()(FILE* ptr)
    {
        fclose(ptr);
    }
};
}

//  FileUniquePtr -   unique_ptr,  fclose
using FileUniquePtr = std::unique_ptr;

::fopen fopen2:


//  ,   
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif

//   ,   Unicode    UNIX-.
FileUniquePtr fopen2(const char* filepath, const char* mode)
{
    assert(filepath);
    assert(mode);
    FILE *file = ::fopen(filepath, mode);
    if (!file)
    {
        throw std::runtime_error("file opening failed");
    }
    return FileUniquePtr(file);
}

:


  • Unicode- Windows

, :



:


- , - , , .


: , , errno . :


//  ,   
#if defined(_MSC_VER)
#define _CRT_SECURE_NO_WARNINGS
#endif

//   ,   Unicode    UNIX-.
FileUniquePtr fopen3(const char* filepath, const char mode)
{
    using namespace std::literals; //   ""s.

    assert(filepath);
    assert(mode);
    FILE *file = ::fopen(filepath, mode);
    if (!file)
    {
        const char* reason = strerror(errno);
        throw std::runtime_error("opening '"s + filepath + "' failed: "s + reason);
    }
    return FileUniquePtr(file);
}

, :



: filesystem


C++17 , — std::filesystem. , boost::filesystem:


  • 2038 , boost::filesystem
  • UTF-8 , (, SDL2) UTF-8
  • boost::filesystem , Undefined Behavior

filesystem , path. Unicode Windows:


//  VS2017  filesystem    experimental
#include 
#include 
#include filesystem>
#include 
#include 
#include 

namespace fs = std::experimental::filesystem;

FileUniquePtr fopen4(const fs::path& filepath, const char* mode)
{
    using namespace std::literals;

    assert(mode);
#if defined(_WIN32)
    fs::path convertedMode = mode;
    FILE *file = ::_wfopen(filepath.c_str(), convertedMode.c_str());
#else
    FILE *file = ::fopen(filepath.c_str(), mode);
#endif
    if (!file)
    {
        const char* reason = strerror(errno);
        throw std::runtime_error("opening '"s + filepath.u8string() + "' failed: "s + reason);
    }
    return FileUniquePtr(file);
}

, - . .


:


, 2017 , , . , VS2017 constexpr if , GCC 8 - if :



-, constexpr if C++17, .


FileUniquePtr fopen5(const fs::path& filepath, const char* mode)
{
    using namespace std::literals;

    assert(mode);
    FILE *file = nullptr;
    //   path::value_type -   wchar_t,  wide-
    //  Windows      UTF-16,   .
    //  : wchar_t   UTF-16   Windows.
    if constexpr (std::is_same_v)
    {
        fs::path convertedMode = mode;
        file = _wfopen(filepath.c_str(), convertedMode.c_str());
    }
    //    ,    UTF-8    Unicode
    else
    {
        file = fopen(filepath.c_str(), mode);
    }
    if (!file)
    {
        const char* reason = strerror(errno);
        throw std::runtime_error("opening '"s + filepath.u8string() + "' failed: "s + reason);
    }
    return FileUniquePtr(file);
}

! C++ , C . , ( ) , IDE .



, — , .


  • ,
  • C, : fopen4 - , mode C, ,
  • fopen - , ,

C, WinAPI, CURL OpenGL .



C++ Russia 2016 C++ Russia 2017 , :



, 2013 "C++ Seasoning" Sean Parent. :



, C++ . ---. - C.


  • C .
  • , : C, —

. :


C/C++. .
C++17?

8 . 3 .

. , .

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/331100/

:  

: [1] []
 

:
: 

: ( )

:

  URL