jaulib v1.4.1-17-gd77ace3-dirty
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
test_darray_01.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2020-2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#include <cassert>
25#include <cstring>
26#include <type_traits>
27
28#include <jau/test/catch2_ext.hpp>
29
30#include "test_datatype01.hpp"
31
32#include "test_datatype02.hpp"
33
34#include <jau/basic_algos.hpp>
35#include <jau/basic_types.hpp>
36#include <jau/darray.hpp>
38#include <jau/callocator.hpp>
40
41/**
42 * Test general use of jau::darray, jau::cow_darray and jau::cow_vector.
43 */
44using namespace jau;
45
46/**********************************************************************************************************************************************/
47/**********************************************************************************************************************************************/
48/**********************************************************************************************************************************************/
49/**********************************************************************************************************************************************/
50/**********************************************************************************************************************************************/
51
52TEST_CASE( "JAU DArray Test 01 - jau::darray initializer list", "[datatype][jau][darray]" ) {
53 int i = 0;
55 (void)ml;
56 // printf("XX: %s\n\n", ml->toString().c_str());
57 ++i;
58 });
59 REQUIRE(3 == i);
60}
61
63 int i = 0;
64 jau::for_each(clist.begin(), clist.end(), [&i](const GattCharacteristicSpec& ml){
65 (void)ml;
66 // printf("XX: %s\n\n", ml->toString().c_str());
67 ++i;
68 });
69 return i;
70}
72 int i = 0;
73 jau::for_each(clist.begin(), clist.end(), [&i](const GattCharacteristicSpec& ml){
74 (void)ml;
75 // printf("XX: %s\n\n", ml->toString().c_str());
76 ++i;
77 });
78 return i;
79}
80
81// NOLINTBEGIN(modernize-use-designated-initializers)
82TEST_CASE( "JAU DArray Test 02 - jau::darray immutable type (const)", "[const][jau][darray]" ) {
84 // GattCharacteristicPropertySpec[9]:
85 { { Read, Mandatory },
88 // GattClientCharacteristicConfigSpec:
90 };
92 cs1,
94 // GattCharacteristicPropertySpec[9]:
95 { { Read, Mandatory },
98 // GattClientCharacteristicConfigSpec:
100 } };
101 clist.push_back( cs1 );
102 int i = 0;
103 jau::for_each(clist.begin(), clist.end(), [&i](const GattCharacteristicSpec& ml){
104 (void)ml;
105 // printf("XX: %s\n\n", ml->toString().c_str());
106 ++i;
107 });
108 REQUIRE(3 == i);
110 REQUIRE(3 == countGattCharacteristicSpecList02Copy(clist));
111}
112// NOLINTEND(modernize-use-designated-initializers)
113
114/**********************************************************************************************************************************************/
115/**********************************************************************************************************************************************/
116/**********************************************************************************************************************************************/
117/**********************************************************************************************************************************************/
118/**********************************************************************************************************************************************/
119
120template<class Payload>
122
123template<class Payload>
125
126template<class Payload>
128 int name;
130
131 std::string toString() const noexcept {
132 std::string res = "NSPL-Default-"+std::to_string(name)+"[sz "+std::to_string(payload.size())+"/"+std::to_string(payload.capacity())+": ";
133 int i=0;
134 jau::for_each(payload.cbegin(), payload.cend(), [&](const std::shared_ptr<Payload>& e) {
135 if(0<i) {
136 res.append(", ");
137 }
138 static_assert(true == std::is_pointer_v<const char*>);
139 // static_assert(true == std::is_pointer_v<decltype(e)>);
140
141 res.append("[").append(jau::to_string(e)).append("]");
142 ++i;
143 } );
144 res.append("]");
145 return res;
146 }
147};
148
149template<class Payload>
151 int name;
153
154 std::string toString() const noexcept {
155 std::string res = "NSPL-MemMove-"+std::to_string(name)+"[sz "+std::to_string(payload.size())+"/"+std::to_string(payload.capacity())+": ";
156 int i=0;
157 jau::for_each(payload.cbegin(), payload.cend(), [&](const std::shared_ptr<Payload>& e) {
158 if(0<i) {
159 res.append(", ");
160 }
161 res.append("[").append(jau::to_string(e)).append("]");
162 ++i;
163 } );
164 res.append("]");
165 return res;
166 }
167};
168
169template<class Payload>
171
172template<class Payload>
174
175template<class Payload>
177 int name;
179
180 std::string toString() const noexcept {
181 std::string res = "NPL-Default-"+std::to_string(name)+"[sz "+std::to_string(payload.size())+"/"+std::to_string(payload.capacity())+": ";
182 int i=0;
183 jau::for_each(payload.cbegin(), payload.cend(), [&](const typename PayloadListDefault<Payload>::value_type & e) {
184 if(0<i) {
185 res += ", ";
186 }
187 res.append("[").append(jau::to_string(e)).append("]");
188 ++i;
189 } );
190 res += "]";
191 return res;
192 }
193};
194
195template<class Payload>
197 int name;
199
200 std::string toString() const noexcept {
201 std::string res = "NPL-MemMove-"+std::to_string(name)+"[sz "+std::to_string(payload.size())+"/"+std::to_string(payload.capacity())+": ";
202 int i=0;
203 jau::for_each(payload.cbegin(), payload.cend(), [&](const Payload& e) {
204 if(0<i) {
205 res += ", ";
206 }
207 res.append("[").append(jau::to_string(e)).append("]");
208 ++i;
209 } );
210 res += "]";
211 return res;
212 }
213};
214
215template<class Payload>
218 int i=0;
219 for(i=0; i<2; i++) {
220 std::shared_ptr<Payload> sp(std::make_shared<Payload>( name+i )); // copy-elision + make_shared in-place
221 data.push_back( sp );
222 }
223 CHECK( 2 == data.size() );
224 for(i=2; i<4; i++) {
225 std::shared_ptr<Payload> sp(new Payload( name+i )); // double malloc: 1 Payload, 2 shared_ptr
226 data.push_back( std::move( sp ) ); // move the less efficient into
227 }
228 CHECK( 4 == data.size() );
230}
231template<class Payload>
233 printf("XXX1: %s\n", src.toString().c_str());
234 const size_t sz0 = src.payload.size();
235 src.payload.pop_back();
236 src.payload.erase(src.payload.cbegin());
237 CHECK( sz0 - 2 == src.payload.size() );
238 printf("XXX2: %s\n", src.toString().c_str());
239 return src;
240}
241
242template<class Payload>
245 int i=0;
246 for(i=0; i<2; i++) {
247 std::shared_ptr<Payload> sp(std::make_shared<Payload>( name+i )); // copy-elision + make_shared in-place
248 data.push_back( sp );
249 }
250 CHECK( 2 == data.size() );
251 for(i=2; i<4; i++) {
252 std::shared_ptr<Payload> sp(new Payload( name+i )); // double malloc: 1 Payload, 2 shared_ptr
253 data.push_back( std::move( sp ) ); // move the less efficient into
254 }
255 CHECK( 4 == data.size() );
257}
258template<class Payload>
261 int i=0;
262 for(i=0; i<2; i++) {
263 Payload sp( name+i ); // copy-elision
264 data.push_back( sp );
265 }
266 CHECK( 2 == data.size() );
267 for(i=2; i<4; i++) {
268 Payload sp( name+i );
269 data.push_back( std::move( sp ) ); // move the less efficient into
270 }
271 CHECK( 4 == data.size() );
273}
274template<class Payload>
277 int i=0;
278 for(i=0; i<2; i++) {
279 Payload sp( name+i ); // copy-elision
280 data.push_back( sp );
281 }
282 CHECK( 2 == data.size() );
283 for(i=2; i<4; i++) {
284 Payload sp( name+i );
285 data.push_back( std::move( sp ) ); // move the less efficient into
286 }
287 CHECK( 4 == data.size() );
289}
290
291#define CHECK_TRAITS 0
292
293template< class Cont >
294static void print_container_info(const std::string& type_id, const Cont &c,
295 std::enable_if_t< jau::is_darray_type<Cont>::value, bool> = true )
296{
297 printf("\nContainer Type %s (a darray, a cow %d):\n - Uses memmove %d (trivially_copyable %d); realloc %d; base_of jau::callocator %d; secmem %d; size %d bytes\n",
298 type_id.c_str(), jau::is_cow_type<Cont>::value,
299 Cont::uses_memmove,
300 std::is_trivially_copyable_v<typename Cont::value_type>,
301 Cont::uses_realloc,
302 std::is_base_of_v<jau::callocator<typename Cont::value_type>, typename Cont::allocator_type>,
303 Cont::uses_secmem,
304 (int)sizeof(c));
305}
306
307template<class Cont>
308static void print_container_info(const std::string& type_id, const Cont &c,
309 std::enable_if_t< !jau::is_darray_type<Cont>::value, bool> = true )
310{
311 printf("\nContainer Type %s (!darray, a cow %d); size %d bytes\n",
312 type_id.c_str(), jau::is_cow_type<Cont>::value, (int)sizeof(c));
313}
314
315
316template<class Payload>
317static void testDArrayValueType(const std::string& type_id) {
318 {
319 // jau::type_cue<Payload>::print(type_id, jau::TypeTraitGroup::ALL);
320 // jau::type_cue<std::shared_ptr<Payload>>::print("std::shared_ptr<"+type_id+">", jau::TypeTraitGroup::ALL);
321 }
322 {
323#if CHECK_TRAITS
324 CHECK( true == std::is_base_of<jau::callocator<Payload>, jau::callocator<Payload>>::value);
326 CHECK( true == std::is_trivially_copyable<Payload>::value);
328#endif
329
331 print_container_info("NamedPayloadListDefault<"+type_id+">", data.payload);
332 size_t sz0 = data.payload.size();
333 printf("COPY-0.0: %s\n\n", data.toString().c_str());
334 CHECK( sz0 == data.payload.capacity() );
335
336 {
337 Payload def_value(1);
339 printf("COPY-0.1: %s\n\n", data2.toString().c_str());
340 CHECK( 0 == data2.payload.size() );
341 CHECK( 0 == data2.payload.capacity() );
342 data2.payload.reserve(2);
343 printf("COPY-0.1a: %s\n\n", data2.toString().c_str());
344 CHECK( 0 == data2.payload.size() );
345 CHECK( 2 == data2.payload.capacity() );
346 data2.payload.resize(2, def_value);
347 printf("COPY-0.1b: %s\n\n", data2.toString().c_str());
348 CHECK( 2 == data2.payload.size() );
349 CHECK( 2 == data2.payload.capacity() );
350 for(Payload p : data2.payload) {
351 CHECK(def_value == p);
352 }
353 data2.payload.resize(4, def_value);
354 printf("COPY-0.2: %s\n\n", data2.toString().c_str());
355 CHECK( 4 == data2.payload.size() );
356 CHECK( 4 == data2.payload.capacity() );
357 for(Payload p : data2.payload) {
358 CHECK(def_value == p);
359 }
360
361 data2.payload.erase(data2.payload.cbegin());
362 printf("COPY-0.3: %s\n\n", data2.toString().c_str());
363 CHECK( 3 == data2.payload.size() );
364 CHECK( sz0 == data2.payload.capacity() );
365
366 data2.payload.shrink_to_fit();
367 printf("COPY-0.4: %s\n\n", data2.toString().c_str());
368 CHECK( 3 == data2.payload.size() );
369 CHECK( 3 == data2.payload.capacity() );
370 }
371 {
372 Payload def_value(1);
374 printf("COPY-1.0: %s\n\n", data2.toString().c_str());
375 CHECK( sz0 == data2.payload.size() );
376 CHECK( sz0 == data2.payload.capacity() );
377 data2.payload.erase(data2.payload.cbegin());
378 printf("COPY-1.1: %s\n\n", data2.toString().c_str());
379 CHECK( sz0-1 == data2.payload.size() );
380 CHECK( sz0 == data2.payload.capacity() );
381 data2.payload.resize(sz0, def_value);
382 printf("COPY-1.2: %s\n\n", data2.toString().c_str());
383 CHECK( sz0 == data2.payload.size() );
384 CHECK( sz0 == data2.payload.capacity() );
385 size_t j=0;
386 for(Payload p : data2.payload) {
387 if( j++ < sz0-1 ) {
388 CHECK(def_value != p);
389 } else {
390 CHECK(def_value == p);
391 }
392 }
393 data2.payload.resize(sz0*2, def_value);
394 printf("COPY-1.2: %s\n\n", data2.toString().c_str());
395 CHECK( sz0*2 == data2.payload.size() );
396 CHECK( sz0*2 == data2.payload.capacity() );
397 j=0;
398 for(Payload p : data2.payload) {
399 if( j++ < sz0-1 ) {
400 CHECK(def_value != p);
401 } else {
402 CHECK(def_value == p);
403 }
404 }
405 }
406 {
407 Payload def_value(1);
409 printf("COPY-2.0: %s\n\n", data3.toString().c_str());
410 CHECK( sz0 == data3.payload.size() );
411 CHECK( sz0 == data3.payload.capacity() );
412 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
413 printf("COPY-2.1: %s\n\n", data3.toString().c_str());
414 CHECK( sz0/2 == data3.payload.size() );
415 CHECK( sz0 == data3.payload.capacity() );
416 data3.payload.resize(sz0, def_value);
417 printf("COPY-2.2: %s\n\n", data3.toString().c_str());
418 CHECK( sz0 == data3.payload.size() );
419 CHECK( sz0 == data3.payload.capacity() );
420 size_t j=0;
421 for(Payload p : data3.payload) {
422 if( j++ < sz0/2 ) {
423 CHECK(def_value != p);
424 } else {
425 CHECK(def_value == p);
426 }
427 }
428 data3.payload.resize(sz0*2, def_value);
429 printf("COPY-2.3: %s\n\n", data3.toString().c_str());
430 CHECK( sz0*2 == data3.payload.size() );
431 CHECK( sz0*2 == data3.payload.capacity() );
432 j=0;
433 for(Payload p : data3.payload) {
434 if( j++ < sz0/2 ) {
435 CHECK(def_value != p);
436 } else {
437 CHECK(def_value == p);
438 }
439 }
440 }
441 {
443 CHECK( sz0 == data8.payload.size() );
444 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
445 CHECK( 2*sz0 == data8.payload.size() );
446 printf("COPY+2: %s\n\n", data8.toString().c_str());
447 }
448 }
449 {
450#if CHECK_TRAITS
451 CHECK( true == std::is_base_of<jau::callocator<Payload>, jau::callocator<Payload>>::value);
453 CHECK( true == std::is_trivially_copyable<Payload>::value);
455#endif
456
458 print_container_info("NamedPayloadListMemMove<"+type_id+">", data.payload);
459
461 data2.payload.erase(data2.payload.cbegin());
462
464 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
465
467 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
468
469 printf("COPY-0: %s\n\n", data.toString().c_str());
470 printf("COPY-1: %s\n\n", data2.toString().c_str());
471 printf("COPY-2: %s\n\n", data3.toString().c_str());
472 printf("COPY+2: %s\n\n", data8.toString().c_str());
473 }
474 {
475#if CHECK_TRAITS
476 CHECK( true == std::is_base_of<jau::callocator<std::shared_ptr<Payload>>, jau::callocator<std::shared_ptr<Payload>>>::value);
478 CHECK( true == std::is_trivially_copyable<std::shared_ptr<Payload>>::value);
480#endif
481
483 print_container_info("NamedSharedPayloadListDefault<"+type_id+">", data.payload);
484
486 data2.payload.erase(data2.payload.cbegin());
487
489 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
490
492 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
493
494 printf("COPY-0: %s\n\n", data.toString().c_str());
495 printf("COPY-1: %s\n\n", data2.toString().c_str());
496 printf("COPY-2: %s\n\n", data3.toString().c_str());
497 printf("COPY+2: %s\n\n", data8.toString().c_str());
498
500 printf("MODI+2-2: %s\n\n", data8_mod.toString().c_str());
501
502 struct Holder {
504 NamedSharedPayloadListDefault<Payload> & get_ref() { return lala; }
505 NamedSharedPayloadListDefault<Payload> & get_ref2() { lala.payload.pop_back(); return lala; }
506 NamedSharedPayloadListDefault<Payload> get_copy() { return lala; }
507 };
508 Holder holder{ data };
509 NamedSharedPayloadListDefault<Payload> & r1r1 = holder.get_ref();
510 printf("R1R1: %s\n\n", r1r1.toString().c_str());
511
512 NamedSharedPayloadListDefault<Payload> r2c1 = holder.get_ref();
513 printf("R1C1: %s\n\n", r2c1.toString().c_str());
514
515 NamedSharedPayloadListDefault<Payload> c1c2 = holder.get_copy();
516 printf("C1C2: %s\n\n", c1c2.toString().c_str());
517
518 r1r1 = holder.get_ref2();
519 printf("R2R2: %s\n\n", r1r1.toString().c_str());
520 }
521 {
522#if CHECK_TRAITS
523 CHECK( true == std::is_base_of<jau::callocator<std::shared_ptr<Payload>>, jau::callocator<std::shared_ptr<Payload>>>::value);
525 CHECK( true == std::is_trivially_copyable<std::shared_ptr<Payload>>::value);
527#endif
528
530 print_container_info("NamedSharedPayloadListMemMove<"+type_id+">", data.payload);
531
533 data2.payload.erase(data2.payload.cbegin());
534
536 data3.payload.erase(data3.payload.begin(), data3.payload.cbegin()+data3.payload.size()/2);
537
539 data8.payload.insert(data8.payload.begin(), data.payload.cbegin(), data.payload.cend());
540
541 printf("COPY-0: %s\n\n", data.toString().c_str());
542 printf("COPY-1: %s\n\n", data2.toString().c_str());
543 printf("COPY-2: %s\n\n", data3.toString().c_str());
544 printf("COPY+2: %s\n\n", data8.toString().c_str());
545 }
546}
547
549 return *GATT_SERVICES[i];
550}
551
553#if CHECK_TRAITS
555 CHECK( true == GattCharacteristicSpecList::uses_realloc);
556
557 CHECK( true == GattCharacteristicSpecList::uses_memmove);
558 CHECK( true == std::is_trivially_copyable<GattCharacteristicSpec>::value);
559#endif
560
562 print_container_info("darray<GattCharacteristicSpec>", gatt2.characteristics);
563
565
566 GattServiceCharacteristic gatt2b = gatt2;
568
569 GattServiceCharacteristic gatt2c(gatt2);
571
572 printf("COPY0-1: %s\n\n", gatt2.toString().c_str());
573 printf("COPY1-2: %s\n\n", gatt2b.toString().c_str());
574 printf("COPY2-3: %s\n\n", gatt2c.toString().c_str());
575}
576
577TEST_CASE( "JAU DArray Test 10 - jau::darray value_type behavior (type traits)", "[datatype][jau][darray]" ) {
583}
584
585/**********************************************************************************************************************************************/
586/**********************************************************************************************************************************************/
587/**********************************************************************************************************************************************/
588/**********************************************************************************************************************************************/
589/**********************************************************************************************************************************************/
590
Implementation of a dynamic linear array storage, aka vector, including relative positional access.
Definition darray.hpp:154
constexpr iterator erase(const_iterator cpos)
Like std::vector::erase(), removes the elements at pos.
Definition darray.hpp:1364
constexpr iterator end() noexcept
Definition darray.hpp:833
constexpr size_type size() const noexcept
Like std::vector::size().
Definition darray.hpp:1115
constexpr void push_back(const value_type &x)
Like std::vector::push_back(), copy.
Definition darray.hpp:1568
constexpr const_iterator cbegin() const noexcept
Definition darray.hpp:831
constexpr iterator begin() noexcept
Definition darray.hpp:829
static constexpr const bool uses_realloc
Definition darray.hpp:161
static constexpr const bool uses_memmove
Definition darray.hpp:159
constexpr UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
Like std::for_each() of 'algorithm'.
std::string to_string(const endian_t v) noexcept
Return std::string representation of the given endian.
constexpr bool value(const Bool rhs) noexcept
constexpr std::string_view name(const Bool v) noexcept
uint_bytes_t< sizeof(unsigned long int)> nsize_t
Natural 'size_t' alternative using uint<XX>_t with xx = sizeof(unsigned long int)*8 as its natural si...
Definition int_types.hpp:85
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
Definition backtrace.hpp:32
std::string toString() const noexcept
jau::darray< GattCharacteristicSpec > characteristics
PayloadListDefault< Payload > payload
std::string toString() const noexcept
PayloadListMemMove< Payload > payload
std::string toString() const noexcept
std::string toString() const noexcept
SharedPayloadListDefault< Payload > payload
std::string toString() const noexcept
SharedPayloadListMemMove< Payload > payload
A simple allocator using POSIX C functions: ::malloc(), ::free() and ::realloc().
template< class T > is_cow_type<T>::value compile-time Type Trait, determining whether the given temp...
template< class T > is_darray_type<T>::value compile-time Type Trait, determining whether the given t...
Definition darray.hpp:1988
static int countGattCharacteristicSpecList01ConstRef(const jau::darray< const GattCharacteristicSpec > &clist)
static NamedSharedPayloadListDefault< Payload > makeNamedSharedPayloadListDefault(int name)
jau::darray< Payload, jau::nsize_t, jau::callocator< Payload >, true > PayloadListMemMove
static NamedSharedPayloadListMemMove< Payload > makeNamedSharedPayloadListMemMove(int name)
static void print_container_info(const std::string &type_id, const Cont &c, std::enable_if_t< jau::is_darray_type< Cont >::value, bool >=true)
static void testDArrayValueType(const std::string &type_id)
static NamedPayloadListDefault< Payload > makeNamedPayloadListDefault(int name)
static GattServiceCharacteristic returnGattSrvcChar(int i)
jau::darray< std::shared_ptr< Payload > > SharedPayloadListDefault
static NamedPayloadListMemMove< Payload > makeNamedPayloadListMemMove(int name)
TEST_CASE("JAU DArray Test 01 - jau::darray initializer list", "[datatype][jau][darray]")
static NamedSharedPayloadListDefault< Payload > modifyCopyOfNamedSharedPayloadListDefault(NamedSharedPayloadListDefault< Payload > src)
jau::darray< Payload > PayloadListDefault
static int countGattCharacteristicSpecList02Copy(jau::darray< const GattCharacteristicSpec > clist)
static void testDArrayGattServiceCharacteristic()
jau::darray< std::shared_ptr< Payload >, jau::nsize_t, jau::callocator< std::shared_ptr< Payload > >, true > SharedPayloadListMemMove
const jau::darray< const GattServiceCharacteristic * > GATT_SERVICES
@ ReliableWriteExt
FIXME: extension?
@ Indicate
@ AuthSignedWrite
@ WriteNoAck
@ Broadcast
@ AuxWriteExt
FIXME: extension?
@ WriteWithAck
@ Optional
@ Mandatory
@ Excluded
@ DEVICE_NAME
@ APPEARANCE
int printf(const char *format,...)
Operating Systems predefined macros.