tsMuxer/libmediation/fs/osdep/file_unix.cpp
Daniel Kamil Kozar 451ec61a50
Introduce a uniform formatting style (#131)
The repository now contains a clang-format file which should be used when committing new code. Additionally, a new workflow job is added which checks the conformance of source files to the specified formatting rules.

Fixes #47.
2020-01-14 21:56:44 +01:00

167 lines
3.7 KiB
C++

/***********************************************************************
* File: file.cpp
* Author: Andrey Kolesnikov
* Date: 13 oct 2006
***********************************************************************/
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sstream>
#include "../directory.h"
#include "../file.h"
#if defined(__APPLE__) && defined(__MACH__)
#define O_LARGEFILE 0
#endif
void makeUnixOpenFlags(unsigned int oflag, int* const unixOflag)
{
int sysFlags = 0;
if (oflag & File::ofRead)
sysFlags = O_RDONLY;
if (oflag & File::ofWrite)
{
if (oflag & File::ofRead)
sysFlags = O_RDWR | O_TRUNC;
else
sysFlags = O_WRONLY | O_TRUNC;
if (!(oflag & File::ofOpenExisting))
sysFlags |= O_CREAT;
if (oflag & File::ofNoTruncate)
{
sysFlags &= ~O_TRUNC;
}
if (oflag & File::ofAppend)
{
sysFlags |= O_APPEND;
sysFlags &= ~O_TRUNC;
}
}
if (oflag & File::ofCreateNew)
sysFlags |= O_CREAT | O_EXCL;
*unixOflag = sysFlags;
}
File::File() : m_impl((void*)0xffffffff), m_name(""), m_pos(0) {}
File::File(const char* fName, unsigned int oflag, unsigned int systemDependentFlags) /* throw ( std::runtime_error ) */
: m_name(fName), m_pos(0)
{
int sysFlags = 0;
makeUnixOpenFlags(oflag, &sysFlags);
m_impl = (void*)::open(fName, sysFlags | O_LARGEFILE | systemDependentFlags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if ((long)m_impl == -1)
{
std::ostringstream ss;
ss << "Error opening file " << fName << ": " << strerror(errno) << "(" << errno << ")";
throw std::runtime_error(ss.str());
}
}
File::~File()
{
if (isOpen())
close();
}
bool File::open(const char* fName, unsigned int oflag, unsigned int systemDependentFlags)
{
m_name = fName;
if (isOpen())
close();
int sysFlags = 0;
makeUnixOpenFlags(oflag, &sysFlags);
createDir(extractFileDir(fName), true);
m_impl = (void*)::open(fName, sysFlags | O_LARGEFILE | systemDependentFlags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
return (long)m_impl != -1;
}
bool File::close()
{
if (::close((long)m_impl) == 0)
{
m_impl = (void*)0xffffffff;
return true;
}
return false;
}
int File::read(void* buffer, uint32_t count) const
{
if (!isOpen())
return -1;
m_pos += count;
return ::read((long)m_impl, buffer, count);
}
int File::write(const void* buffer, uint32_t count)
{
if (!isOpen())
return -1;
m_pos += count;
return ::write((long)m_impl, buffer, count);
}
bool File::isOpen() const { return m_impl != (void*)0xffffffff; }
bool File::size(uint64_t* const fileSize) const
{
bool res = false;
struct stat64 buf;
if (isOpen() && (fstat64((long)m_impl, &buf) == 0))
{
*fileSize = buf.st_size;
res = true;
}
return res;
}
uint64_t File::seek(int64_t offset, SeekMethod whence)
{
if (!isOpen())
return (uint64_t)-1;
int sWhence = 0;
switch (whence)
{
case smBegin:
sWhence = SEEK_SET;
break;
case smCurrent:
sWhence = SEEK_CUR;
break;
case smEnd:
sWhence = SEEK_END;
break;
}
m_pos = offset;
#if defined(__APPLE__) && defined(__MACH__)
return lseek((long)m_impl, offset, sWhence);
#else
return lseek64((long)m_impl, offset, sWhence);
#endif
}
bool File::truncate(uint64_t newFileSize)
{
#if defined(__APPLE__) && defined(__MACH__)
return ftruncate((long)m_impl, newFileSize) == 0;
#else
return ftruncate64((long)m_impl, newFileSize) == 0;
#endif
}
void File::sync() { ::sync(); }