Did you get your order?


Endianness
. The compiler will vaguepettyassignment.eu generate the call to
appropriate
writeData()
function, which in turn forward it to
writeBig()
or
writeLittle()
.
To serialise data using big endian the traits should be de
fined as following:
struct
MyTraits
{
typedef
embxx::io::traits::endian::Big Endianness;
};
SomeClass someClassObj;
...
someClassObj.serialise(iter);
// Will serialise using big endian
Data Serialisation
66
The interface described above is very easy and convenient to use a
nd quite easy to
implement using straightforward approach. However, any variation
of template parameters
create an instantiation of new binary code which may create sig
nificant code bloat if not
used carefully. Consider the following:
Read/write of signed vs unsigned integer values. The serialisa
tion/deserialisation code
is identical for both cases, but won't be considered as such wh
en instantiating the
functions. To optimise this case, there is a need to implement
read/write operations only
for unsigned value, while the "signed" functions become wrappe
rs around the former.
Don't forget a sign extension operation when retrieving part
ial signed value.
The read/write operations are more or less the same for any lengt
h of the values, i.e of
any types:
(unsigned) char
,
(unsigned) short
,
(unsigned) int
, etc... To optimise this
case, there is a need for internal function that receives leng
th of serialised value as a
run time parameter, while the functions described above are mere
wrappers around it.
Usage of the iterators also require caution. For example readin
g values may be
performed using regular
iterator
as well as
const_iterator
, i.e. iterator pointing to
const values. These are two different iterator types that will
duplicate the "read"
functionality if both of them are used:
char
buf[
128
] = {...};
const
char
* iter1 = &buf[
0
];
char
* iter2 = &buf[
0
];
// Instantiation 1
auto
value1 = embxx::io::readBig<
std
::
uint16_t
>(iter1);
// Instantiation 2
auto
value2 = embxx::io::readBig<
std
::
uint16_t
>(iter2);
It is possible to optimise the case above for random access iterato
r by using temporary
pointers to unsigned characters to read the required value. Afte
r retrieval is complete, just
increment the value of the passed iterator with number of chara
cters read.
All the consideration points stated above require quite comple
x implementation of the
serialisation/deserialisation functionality with multiple le
vels of abstraction which is beyond
the scope of this book. It would be a nice exercise to try and
implement it yourself. Another
option is to use the code as is from
embxx
library
******* 0000-09d0: b3 c3 44 74-02 63 40 48-44 f4 ce b2-20 8d cd 18 ..Dt.c@H D....... 0000-09e0: fe f2 20 c1-84 64 d4 0e-40 02 a0 22-48 40 33 06 .....d.. @.."H@3. 0000-09f0: c9 9a cd 81-64 ee aa 20-73 0f db 01-c4 5a 5a 5a ....d... s....ZZZ 0000-0a00: b2 1b 37 6e-bc 63 fe fc-f9 4d 1e 8f-e7 42 48 00 ..7n.c.. .M...BH. 0000-0a10: f5 8a 92 92-12 ff 39 e7-9c 53 e1 fc-1c 8b c5 72 ......9. .S.....r 0000-0a20: b1 58 2c 97-c9 64 ac fe-fe fe 64 47-47 c7 d8 e1 .X,..d.. ..dGG... 0000-0a30: c3 87 93 ab-56 ad 8a 6d-da b4 29 75-e8 d0 a1 4c ....V..m ..)u...L 0000-0a40: 69 69 a9 f9-0f ff f0 0f-65 0b 17 2e-f4 05 83 c1 ii...... e....... 0000-0a50: 91 54 2a d5-d7 d3 d3 13-3f 74 e8 50-66 df be 7d .T*..... ?t.Pf..} 0000-0a60: 6a df be 7d-9e 03 07 0e-a8 ce ce 4e-67 18 aa 09 j..}.... ...Ng... 0000-08d0: 86 74 3c c4-00 1c e0 ff-9c 88 4e 64-0c 08 89 88 .t<..... ..Nd.... 0000-08e0: de 59 06 80-25 90 79 78-bb 21 41 c8-9f cb 82 04 .Y..%.yx .!A..... 0000-08f0: 2b 71 48 30-16 82 04 31-51 00 0d 00-b6 43 02 c6 +qH0...1 Q....C.. 0000-0900: 06 00 3d 00-9e 01 60 24-12 89 d9 1e-8f a7 1c c0 ..=...`$ ........ 0000-0910: 02 e7 89 02-81 80 f9 b1-8f 7d 6c 2a-00 f4 f5 f5 ........ .}l*.... 0000-0920: a5 76 ee dc-39 a3 b3 b3-33 d9 dd dd-9d ea ea ea .v..9... 3....... 0000-0930: 4a f7 f5 f5-59 a9 54 2a-7d e8 d0 a1-fe f5 eb d7 J...Y.T* }....... 0000-0940: f7 e6 72 b9-21 48 63 d9-c9 c4 79 01-04 aa aa aa ..r.!Hc. ..y..... 0000-0950: 22 a9 54 ca-ee ef ef ef-86 04 70 3e-fd be 42 90 ".T..... ..p>..B. 0000-0960: 0c 66 08 12-70 8d e9 9b-01 c9 00 a6-20 d9 4c 1b .f..p... ......L. 0000-0970: 72 6d b2 20-81 62 4c df-e2 70 87 6f-a6 01 0c ea rm...bL. .p.o.... 0000-0980: cf ee 0c 43-35 e1 06 88-11 b8 c3 5a-6b f5 e7 77 ...C5... ...Zk..w 0000-0990: b2 80 f9 90-2c e0 21 48-a0 98 84 9b-01 74 86 cc ....,.!H .....t.. 0000-09a0: 7a f4 fb 4e-eb d7 ae 87-1b 1c b6 eb-c7 c5 5f e7 z..N.... ......_. 0000-07c0: 90 00 2e 05-19 82 9a 86-1b 34 8e ea-bf 39 8f 37 ........ .4...9.7 0000-07d0: f4 7b f6 40-02 db 3c fd-b3 5f 7f f5-e9 bf 39 f7 .{.@..<. ._....9. 0000-07e0: b7 f4 f3 8d-e9 f7 3c a2-9f cf 79 2f-b9 71 db 4e ......<. ..y/.q.N 0000-07f0: 8d fb 0c ce-b6 74 82 d0-a4 fe 9c 4e-50 98 d2 ef .....t.. ...NP... 0000-0800: 2d a9 df 27-8b f6 10 11-d1 09 87 01-21 11 d1 3b -..'.... ....!..; 0000-0810: 4b 41 b2 6c-43 90 60 e3-2f c9 3e 65-01 ec 00 30 KA.lC.`. /.>e...0 0000-0820: 09 12 f0 8d-00 68 83 04-4d 9d 90 79-86 8d 00 a2 .....h.. M..y.... 0000-0830: 90 e2 33 fd-00 cc c2 c2-c2 a9 3e 9f-cf 07 00 4a ..3..... ..>....J 0000-0840: 29 75 ea a9-a7 4e 3c e5-94 53 ea 66-cf 9e 7d b0 )u...N<. .S.f..}. 0000-0850: b1 b1 31 d5-dd dd dd bb-71 e3 c6 c3-07 0f 1e 1c ..1..... q....... 0000-0860: 18 1b 1b 1b-84 04 46 e3-b3 7e 8e 0c-dc c0 2e 00 ......F. .~...... 0000-0870: a9 78 5a 0c-c9 2e 3a c1-9b 47 df 2f-33 ee 79 bc .xZ...:. .G./3.y. 0000-0880: fa 96 86 1b-70 25 20 01-5d 02 6e e6-d3 c9 de 39 ....p%.. ].n....9 0000-0890: 73 1e 9d a0-cc 84 0c 9f-0d ea d7 2a-80 0c 6f f5 s....... ...*..o. 0000-08a0: e8 9b d2 f7-4b 01 88 01-e8 86 64 3a-63 fa 7d 59 ....K... ..d:c.}Y 0000-08b0: 90 20 16 fa-7d 00 6e 16-35 a5 bf b7-f4 fb 19 00 ....}.n. 5....... 0000-08c0: d0 05 19 36-1b 87 9b 59-a4 13 53 15-80 53 01 1c ...6...Y ..S..S.. --- Sometimes the endianness of data serialisation may depend on so
me traits class
parameters. In order to be able to choose "Little" or "Big" variant
functions at compile time
instead of runtime the tag parameter dispatch idiom must be use
d.
There are similar read/write functions, but instead of being
differentiated by name they have
additional tag parameter to specify the endianness of seriali
sation:
Data Serialisation
64
/// Same as writeBig(value, iter);
template
<
typename
T,
typename
TIter>
void
writeData
(
T value,
TIter& iter,
const
traits::endian::Big& endian)
;
/// Same as writeBig(value, iter)
template
<
std
::
size_t
TSize,
typename
T,
typename
TIter>
void
writeData
(
T value,
TIter& iter,
const
traits::endian::Big& endian)
;
/// Same as writeLittle(value, iter)
template
<
typename
T,
typename
TIter>
void
writeData
(
T value,
TIter& iter,
const
traits::endian::Little& endian)
;
/// Same as writeLittle(value, ite
r)
template
<
std
::
size_t
TSize,
typename
T,
typename
TIter>
void
writeData
(
T value,
TIter& iter,
const
traits::endian::Little& endian)
;
/// Same as readBig(iter)
template
<
typename
T,
typename
TIter>
T
readData
(TIter& iter,
const
traits::endian::Big& endian)
;
/// Same as readBig(iter)
template
<
typename
T,
std
::
size_t
TSize,
typename
TIter>
T
readData
(TIter& iter,
const
traits::endian::Big& endian)
;
/// Same as readLittle(iter)
template
<
typename
T,
typename
TIter>
T
readData
(TIter& iter,
const
traits::endian::Little& endian)
;
/// Same as readLittle(iter)
template
<
typename
T,
std
::
size_t
TSize,
typename
TIter>
T
readData
(TIter& iter,
const
traits::endian::Little& endian)
;
The
traits::endian::Big
and
traits::endian::Little
are defined as empty tag classes:
Data Serialisation
65
namespace
traits
{
namespace
endian
{
struct
Big {};
struct
Little {};
}
// namespace endian
}
// namespace traits
For example:
template
<
typename
TTraits>
class
SomeClass
{
public
:
typedef
typename
TTraits::Endianness Endianness;
template
<
typename
TIter>
void
serialise
(TIter& iter)
const
{
embxx::io::writeData(data_, iter, Endiannes
s());
}
private
:
std
::
uint32_t
data_;
};
So the code above is not aware what endianness is used to seri
alise the data. It is provided
as internal type of
Traits
class named

posted by Isaac Hobart at 11:26 AM

0 Comments:

Post a Comment

<< Home