libscio/fdiobuf.cpp

78 lines
1.8 KiB
C++

//
// fdiobuf.cpp
// libscio
//
// Created by Bob Polis at 2020-02-14
// Copyright (c) 2020 SwiftCoder. All rights reserved.
//
#include "libscio.hpp"
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif
std::streambuf::int_type sc::io::fdiobuf::underflow() {
int num = ::read(_fd, &_ch, 1);
if (num <= 0) {
return EOF;
}
setg(&_ch, &_ch, &_ch + 1);
return _ch;
}
std::streamsize sc::io::fdiobuf::xsgetn(char* s, std::streamsize n) {
return ::read(_fd, s, n);
}
std::streambuf::int_type sc::io::fdiobuf::overflow(std::streambuf::int_type c) {
if (c != EOF) {
int res;
if ((res = ::write(_fd, &c, 1)) != 1) {
return EOF;
}
else {
std::cerr << "write result = " << res << ", errno = " << errno << '\n';
}
}
_ch = c;
setp(&_ch, &_ch + 1);
return c;
}
std::streamsize sc::io::fdiobuf::xsputn(const char* s, std::streamsize num) {
int res = ::write(_fd, s, num);
if (res != num) {
std::cerr << "write result = " << res << ", errno = " << errno << '\n';
return EOF;
}
return res;
}
std::streambuf::pos_type sc::io::fdiobuf::seekoff(std::streambuf::off_type off,
std::ios_base::seekdir dir,
std::ios_base::openmode /*which*/) {
int whence;
switch (dir) {
case std::ios_base::beg: whence = SEEK_SET; break;
case std::ios_base::end: whence = SEEK_END; break;
case std::ios_base::cur: whence = SEEK_CUR; break;
default: throw std::runtime_error("invalid seekdir");
}
return ::lseek(_fd, off, whence);
}
std::streambuf::pos_type sc::io::fdiobuf::seekpos(std::streambuf::pos_type pos,
std::ios_base::openmode /*which*/) {
return ::lseek(_fd, pos, SEEK_SET);
}
std::streambuf::int_type sc::io::fdiobuf::pbackfail(std::streambuf::int_type /*c*/) {
if (::lseek(_fd, -1, SEEK_CUR) == -1) {
return EOF;
}
return 0;
}