5 #ifndef NDS2_CLIENT_NDS1_CHANNEL_LISTING_HH
6 #define NDS2_CLIENT_NDS1_CHANNEL_LISTING_HH
12 #include "common/utils.hh"
13 #include "nds1/common/basic_io.hh"
22 typedef std::array< char, 148 > raw_sc2_channel;
24 template <
typename Reader,
typename Transform >
25 class ChannelListIterator
29 typedef typename std::result_of< decltype (
30 &Transform::operator( ) )(
31 Transform, raw_sc2_channel ) >::type value_type;
32 typedef value_type& reference;
33 typedef value_type* pointer;
34 typedef std::size_t difference_type;
35 typedef std::input_iterator_tag iterator_category;
37 ChannelListIterator( Reader& r, Transform& t )
38 : pos_{ 0 }, end_{ 0 }, t_( t ), r_( r ), cur_{}
41 ChannelListIterator( Reader& r, Transform& t,
int pos,
int end )
42 : pos_{ pos }, end_{ end }, t_( t ), r_( r ),
43 cur_( t( read_in_sc2_channel( r ) ) )
46 ChannelListIterator( Reader& r, Transform& t,
int end )
47 : pos_{ end }, end_{ end }, t_( t ), r_( r ), cur_{}
50 ChannelListIterator( ChannelListIterator&& other )
51 : pos_{ other.pos_ }, end_{ other.end_ }, t_( other.t_ ),
52 r_( other.r_ ), cur_{ std::move( other.cur_ ) }
57 const ChannelListIterator< Reader, Transform >& other )
58 : pos_{ other.pos_ }, end_{ other.end_ }, t_( other.t_ ),
59 r_( other.r_ ), cur_( other.cur_ )
64 operator==(
const ChannelListIterator< Reader, Transform >&
67 return other.pos_ == pos_;
71 operator!=(
const ChannelListIterator< Reader, Transform >&
74 return other.pos_ != pos_;
77 reference operator*( )
82 ChannelListIterator< Reader, Transform >& operator++( )
88 read_in_sc2_channel( r_, buf );
98 ChannelListIterator< Reader, Transform > operator++(
int )
101 ChannelListIterator< Reader, Transform >( *this );
114 read_in_sc2_channel( Reader& r, raw_sc2_channel& buf )
116 const size_t name_length = 60;
117 std::array< char, 1 > tmp;
118 r.read_exactly( buf.data( ), buf.data( ) + name_length );
124 r.peek( tmp.data( ), tmp.data( ) + 1 );
125 if ( tmp[ 0 ] ==
'\t' )
127 r.read_exactly( tmp.data( ), tmp.data( ) + 1 );
129 r.read_exactly( buf.data( ) + name_length,
130 buf.data( ) + buf.size( ) );
133 static raw_sc2_channel
134 read_in_sc2_channel( Reader& r )
137 read_in_sc2_channel( r, buf );
174 nds_impl::common::IdentityTransform< raw_sc2_channel >,
176 nds_impl::common::TruePredicate<
typename std::result_of<
177 decltype ( &Transform::operator( ) )(
178 Transform, raw_sc2_channel ) >::type > >
180 read_get_channels( Reader& r,
182 Transform t = Transform( ),
183 Predicate p = Predicate( ) )
185 typedef nds_impl::nds1::common::Basic_IO< Reader > basic_reader;
186 basic_reader io( r );
187 auto count = io.read_uint32_hex( );
188 ChannelListIterator< Reader, Transform > begin_range(
190 ChannelListIterator< Reader, Transform > end_range(
192 std::copy_if( begin_range, end_range, it, p );
202 #ifdef _NDS_IMPL_ENABLE_CATCH_TESTS_
210 #include "socket/socket.hh"
212 #include "socket/buffered_reader.hh"
213 #include "common/status_codes.hh"
214 #include "common/utils.hh"
215 #include "nds1/common/utils.hh"
217 #include "tests/nds1_test_utilities.hh"
218 #include "tests/dummy_socket.hh"
221 TEST_CASE(
"LIST Channels" )
240 nds_testing::DummySocket s{ nds_testing::generate_sc2_channel_stream(
242 nds_impl::Socket::BufferedReader< nds_testing::DummySocket > r{ s };
244 std::vector< std::string > channels;
246 using nds_impl::nds1::v12_2::raw_sc2_channel;
248 nds_impl::nds1::v12_2::read_get_channels(
250 std::back_inserter( channels ),
252 []( nds_impl::nds1::v12_2::raw_sc2_channel input ) -> std::string {
253 typedef nds_impl::common::Span< char > char_span;
254 char_span input_span( input.data( ), input.size( ) );
255 char_span name_span =
256 nds_impl::nds1::common::identify_padded_string(
257 input.data( ), input.data( ) + 60 );
258 return std::string{ name_span.data( ), name_span.size( ) };
260 []( std::string& channel_name ) ->
bool {
264 REQUIRE( channels.size( ) == 340 );
267 #endif // _NDS_IMPL_ENABLE_CATCH_TESTS_
269 #endif // NDS2_CLIENT_NDS1_CHANNEL_LISTING_HH