-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstdio.cpp
More file actions
113 lines (94 loc) · 3.14 KB
/
Copy pathstdio.cpp
File metadata and controls
113 lines (94 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* File: /lib/impl/stream/stdio.cpp
*
* This file is a part of cpplib project which is distributed under MIT License.
* See file LICENSE for full license details.
*
* Copyright (c) 2020-present Nikita Zuev (V.Slavski!) <[email protected]>
*/
#include "../../../lib/debug/platform.hpp"
#ifdef CPPLIB_PLATFORM_POSIX
#include <sys/ioctl.h>
#include <unistd.h>
#endif // CPPLIB_PLATFORM_POSIX
#include <cerrno>
#include <cstdio>
#include <cstdarg>
#include <limits>
#include "./stdio.hpp"
namespace lib::stream::impl {
// IMPLEMENTATION lib::stream::impl::stdio
data::result_t stdio::putc( char symbol ) {
return check_error( ::std::fputc( symbol, stdout ) );
}
data::result_t stdio::puts( const char* string ) {
return check_error( ::std::fputs( string, stdout ) );
}
data::result_t stdio::printf( CPPLIB_PRINTF_ANNOTATION const char* format, ... )
//CPPLIB_PRINTF_ATTRIBUTE( format(printf,/*implicit this,*/2,3) )
{
va_list args;
va_start( args, format );
const auto result = check_error( ::std::vfprintf( stdout, format, args ) );
va_end( args );
return result;
}
data::result_t stdio::check_error( isize result ) {
if ( result >= 0 )
return (usize) result;
if ( errno == 0 )
return {};
return error_ = ::std::make_error_condition( (::std::errc) errno );
}
// IMPLEMENTATION lib::stream::impl::stdio: lib::data::rstream_t, lib::data::wstream_t
data::result_t stdio::read( const data::buffer_t & buffer )/* override*/ {
#ifndef CPPLIB_PLATFORM_POSIX
const auto result = ::std::fread( buffer.data(), 1, buffer.size(), stdin );
if ( result == 0 and check_error( ::std::ferror( stdin ) ).failed() )
return error_;
return result;
#else
return check_error( ::read( STDIN_FILENO, buffer.data(), buffer.size() ) );
#endif // not CPPLIB_PLATFORM_POSIX
}
data::result_t stdio::write( const data::cbuffer_t & buffer )/* override*/ {
#ifndef CPPLIB_PLATFORM_POSIX
const auto result = ::std::fwrite( buffer.data(), 1, buffer.size(), stdout );
if ( result == 0 and check_error( ::std::ferror( stdout ) ).failed() )
return error_;
return result;
#else
return check_error( ::write( STDOUT_FILENO, buffer.data(), buffer.size() ) );
#endif // not CPPLIB_PLATFORM_POSIX
}
bool stdio::read_flush()/* override*/ {
/// @todo Implement?
return false;
}
bool stdio::write_flush()/* override*/ {
return check_error( ::std::fflush( stdout ) ).success();
}
data::result_t stdio::read_size()/* override*/ {
#ifndef CPPLIB_PLATFORM_POSIX
/// @todo Is it possible to determine it standard way?
return ::std::numeric_limits< decltype(read_size()) >::max();
#else
int value = 0;
auto result = check_error( ::ioctl( STDIN_FILENO, FIONREAD, &value ) );
if ( result.success() )
result = (usize) value;
return result;
#endif // not CPPLIB_PLATFORM_POSIX
}
data::result_t stdio::write_size()/* override*/ {
#ifndef CPPLIB_PLATFORM_POSIX
/// @todo Is it possible to determine it standard way?
return ::std::numeric_limits< decltype(write_size()) >::max();
#else
int value = 0;
auto result = check_error( ::ioctl( STDOUT_FILENO, TIOCOUTQ, &value ) );
if ( result.success() )
result = (usize) value;
return result;
#endif // not CPPLIB_PLATFORM_POSIX
}
} // namespace lib::stream::impl