2020-12-26 14:12:05 -08:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
2016-09-25 17:23:39 -07:00
|
|
|
|
2019-05-31 13:43:32 -07:00
|
|
|
#define _CRT_NONSTDC_NO_WARNINGS
|
|
|
|
|
|
2018-04-29 23:33:19 -07:00
|
|
|
#include "wpi/raw_istream.h"
|
2016-09-25 17:23:39 -07:00
|
|
|
|
2016-10-08 16:03:33 -07:00
|
|
|
#ifdef _WIN32
|
|
|
|
|
#include <io.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-10-21 20:31:20 -07:00
|
|
|
#include <cstdlib>
|
|
|
|
|
#include <cstring>
|
2021-06-06 16:13:58 -07:00
|
|
|
#include <string_view>
|
2017-10-21 20:31:20 -07:00
|
|
|
|
2018-04-29 23:33:19 -07:00
|
|
|
#include "wpi/SmallVector.h"
|
2021-06-01 21:50:35 -07:00
|
|
|
#include "wpi/fs.h"
|
2017-08-13 00:56:35 -07:00
|
|
|
|
2017-08-13 00:37:14 -07:00
|
|
|
#if defined(_MSC_VER)
|
|
|
|
|
#ifndef STDIN_FILENO
|
2017-10-21 20:31:20 -07:00
|
|
|
#define STDIN_FILENO 0
|
2017-08-13 00:37:14 -07:00
|
|
|
#endif
|
|
|
|
|
#ifndef STDOUT_FILENO
|
2017-10-21 20:31:20 -07:00
|
|
|
#define STDOUT_FILENO 1
|
2017-08-13 00:37:14 -07:00
|
|
|
#endif
|
|
|
|
|
#ifndef STDERR_FILENO
|
2017-10-21 20:31:20 -07:00
|
|
|
#define STDERR_FILENO 2
|
2017-08-13 00:37:14 -07:00
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-09-25 17:23:39 -07:00
|
|
|
using namespace wpi;
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
std::string_view raw_istream::getline(SmallVectorImpl<char>& buf, int maxLen) {
|
2017-08-13 00:56:35 -07:00
|
|
|
buf.clear();
|
|
|
|
|
for (int i = 0; i < maxLen; ++i) {
|
|
|
|
|
char c;
|
|
|
|
|
read(c);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (has_error()) {
|
2021-06-06 16:13:58 -07:00
|
|
|
return {buf.data(), buf.size()};
|
2020-12-28 12:58:06 -08:00
|
|
|
}
|
|
|
|
|
if (c == '\r') {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-08-13 00:56:35 -07:00
|
|
|
buf.push_back(c);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (c == '\n') {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-08-13 00:56:35 -07:00
|
|
|
}
|
2021-06-06 16:13:58 -07:00
|
|
|
return {buf.data(), buf.size()};
|
2017-08-13 00:56:35 -07:00
|
|
|
}
|
|
|
|
|
|
2016-09-02 20:53:45 -07:00
|
|
|
void raw_mem_istream::close() {}
|
|
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
size_t raw_mem_istream::in_avail() const {
|
|
|
|
|
return m_left;
|
|
|
|
|
}
|
2016-10-21 22:50:38 -07:00
|
|
|
|
2017-10-21 20:31:20 -07:00
|
|
|
void raw_mem_istream::read_impl(void* data, size_t len) {
|
2016-09-02 20:53:45 -07:00
|
|
|
if (len > m_left) {
|
|
|
|
|
error_detected();
|
2018-05-13 19:08:26 -07:00
|
|
|
len = m_left;
|
2016-09-02 20:53:45 -07:00
|
|
|
}
|
2016-09-25 17:23:39 -07:00
|
|
|
std::memcpy(data, m_cur, len);
|
|
|
|
|
m_cur += len;
|
|
|
|
|
m_left -= len;
|
2018-05-13 19:08:26 -07:00
|
|
|
set_read_count(len);
|
2016-09-25 17:23:39 -07:00
|
|
|
}
|
2016-10-08 16:03:33 -07:00
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
static int getFD(std::string_view Filename, std::error_code& EC) {
|
2017-08-13 00:37:50 -07:00
|
|
|
// Handle "-" as stdin. Note that when we do this, we consider ourself
|
|
|
|
|
// the owner of stdin. This means that we can do things like close the
|
|
|
|
|
// file descriptor when we're done and set the "binary" flag globally.
|
2021-06-06 16:13:58 -07:00
|
|
|
if (Filename == "-") {
|
2017-08-13 00:37:50 -07:00
|
|
|
EC = std::error_code();
|
|
|
|
|
return STDIN_FILENO;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
fs::file_t F = fs::OpenFileForRead(Filename, EC);
|
2021-06-01 21:50:35 -07:00
|
|
|
if (EC) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
int FD = fs::FileToFd(F, EC, fs::OF_None);
|
2020-12-28 12:58:06 -08:00
|
|
|
if (EC) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2017-08-13 00:37:50 -07:00
|
|
|
return FD;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-06 16:13:58 -07:00
|
|
|
raw_fd_istream::raw_fd_istream(std::string_view filename, std::error_code& ec,
|
2017-10-21 20:31:20 -07:00
|
|
|
size_t bufSize)
|
2017-08-13 00:37:50 -07:00
|
|
|
: raw_fd_istream(getFD(filename, ec), true, bufSize) {}
|
|
|
|
|
|
2017-10-21 20:31:20 -07:00
|
|
|
raw_fd_istream::raw_fd_istream(int fd, bool shouldClose, size_t bufSize)
|
2016-10-08 16:03:33 -07:00
|
|
|
: m_bufSize(bufSize), m_fd(fd), m_shouldClose(shouldClose) {
|
|
|
|
|
m_cur = m_end = m_buf = static_cast<char*>(std::malloc(bufSize));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
raw_fd_istream::~raw_fd_istream() {
|
2020-12-28 12:58:06 -08:00
|
|
|
if (m_shouldClose) {
|
|
|
|
|
close();
|
|
|
|
|
}
|
2016-10-08 16:03:33 -07:00
|
|
|
std::free(m_buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void raw_fd_istream::close() {
|
|
|
|
|
if (m_fd >= 0) {
|
|
|
|
|
::close(m_fd);
|
|
|
|
|
m_fd = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-28 12:58:06 -08:00
|
|
|
size_t raw_fd_istream::in_avail() const {
|
|
|
|
|
return m_end - m_cur;
|
|
|
|
|
}
|
2016-10-21 22:50:38 -07:00
|
|
|
|
2017-10-21 20:31:20 -07:00
|
|
|
void raw_fd_istream::read_impl(void* data, size_t len) {
|
2018-05-13 19:08:26 -07:00
|
|
|
char* cdata = static_cast<char*>(data);
|
|
|
|
|
size_t pos = 0;
|
|
|
|
|
while (static_cast<size_t>(m_end - m_cur) < len) {
|
2016-10-08 16:03:33 -07:00
|
|
|
// not enough data
|
|
|
|
|
if (m_cur == m_end) {
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
int count = ::_read(m_fd, m_buf, m_bufSize);
|
|
|
|
|
#else
|
|
|
|
|
ssize_t count = ::read(m_fd, m_buf, m_bufSize);
|
|
|
|
|
#endif
|
2017-09-06 22:06:21 -07:00
|
|
|
if (count <= 0) {
|
2016-10-08 16:03:33 -07:00
|
|
|
error_detected();
|
2018-05-13 19:08:26 -07:00
|
|
|
set_read_count(pos);
|
2016-10-08 16:03:33 -07:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
m_cur = m_buf;
|
|
|
|
|
m_end = m_buf + count;
|
2018-05-13 19:08:26 -07:00
|
|
|
continue;
|
2016-10-08 16:03:33 -07:00
|
|
|
}
|
|
|
|
|
|
2018-05-13 19:08:26 -07:00
|
|
|
size_t left = m_end - m_cur;
|
|
|
|
|
std::memcpy(&cdata[pos], m_cur, left);
|
|
|
|
|
m_cur += left;
|
|
|
|
|
pos += left;
|
|
|
|
|
len -= left;
|
2016-10-08 16:03:33 -07:00
|
|
|
}
|
|
|
|
|
|
2018-05-13 19:08:26 -07:00
|
|
|
std::memcpy(&cdata[pos], m_cur, len);
|
2016-10-08 16:03:33 -07:00
|
|
|
m_cur += len;
|
2018-05-13 19:08:26 -07:00
|
|
|
pos += len;
|
|
|
|
|
set_read_count(pos);
|
2016-10-08 16:03:33 -07:00
|
|
|
}
|