Line data Source code
1 : /**
2 : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef STAPPLER_CORE_IO_SPIOCONSUMER_H_
25 : #define STAPPLER_CORE_IO_SPIOCONSUMER_H_
26 :
27 : #include "SPIOCommon.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::io {
30 :
31 : struct ConsumerTraitsStream {
32 : using stream_type = std::basic_ostream<char>;
33 424750 : static size_t WriteFn(void *ptr, const uint8_t *buf, size_t nbytes) {
34 424750 : ((stream_type *)ptr)->write((const char *)buf, nbytes);
35 424750 : return nbytes;
36 : }
37 :
38 0 : static void FlushFn(void *ptr) { ((stream_type *)ptr)->flush(); }
39 : };
40 :
41 : template <typename T> size_t WriteFunction(T &, const uint8_t *buf, size_t nbytes);
42 : template <typename T> void FlushFunction(T &);
43 :
44 : template <class T>
45 : struct ConsumerTraitsOverload {
46 : static size_t WriteFn(void *ptr, const uint8_t *buf, size_t nbytes) {
47 : return WriteFunction(*((T *)ptr), buf, nbytes);
48 : }
49 :
50 : static void FlushFn(void *ptr) { FlushFunction(*((T *)ptr)); }
51 : };
52 :
53 : template <typename T>
54 : struct ConsumerTraitsReolution {
55 : using type = typename std::conditional<
56 : std::is_base_of<std::basic_ostream<char>, T>::value,
57 : ConsumerTraitsStream,
58 : ConsumerTraitsOverload<T>>::type;
59 : };
60 :
61 : template <typename T>
62 : struct ConsumerTraits {
63 : using traits_type = typename ConsumerTraitsReolution<T>::type;
64 :
65 424750 : static size_t WriteFn(void *ptr, const uint8_t *buf, size_t nbytes) {
66 424750 : return traits_type::WriteFn(ptr, buf, nbytes);
67 : }
68 :
69 0 : static void FlushFn(void *ptr) { traits_type::FlushFn(ptr); }
70 : };
71 :
72 : struct Consumer {
73 : template <typename T, typename Traits = ConsumerTraits<typename std::decay<T>::type>> Consumer(T &t);
74 :
75 : size_t write(const uint8_t *buf, size_t nbytes) const;
76 : size_t write(const Buffer &) const;
77 : void flush() const;
78 :
79 : void *ptr = nullptr;
80 : write_fn write_ptr = nullptr;
81 : flush_fn flush_ptr = nullptr;
82 : };
83 :
84 : template <typename T, typename Traits>
85 325 : inline Consumer::Consumer(T &t)
86 325 : : ptr((void *)(&t))
87 325 : , write_ptr(&Traits::WriteFn)
88 325 : , flush_ptr(&Traits::FlushFn) { }
89 :
90 0 : inline size_t Consumer::write(const uint8_t *buf, size_t nbytes) const { return write_ptr(ptr, buf, nbytes); }
91 : inline void Consumer::flush() const { flush_ptr(ptr); }
92 :
93 : }
94 :
95 : #endif /* STAPPLER_CORE_IO_SPIOCONSUMER_H_ */
|