Esempio n. 1
0
// static
std::string File::readToString(const char *filename)
{
    // Binary mode is required on Windows to be able to determine a size
    // that can be passed to fread().
    File file(filename, "rb");
    FILE *fp = file.handle();

    if (std::fseek(fp, 0L, SEEK_END) != 0)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Seeking to end of file failed"),
                             "fseek", errno);
    }
    long len = std::ftell(fp);
    if (len == -1)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Reading file length failed"),
                             "ftell", errno);
    }
    if (std::fseek(fp, 0L, SEEK_SET) != 0)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Seeking to start of file failed"),
                             "fseek", errno);
    }

    std::vector<char> data(len);
    file.readBytes(&data[0], len);
    file.close();

    std::string result(&data[0], len);
    // The below is necessary on Windows to make newlines stay as '\n' on a
    // roundtrip.
    result = replaceAll(result, "\r\n", "\n");

    return result;
}
Esempio n. 2
0
bool File::readLine(std::string *line)
{
    line->clear();
    const size_t bufsize = 256;
    std::string result;
    char buf[bufsize];
    buf[0] = '\0';
    FILE *fp = handle();
    while (fgets(buf, bufsize, fp) != NULL)
    {
        size_t length = std::strlen(buf);
        result.append(buf, length);
        if (length < bufsize - 1 || buf[length - 1] == '\n')
        {
            break;
        }
    }
    if (ferror(fp))
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
                             "fgets", errno);
    }
    *line = result;
    return !result.empty() || !feof(fp);
}
Esempio n. 3
0
void File::throwOnNotFound(const NotFoundInfo &info)
{
    throwOnError(info);
    const std::string message
        = formatString("File '%s' does not exist or is not accessible.\n%s",
                       info.filename, info.message);
    GMX_THROW_WITH_ERRNO(InvalidInputError(message), info.call, info.err);
}
Esempio n. 4
0
void File::writeString(const char *str)
{
    if (fprintf(handle(), "%s", str) < 0)
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Writing to file failed"),
                             "fprintf", errno);
    }
}
Esempio n. 5
0
void File::throwOnError(const NotFoundInfo &info)
{
    if (info.wasError)
    {
        const std::string message
            = formatString("Failed to access file '%s'.\n%s",
                           info.filename, info.message);
        GMX_THROW_WITH_ERRNO(FileIOError(message), info.call, info.err);
    }
}
Esempio n. 6
0
// static
FILE *File::openRawHandle(const char *filename, const char *mode)
{
    FILE *fp = fopen(filename, mode);
    if (fp == NULL)
    {
        GMX_THROW_WITH_ERRNO(
                FileIOError(formatString("Could not open file '%s'", filename)),
                "fopen", errno);
    }
    return fp;
}
Esempio n. 7
0
void
IntegrationTestFixture::redirectStringToStdin(const char* theString)
{
    std::string fakeStdin("fake-stdin");
    gmx::File::writeFileFromString(fakeStdin, theString);
    if (NULL == std::freopen(fakeStdin.c_str(), "r", stdin))
    {
        GMX_THROW_WITH_ERRNO(FileIOError("Failed to redirect a string to stdin"),
                             "freopen",
                             errno);
    }
}
Esempio n. 8
0
void File::open(const char *filename, const char *mode)
{
    GMX_RELEASE_ASSERT(impl_->fp_ == NULL,
                       "Attempted to open the same file object twice");
    // TODO: Port all necessary functionality from ffopen() here.
    impl_->fp_ = fopen(filename, mode);
    if (impl_->fp_ == NULL)
    {
        GMX_THROW_WITH_ERRNO(
                FileIOError(formatString("Could not open file '%s'", filename)),
                "fopen", errno);
    }
}
Esempio n. 9
0
void File::close()
{
    GMX_RELEASE_ASSERT(impl_->fp_ != NULL,
                       "Attempted to close a file object that is not open");
    GMX_RELEASE_ASSERT(impl_->bClose_,
                       "Attempted to close a file object that should not be");
    bool bOk = (fclose(impl_->fp_) == 0);
    impl_->fp_ = NULL;
    if (!bOk)
    {
        GMX_THROW_WITH_ERRNO(
                FileIOError("Error while closing file"), "fclose", errno);
    }
}
Esempio n. 10
0
void File::readBytes(void *buffer, size_t bytes)
{
    errno = 0;
    FILE *fp = handle();
    // TODO: Retry based on errno or something else?
    size_t bytesRead = std::fread(buffer, 1, bytes, fp);
    if (bytesRead != bytes)
    {
        if (feof(fp))
        {
            GMX_THROW(FileIOError(
                        formatString("Premature end of file\n"
                                     "Attempted to read: %d bytes\n"
                                     "Successfully read: %d bytes",
                                     static_cast<int>(bytes),
                                     static_cast<int>(bytesRead))));
        }
        else
        {
            GMX_THROW_WITH_ERRNO(FileIOError("Error while reading file"),
                                 "fread", errno);
        }
    }
}
Esempio n. 11
0
bool Path::isEquivalent(const std::string &path1, const std::string &path2)
{
    //based on boost_1_56_0/libs/filesystem/src/operations.cpp under BSL
#ifdef GMX_NATIVE_WINDOWS
    // Note well: Physical location on external media is part of the
    // equivalence criteria. If there are no open handles, physical location
    // can change due to defragmentation or other relocations. Thus handles
    // must be held open until location information for both paths has
    // been retrieved.

    // p2 is done first, so any error reported is for p1
    // FixME: #1635
    handle_wrapper h2(
            CreateFile(
                    path2.c_str(),
                    0,
                    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                    0,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS,
                    0));

    handle_wrapper h1(
            CreateFile(
                    path1.c_str(),
                    0,
                    FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
                    0,
                    OPEN_EXISTING,
                    FILE_FLAG_BACKUP_SEMANTICS,
                    0));

    if (h1.handle == INVALID_HANDLE_VALUE
        || h2.handle == INVALID_HANDLE_VALUE)
    {
        // if one is invalid and the other isn't, then they aren't equivalent,
        // but if both are invalid then it is an error
        if (h1.handle == INVALID_HANDLE_VALUE
            && h2.handle == INVALID_HANDLE_VALUE)
        {
            GMX_THROW(FileIOError("Path::isEquivalent called with two invalid files"));
        }

        return false;
    }

    // at this point, both handles are known to be valid

    BY_HANDLE_FILE_INFORMATION info1, info2;

    if (!GetFileInformationByHandle(h1.handle, &info1))
    {
        GMX_THROW(FileIOError("Path::isEquivalent: GetFileInformationByHandle failed"));
    }

    if (!GetFileInformationByHandle(h2.handle, &info2))
    {
        GMX_THROW(FileIOError("Path::isEquivalent: GetFileInformationByHandle failed"));
    }

    // In theory, volume serial numbers are sufficient to distinguish between
    // devices, but in practice VSN's are sometimes duplicated, so last write
    // time and file size are also checked.
    return
        info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
        && info1.nFileIndexHigh == info2.nFileIndexHigh
        && info1.nFileIndexLow == info2.nFileIndexLow
        && info1.nFileSizeHigh == info2.nFileSizeHigh
        && info1.nFileSizeLow == info2.nFileSizeLow
        && info1.ftLastWriteTime.dwLowDateTime
        == info2.ftLastWriteTime.dwLowDateTime
        && info1.ftLastWriteTime.dwHighDateTime
        == info2.ftLastWriteTime.dwHighDateTime;
#else
    struct stat s1, s2;
    int         e2 = stat(path2.c_str(), &s2);
    int         e1 = stat(path1.c_str(), &s1);

    if (e1 != 0 || e2 != 0)
    {
        // if one is invalid and the other isn't then they aren't equivalent,
        // but if both are invalid then it is an error.
        if (e1 != 0 && e2 != 0)
        {
            GMX_THROW_WITH_ERRNO(
                    FileIOError("Path::isEquivalent called with two invalid files"),
                    "stat", errno);
        }
        return false;
    }

    // both stats now known to be valid
    return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino
           // According to the POSIX stat specs, "The st_ino and st_dev fields
           // taken together uniquely identify the file within the system."
           // Just to be sure, size and mod time are also checked.
           && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime;
#endif
}