Newer
Older
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% Copyright (C) 2015, Luca Fulchir<luca@fulchir.it>
% Permission is granted to copy, distribute and/or modify this document
% under the terms of the GNU Free Documentation License, Version 1.3
% or any later version published by the Free Software Foundation;
% with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
% A copy of the license is included in the section entitled "GNU
% Free Documentation License".
\documentclass[11pt,a4paper]{refart}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{hyperref}
\usepackage{makeidx}
\usepackage{verbatimbox}
\usepackage{listings}
\usepackage{color}
\definecolor{mygreen}{rgb}{0,0.6,0}
\definecolor{mygray}{rgb}{0.5,0.5,0.5}
\definecolor{mymauve}{rgb}{0.58,0,0.82}
\lstset{ %
backgroundcolor=\color{white}, % choose the background color; you must add \usepackage{color} or \usepackage{xcolor}
basicstyle=\footnotesize, % the size of the fonts that are used for the code
breakatwhitespace=false, % sets if automatic breaks should only happen at whitespace
breaklines=true, % sets automatic line breaking
captionpos=b, % sets the caption-position to bottom
commentstyle=\color{mygreen}, % comment style
deletekeywords={...}, % if you want to delete keywords from the given language
escapeinside={\%*}{*)}, % if you want to add LaTeX within your code
extendedchars=true, % lets you use non-ASCII characters; for 8-bits encodings only, does not work with UTF-8
frame=single, % adds a frame around the code
keepspaces=true, % keeps spaces in text, useful for keeping indentation of code (possibly needs columns=flexible)
keywordstyle=\color{blue}, % keyword style
language=C, % the language of the code
%otherkeywords={*,...}, % if you want to add more keywords to the set
%numbers=left, % where to put the line-numbers; possible values are (none, left, right)
%numbersep=5pt, % how far the line-numbers are from the code
%numberstyle=\tiny\color{mygray}, % the style that is used for the line-numbers
rulecolor=\color{black}, % if not set, the frame-color may be changed on line-breaks within not-black text (e.g. comments (green here))
showspaces=false, % show spaces everywhere adding particular underscores; it overrides 'showstringspaces'
showstringspaces=false, % underline spaces within strings only
showtabs=false, % show tabs within strings adding particular underscores
stepnumber=2, % the step between two line-numbers. If it's 1, each line will be numbered
stringstyle=\color{mymauve}, % string literal style
tabsize=4, % sets default tabsize to 2 spaces
title=\lstname % show the filename of files included with \lstinputlisting; also try caption instead of title
}
\title{Using libRaptorQ library: RFC6330 interface}
\date{\today}
\makeindex
\begin{document}
\maketitle
\begin{abstract}
\textbf{libRaptorQ} is a C++11 implementation of the RaptorQ Forward Error Correction. It includes two interfaces, one derived from the \href{https://tools.ietf.org/html/rfc6330}{RFC6330} standard, and one RAW API for a more flexible and easy usage.
This document is only about the RFC6330 interface.
The implementation was started as a university laboratory project, and will be later used and included in \href{https://www.fenrirproject.org}{Fenrir}, the
maintainer's master thesis project.
libRaptorQ is the only RaptorQ implementation in C++, include C hooks, and it is the only free (\textbf{LGPL3}) implementation of the rfc, except for the (apache2)
java implementation, OpenRQ.
\end{abstract}
\vfill\hfill
\begin{verbbox}[\tiny]
Copyright (C) 2015-2018, Luca Fulchir<luker@fenrirproject.org>
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".
\end{verbbox}
\theverbbox
\newpage
\tableofcontents
\newpage
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Contacts}\index{Contacts}
The main development and dicussions on the project, along with bug reporting, happens on
\href{https://fenrirproject.org/Luker/libRaptorQ}{the main website}.
\marginlabel{Mailing Lists} Mailing lists are available at \href{https://fenrirproject.org/lists}{https://fenrirproject.org/lists}\\
The two mailing lists are for development and announcements, but due to the low traffic of the development mailing list, it
can also be used by users for questions on the project.
\marginlabel{IRC} Since there are not many developers for now, the main irc channel is \textbf{\#fenrirproject} on freenode
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Build \& install}
\subsection{Get the source code}
This document follows the 1.0 stable release.
You can get the tarballs from the main website here:\\
\href{https://fenrirproject.org/Luker/libRaptorQ/tags}{https://fenrirproject.org/Luker/libRaptorQ/tags}
Or you can check out the repository (warning: development in progress):
\begin{verbatim}
$ git clone https://github.com/LucaFulchir/libRaptorQ.git
\end{verbatim}
You can also get it from our main server:
\begin{verbatim}
$ git clone https://fenrirproject.org/Luker/libRaptorQ.git
\end{verbatim}
\index{GPG}\marginlabel{GPG verification:}
Once you have cloned it, it's always a good thing to check the repository gpg
signatures, so you can import my key with:
\begin{verbatim}
$ gpg --keyserver pgp.mit.edu --recv-key 7393DAD255BEB5751DBDA04AB11CD823BA278C85
\end{verbatim}
Now you have the source, and the key, it's enough to check the signature of the
last commit:
\begin{verbatim}
$ git log -n 1 --show-signature
\end{verbatim}
The important part is that you get something like this:
\begin{verbbox}[\footnotesize]
gpg: Signature made Mon 11 Dec 2017 21:55:28 CET
gpg: using RSA key 8F7474044095B405D0F042F0A2CCA134BC7C8572
gpg: Good signature from "Luca Fulchir <luker@fenrirproject.org>" [unknown]
gpg: aka "Luca Fulchir <luca@fulchir.it>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 7393 DAD2 55BE B575 1DBD A04A B11C D823 BA27 8C85
\end{verbbox}
\theverbbox
And as long as you got the right key, and you find the \textbf{"gpg: Good signature"} string,
you can be sure you have the right code.
The main development happens in the $master$ branch, while we keep one branch for each stable version.
\subsection{Dependencies}\index{dependencies}
libRaptorQ has 4 dependencies:
\begin{description}
\item[\textbf{Eigen3}] This is used for matrix manipulation, which is a big part of RaptorQ.
\item[\textbf{lz4}] Used to compress cached precomputations.
\item[\textbf{git}] This is used not only to get the source, but also by the build system. We get the last git commit id and feed it to clang or gcc as seed for their
\item[\textbf{optionparser}] Library used to parse the command line easily in C++, without exceptions
internal random number generator. This makes it possible to have reproducible builds.
\end{description}
All dependencies are included in the sources, so you do not need to download and compile them.\\
Eigen3 is only needed at build time, so there is no need to download it again. we use the 3.2.8 version.\\
LZ4 is included as a git submodule. if you do not have it, run:
\begin{verbatim}
$ git submodule init
$ git submodule update
\end{verbatim}
and LZ4 will be build statically in the library (it will not be installed on the system)
\subsection{Build \& Install}
libRaptorQ uses the cMake build system, so things are fairly standard:
\begin{verbatim}
$ cd libRaptorQ.git
$ mkdir build
$ cd build
$ cmake ../
$ make -j 4
\end{verbatim}
By default, the libRaptorQ project tries to have deterministic builds. This means that if you compile things twice, or with two different computers, the
hash of the resulting library will be the same, provided that the same compiler (clang, gcc 4.8, gcc 4.9 etc) was used. Currently the only exception is the clang
compiler with the \textit{PROFILING} option enabled, and this will not likely be solved.
\index{cMake}
There are lots of options, you can use in cmake. As always, you can change them by adding ``\textbf{-Dcmake\_option=cmake\_value}'' when calling cmake.
You can always use the cmake-gui or ccmake commands to have the list of possible options.
The ones we recognize are:
\begin{description}
\item[LTO] ON/OFF. Default:\textbf{ON}. Enables \textit{Link Time Optimizatios} for clang or gcc. Makes libraries smaller and better optimized.
\item[PROFILING] ON/OFF. Default:\textbf{ON}.
Profiling compiles everything once, then runs a test to see which code paths are used more, and then
recompiles everything again, but making sure that the binary is optimized for those paths. Works with clang and gcc. Provides a slight speedup.
\item[CMAKE\_C\_COMPILER] gcc and clang are directly supported. other should work, too. This is only used if you want to build the C example.
\item[CMAKE\_CXX\_COMPILER] g++, clang++ are directly supported. other should work, too.
\item[CLANG\_STDLIB] use clang's libc++ standard library. Only available with clang.
\item[CMAKE\_BUILD\_TYPE] Type of build. you can choose between ``Debug'', ``Release'', ``MinSizeRel'' or ``RelWithDebInfo''
\item[CMAKE\_INSTALL\_PREFIX] Default to \textit{/usr/local}. Change it to fit your distribution guidelines.
\end{description}
Then you can build everything by running:
\begin{verbatim}
$ make -j 4
\end{verbatim}
Of course, you can configure the number of parallel jobs (the \textit{-j} parameter) to be what you need.
\marginlabel{Optional make targets:}
The following optional targets are also supported:
\begin{verbatim}
$ make docs tests examples
$ make everything
\end{verbatim}
The ``docs'' target builds this document, but you need latex with the refman style.
The tests are only useful to check perfromance of rfc compliance right now. ``examples'' compiles the C and C++ examples, which will not be installed.
\index{Install}\marginlabel{\textbf{Install:}}
The installation process is very simple:
\begin{verbatim}
$ make install DESTDIR=...
\end{verbatim}
You can change the \textit{DESTDIR} parameter to fit your distribution guidelines.
\newpage
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{Working with RaptorQ}
\subsection{Theory (you really need this)}\index{Theory}
To be able to work with liRaptorQ, you must first understand how the RaptorQ algorithms works. We won't go into the details, but just what you need
to be able to tune the algorithm to your needs.
\marginlabel{Fountain codes:}
Fountain codes are a special \textit{Forward-Error-Correcting} code class, which characteristic is simple: if you want to send $K$ packets, you actually
send $K+X$ packets, and the receiver only needs to get any $K$ packets to be able to reconstruct your data. The number $X$ of overhead packets can be as big
as you need (theoretically infinite), so you can tune it to be slightly higher than the expected packet loss.
\marginlabel{Systematic codes:} RaptorQ is also a systematic code. This means that those first $K$ packets are the input \textit{as-is} (\textbf{source symbols}),
and the $X$ packets (\textbf{repair symbols}) have the information needed to recover any of the lost source packets. This has the big advantage of
avoiding any kind of time and memory consuming decoding if there is no packet loss during the transmission.
\marginlabel{Complexity:} The RaptorQ algorithm is often presented as having a linear time encoder and decoder. This is both false and misleading.
Generating the source or repair symbols from the intermediate symbols has linear complexity. Generating the intermediate symbols has cubic complexity on the
number of symbols. Which is a completely different thing.
It is still very quick. On a core i7, 2.4Ghz, you need to wait \textit{0.4ms} for $10$ symbols, \textit{280ms} for 1.000 symbols, but it can take an hour for $27.000$ symbols.
RaptorQ handles up to $56.403$ symbols.
\marginlabel{\textbf{Caching}} libRaptorQ can work with big matrices that take a lot of time to compute. For this reason the matrices can be saved once they have
been computed the first time. libRaptorQ uses a \textbf{local} cache. The matrix can be compressed with LZ4.
\subsection{RFC6330: Blocks \& Symbols}
To understand how to properly use and tune libRaptorQ, you first need to understand how RaptorQ and the \textbf{RFC6330} handles its inputs, outputs, and what the time and memory
constraints are.
\index{Sequencing}\marginlabel{Input sequencing:}
The RC6330 needs to have the whole input you want to send before it can start working.\\
This means that it might be a little more difficult to use in live-streaming contexts, or where you need real-time data, but for that you probably want to use the single-block API in the \textbf{RaptorQ} C++ namespace. There is a second document tracking that interface, this document tracks only the RFC6330 interface.
Once you have the whole input, RFC6330 divides it into \textbf{blocks}. Each block \textit{is encoded and decoded independently} and will be divided into \textbf{symbols}. Each symbol \textit{should}
be transmitted separately in its own packet (if you are on the network).
\index{Sequencing!Sizes}\marginlabel{Sizes:}Each input can have up to \textit{256 blocks}, each block can have up to \textit{$56.403$ symbols}, and each
symbol can have up to \textit{$2^{16}-1$ bytes}long. This gives a maximum files size of almost $881$ GB (946270874880 bytes to be exact)
\index{Interleaving}\marginlabel{Interleaving:}
An other feature of RFC6330 is to automatically provide some interleaving of the input data before transmitting it. This means that one symbol will not
represent one sequential chunk of your input data, but more likely it's the concatenation of different \textbf{sub-symbols}. The size of the subsymbol must thus
be a fraction of the symbol size. \textit{This feature is not used if you set the size of the subsymbol to the size of symbol}.
\marginlabel{Memory and Time:}
Memory and time requirements are to be considered, though, as RFC6330 needs to run a cubic algorithm on matrix of size $K*K$, where $K$ is the number of
symbols in each block.\\
The algorithm needs to keep in memory two of these matrices, although most of the work is done on only one.\\
This is actually a lot. More benchmarks and optimizations will come later, for now remember that with 10 symbols it takes something like 0.4ms on a core i7 2.4GHZ, 280ms with 1000 symbols, and up to an hour with 27.000 symbols.
\subsection{C++ interface}
\index{Interface!C++}
To use the C++ interface you only need to include the \textbf{RaptorQ/RFC6330\_v1.hpp} header, and link \textbf{libRaptorQ} and your threading library (usually
\textit{libpthread}).
You can also use the library as a header-only include, by including \textbf{RaptorQ/RFC6330\_v1\_hdr.hpp}. All your code should keep working even if you switch between linked and header-only at a later date. If you use the header-only version, remember to have Eigen3 in your include path.
\marginlabel{Namespace}
Since the libRaptorQ library now has two very different usages, everything was split into two namespaces: \textbf{RFC6330} and \textbf{RaptorQ}. The names should be explanatory: the first namespace (that we cover in this document) is for the RFC interface, while the second namespace is for the low-level interface.
Since we will cover only the \textbf{RFC6330} namespace here, remember that everything we talk about is in this namespace.
\newpage
\index{Iterators}\marginlabel{Templates}
There are two main classes you will use:
\begin{verbatim}
template <typename Rnd_It, typename Fwd_It>
class Encoder
template <typename In_It, typename Fwd_It>
class Decoder
\end{verbatim}
As you might guess, the classes for the encoder and decoder take two template parameters.\\
For the \textbf{Encoder}, the first parameter \textit{MUST} be a \textit{random access iterator} to the input data, and the second parameter is an
\textit{forward iterator}. The random access iterator will be used to scan your input data, and perform an interleaving (if you did not set the same size the
symbol and to the subsymbol). The forward iterator will be used to write the data to your structure.\\
The same is done for the \textbf{Decoder}, but we do not need to do any interleaving on the input, so the first iterator can be just an input iterator,
and nothing more.
\subsection{Caching precomputations}
\index{Cache!C++'}
libRaptorQ can now cache the most used matrices for a quicker reference. The cache can be scaled up or down dynamically.
\begin{description}
\item[local\_cache\_size] \textbf{const uint64\_t local\_cache}\\
\textbf{return: bool}\\
Set the local cache size. returns false on error.
\item[get\_local\_cache\_size()] \textbf{return: uint64\_t}\\
get the size of our local cache
\item[supported\_compressions()] \textbf{return: Compress} \\
Get the bitmask of all supported compression algorithms. currently only \textbf{Compress::NONE} and \textbf{Compress::LZ4}.
\item[get\_compression()] \textbf{return: Compress} \\
Get the current compression used.
\item [set\_compression] \textbf{const Compress compression} \\
\textbf{return: bool}\\
Try to set a compression algorithm. LZ4 is not a mandatory dependency, so we might not have it
\end{description}
\newpage
\subsubsection{Thread pool}
Both the encoder and the decoder can work with multiple blocks at the same time, so it makes sense to have a thread pool for such work.
\begin{description}
\item[set\_thread\_pool] \textbf{Input: const size\_t threads}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint16\_t max\_block\_concurrency}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const RaptorQ\_\_v1::Work\_State exit\_type}\\
\textbf{return: bool}\\
set a pool of a certain number of threads. But the decoder is special: if one decoding fails we can always try again once we have at least one other symbol. The second parameter tells the pool how many times we can try to decode the same block concurrently. $1$ is a safe option.\\
The final argument is used when downsizing the queue: what do we do if all the threads are running but you asked to have less threads?
\begin{lstlisting}
enum class Work_State : uint8_t {
KEEP_WORKING
ABORT_COMPUTATION
};
\end{lstlisting}
\end{description}
\newpage
\subsubsection{The Encoder}
\index{Encoder!C++}
The constructor is the following:
\begin{lstlisting}[language=C++]
Encoder (const Rnd_It data_from, const Rnd_It data_to,
const uint16_t min_subsymbol_size,
const uint16_t symbol_size,
const size_t max_sub_block);
\end{lstlisting}
As we said, the RFC will decide by itself how many blocks each input will have, the actual size of the subsymbol, and the size of the blocks. Although needed for RFC compliance, you probably do not care about the \textit{min\_subsymbol\_size}, in which case the safe choice is to put it at the same size of the symbol.\\
The \textit{max\_sub\_block} the the maximum size of a sub-block in bytes. Again, unless you \textit{really} understand the RFC, you should probably ignore this and put it to a high value. This parameter is used to limit the block size used by the RFC, and is the size (in bytes) of the biggest block you allow the RFC to use.\\
\textbf{safe settings for max\_sub\_block:} sub\_symbol\_size * block\_size.
You can instantiate an encoder for example by doing:
\begin{lstlisting}[language=C++]
std::vector<uint32_t> input, output;
...
using T_it = typename std::vector<uint32_t>::iterator;
RFC6330::Encoder<T_it, T_it> enc (input.begin(),
input.end(),
4, 1444, 10000)
\end{lstlisting}
This will create an Encoder that works on vectors of unsigned 32 bit integers for both input and output, that will create symbols of size 1444 bytes, interleaving
your input every 4 bytes, and try to work with a big number of symbols per blocks.
The available methods for the encoder are the following:
\begin{description}
\item[operator bool()] \textbf{return:bool}\\
False if constructor parameters did not make sense. Else true.
\item[OTI\_Common()] \textbf{return: OTI\_Common\_Data}, aka \textit{uint64\_t}.\\
Keeps total \textbf{file size and symbol size}. You need to send this to the receiver, so that it will be able to properly decode the data.
\item[OTI\_Scheme\_Specific\_Data()] \textbf{return: OTI\_Scheme\_Specific\_Data}, aka \textit{uint32\_t}.\\
Keeps number of \textbf{source blocks, sub blocks, and alignment}. As for the OTI\_Common\_Data, you need to send this to the receiver to be able to
properly decode the data.
\item[compute] \textbf{Input: const Compute flags}\\
\textbf{return: std::future<std::pair<Error, uint8\_t> >}\\
For C++11 only (automatically disabled on C++98). Start the computation, return a future, which has a pair of Error and the number of blocks ready.\\
Compute flags:
\begin{lstlisting}[language=C++]
enum class Compute : uint8_t {
NONE
// report every time there is more data, but only
// if that data starts at the beginning.
PARTIAL_FROM_BEGINNING
PARTIAL_ANY
COMPLETE // only when all the data is available
NO_BACKGROUND // only return after the computation is finished
NO_POOL // do not use the thread pool
NO_RETRY // do not retry if we failed, even if there is more data
};
\end{lstlisting}
\item [precompute\_max\_memory] \textbf{return: size\_t}\\
Each precomputation can take a lot of memory, depending on the configuration, so you might want to limit the number of precomputations run in parallel
depending on the memory used. This method returns the amount of memory taken by \textbf{ONE} precomputation.
\item[encode] \textbf{Input: Fwd\_It \&output, const Fwd\_It end, const uint32\_t esi, const uint8\_t sbn}.\\
\textbf{return:size\_t}.\\
Take as input the iterators to the data structure into where we have to save the encoded data, the \textbf{Encoding Symbol Id} and the
\textbf{Source Block Number}. As you are writing in C++, you probably want to use the iterators begin/end, though. Returns the number of written
iterators (\textbf{NOT} the bytes)
\item[encode] \textbf{Input: Fwd\_It \&output, const Fwd\_It end, const uint32\_t id}.\\
\textbf{return:size\_t}.\\
Exactly as before, but the \textbf{id} contains both the \textit{source block number} and the \textit{encoding symbol id}
\item[begin()] \textbf{return: Block\_Iterator<Rnd\_It, Fwd\_It>}\\
This returns an iterator to the blocks in which the RFC divided the input data. See later to understand how to use it.
\item[end()] \textbf{return: const Block\_Iterator<Rnd\_It, Fwd\_It>}\\
This returns an iterator to the end of the blocks in which the RFC divided the input data. See later to understand how to use it.
\item [free] \textbf{Input: const uint8\_t sbn}\\
\textbf{return: void}\\
Each block takes some memory, (a bit more than $symbols * symbol\_size$), so once you are done sending source and repair symbols for one block,
you might want to free the memory of that block.
\item[blocks()] \textbf{return: uint8\_t} The number of blocks.
\item[block\_size()] \textbf{Input: const uint8\_t sbn}\\
\textbf{return: uint32\_t}\\
The block size, in bytes. Each block can have different symbols and thus different size.
\item[symbol\_size()] \textbf{return: uint16\_t} The size of a symbol.
\item[symbols] \textbf{Input:uint8\_t sbn}\\
\textbf{return: uint16\_t}\\
The number of symbols in a specific block. different blocks can have different symbols.
\item[max\_repair] \textbf{Input: const uint8\_t sbn)}\\
\textbf{return: uint32\_t}\\
The maximum amount of repair symbols that you can generate. Something less than $2^{24}$, but the exact number depends on the number of symbols
in a block
\end{description}
\subsubsection{Blocks}
\index{Blocks!C++}
With the \textit{begin()/end()} calls you get \textit{Input iterators} to the blocks. A Block has the following type:
\begin{lstlisting}[language=C++]
template <typename Rnd_It, typename Fwd_It>
class Block
\end{lstlisting}
and exposes the following methods:
\begin{description}
\item[begin\_source()]\textbf{return: Symbol\_Iterator}
\item[end\_source()]\textbf{return: Symbol\_Iterator}
\item[begin\_repair()]\textbf{return: Symbol\_Iterator}
\item[end\_repair()]\textbf{Input: const uint32\_t max\_repair}\\
\textbf{return: Symbol\_Iterator}
\item[id()]\textbf{return: uint8\_t}
\item[max\_repair()]\textbf{return: uint32\_t}
\item[symbols()]\textbf{return: uint16\_t}
\item[block\_size()]\textbf{return: uint32\_t}
\end{description}
As the names explain, you will get an iterator to the symbols in the block. As the number of repair symbols can vary, for now you get two separate begin/ends,
so that you can check when you sent the source symbols, and how many repair symbols you send.\\
The other functions are helpers for the details of the block.
\subsubsection{Symbols}
\index{Symbols!C++}
Finally, through the \textit{Symbol\_Iterator} \textit{Input Iterator} we get the \textbf{Symbol} class:
\begin{lstlisting}[language=C++]
template <typename Rnd_It, typename Fwd_It>
class Symbol
\end{lstlisting}
which exposes the following methods we need to get the symbol data:
\begin{description}
\item[operator()]\textbf{Input:Fwd\_It \&start, const Fwd\_It end}\\
\textbf{return: uint64\_t}\\
takes a forward iterator, and fill it with the symbol data. returns the number of written iterators.
\item[id()]\textbf{return: uint32\_t}\\
return the id (\textit{$sbn + esi$}) of this symbol, that you need to include in every packet you send, before the symbols.
\item[block()]\textbf{return: uint8\_t}\\
return the \textit{block} of this symbol.
\item[esi()]\textbf{return: uint32\_t}\\
return the \textit{esi} of this symbol.
\end{description}
\subsubsection{The Decoder}
\index{Decoder!C++}
The decoder is a bit simpler than the encoder.
There are two constructors for the Decoder:
\begin{lstlisting}[language=C++]
std::vector<uint32_t> input, output;
using T_it = typename std::vector<uint32_t>::iterator;
RaptorQ::Decoder<T_it, T_it> dec (
const OTI_Common_Data common,
const OTI_Scheme_Specific_Data scheme)
RaptorQ::Decoder<T_it, T_it> dec (uint64_t size,
uint16_t symbol_size,
uint16_t sub_blocks,
uint8_t blocks)
\end{lstlisting}
Which should be pretty self-explanatory, once you understand how the encoder works:
you can either get the \texttt{OTI} parameters from the Encoder or you can provide the raw values by yourself (only if you know what you are doing)
The remaining methods are:
\begin{description}
\item[begin()] \textbf{return: Block\_Iterator<In\_It, Fwd\_It>}\\
This returns an iterator to the blocks in which the RFC divided the input data.
\item[end()] \textbf{return: const Block\_Iterator<In\_It, Fwd\_It>}\\
This returns an iterator to the end of the blocks in which the RFC divided the input data.
\item[operator bool()] \textbf{return: bool}\\
check if the Decoder was initialized properly
\item[compute] \textbf{Input: const Compute flags}\\
\textbf{return: std::future<std::pair<Error, uint8\_t> >}\\
Only enabled if you use C++11. Start the computation as soon as enough data is available.\\
Compute flags:
\begin{lstlisting}[language=C++]
enum class Compute : uint8_t {
NONE
// report every time there is more data, but only
// if that data starts at the beginning.
PARTIAL_FROM_BEGINNING
PARTIAL_ANY
COMPLETE // only when all the data is available
NO_BACKGROUND // only return after the computation is finished
NO_POOL // do not use the thread pool
NO_RETRY // do not retry if we failed, even if there is more data
};
\end{lstlisting}
\item[end\_of\_input] \textbf{Input:const uint8\_t block}\\
\textbf{return: void}\\
Tell the decoder that we know that there will be no more data for this block. This enables the decoder to return error earlier instead of waiting forever for new data.
\item[end\_of\_input()] \textbf{return: void}\\
Same as before, but we know that there will be no more inputs for any block.
\item[decode\_symbol]\textbf{Input: Fwd\_It \&start}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const Fwd\_It end}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint16\_t esi}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}
\textbf{return: uint64\_t}\\
Decode a single symbol. you need to provide the block number and symbol identifier.
\item[decode\_bytes] \textbf{Input: Fwd\_It \&start}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const Fwd\_It end}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
\textbf{return: uint64\_t}\\
Decode everything. returns the number of bytes written. You can start writing the output \texttt{skip} bytes after the first iterator in case the parameters you have used do not align (set to $0$ for everyone else).
\item[decode\_bytes] \textbf{Input: Fwd\_It \&start}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const Fwd\_It end}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: uint64\_t}\\
Same as before, but you can specify a \textbf{Single Block Number} instead of the whole output
\item[decode\_aligned]\textbf{Input: Fwd\_It \&start}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const Fwd\_It end}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
\textbf{return: aligned\_res}\\
Same as \texttt{decode\_bytes}, but yu can use this if for some weir reason the data does not align with the type of the output
\begin{lstlisting}[language=C++]
struct aligned_res
{
uint64_t written; // iterators written
uint8_t offset; // bytes written in the last
// iterator if it was not full
};
\end{lstlisting}
\item[decode\_block\_aligned]\textbf{Input: Fwd\_It \&start}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const Fwd\_It end}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: aligned\_res}\\
Same as before, but now you can choose the block
\item[add\_symbol]\textbf{Input: In\_It \&start}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const In\_It end}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t esi}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: RFC6330::Error}\\
Add one symbol, while explicitly specifying the symbol id and the block id.
\item[add\_symbol]\textbf{Input: In\_It \&start}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const In\_It end}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t id}\\
\textbf{return: RFC6330::Error}\\
Same as before, but extract the block id and the symbol id from the \textit{id} parameter
\item[blocks\_ready()]\textbf{return: uint8\_t}\\
return the number of the blocks that are ready for output
\item[is\_ready()]\textbf{return: bool}\\
Whether everything has been decoded or not.
\item[is\_block\_ready]\textbf{Input:const uint8\_t block}\\
\textbf{return: bool}\\
Test if the specified block has been decoded or not
\item[free]\textbf{Input: const uint8\_t sbn}\\
\textbf{return: void}\\
You might have stopped using a block, but the memory is still there. Free it.
\item[bytes()] \textbf{return: uint64\_t}\\
The total bytes of the output
\item[blocks()] \textbf{return: uint8\_t}\\
The number of blocks.
\item[block\_size()] \textbf{Input: const uint8\_t sbn}\\
\textbf{return: uint32\_t}\\
The block size, in bytes. Each block can have different symbols and thus different size.
\item[symbol\_size()] \textbf{return: uint16\_t} The size of a symbol.
\item[symbols] \textbf{Input:uint8\_t sbn}\\
\textbf{return: uint16\_t}\\
The number of symbols in a specific block. different blocks can have different symbols.
\end{description}
\newpage
\subsection{C interface}\index{Interface!C}
The C interface looks a lot like the C++ one.\\
You need to include the \textbf{RaptorQ/RFC6330.h} header, and link the \textit{libRaptorQ} library.\\
\marginlabel{Static linking}\index{Static Linking}
If you are working with the static version of libRaptorQ remember to link the C++ standard library used when
compiling the library (\textit{libstdc++} for gcc or maybe \textit{libc++} for clang), your threding library (usually \textit{libpthread}), and the C math library (\textit{libm}).\\
\marginlabel{\textbf{API versioning}} To better support future changes in the API and to help you with future changes,
there are only 2 API calls in this library:
\begin{description}
\item[RFC6330\_api] \textbf{Input: uint32\_t version}\\
\textbf{return: struct RFC6330\_base\_api*}\\
This will give you a pointer to a struct containing pointers to the calls you will use.
The struct will change depending on which API you request (currently only number $1$ is supported).
Since this pointer works for every api, you have to cast it to the struct you expect, or you will not see
the pointers to the function calls. Then you can use that pointer to access of the functions, like:
\begin{lstlisting}[language=C]
struct RFC6330_v1 *rfc = (struct RFC6330_v1*)
RFC6330_api (1);
rfc->set_compression (RQ_COMPRESS_LZ4);
\end{lstlisting}
\item[RFC6330\_free\_api] \textbf{Input:struct RFC6330\_base\_api **api}\\
\textbf{return: void}\\
As the name implies, this frees the given structure.
\end{description}
Again, we only support API version 1 at the moment.
\index{Cache!C}
\marginlabel{\textbf{Cache settings}}
As for the C++11 interface, you can get and set the local memory cache.
\begin{description}
\item[supported\_compressions] \textbf{return: RFC6330\_Compress}\\
return the bitmask of all supported compressions. currently either \texttt{RQ\_COMPRESS\_NONE} or \texttt{RQ\_COMPRESS\_LZ4}
\item[get\_compression] \textbf{return: RFC6330\_Compress}\\
Which compression are we currently using?
\item[set\_compression] \textbf{Input: const RFC6330\_Compress compression}\\
\textbf{return: bool}\\
Set a compression method or another.
\item[local\_cache\_size] \textbf{Input: const size\_t bytes}\\
\textbf{return: size\_t}\\
Set the maximum amount of cache usable. Default: $0$
\item[get\_local\_cache\_size] \textbf{return: size\_t}\\
get the amount of cache configured
\end{description}
\marginlabel{C Constructors}
The first thing you need is to allocate the encoder or the decoder.
The C interface is just a wrapper around the C++ code, so you still have to specify the same things as before.\\
A quick glance at the constructors should give you all the information you need:
\begin{lstlisting}[language=C]
typedef enum { RQ_NONE, RQ_ENC_8, RQ_ENC_16,
RQ_ENC_32, RQ_ENC_64, RQ_DEC_8,
RQ_DEC_16, RQ_DEC_32, RQ_DEC_64}
RFC6330_type;
\end{lstlisting}
\begin{description}
\item[Encoder] \textbf{Input:const RFC6330\_type type}\\
.\ \ \ \ \ \ \ \ \ \textbf{void *data\_from}\\
.\ \ \ \ \ \ \ \ \ \textbf{const uint64\_t size}\\
.\ \ \ \ \ \ \ \ \ \textbf{const uint16\_t min\_subsymbol\_size}\\
.\ \ \ \ \ \ \ \ \ \textbf{const uint16\_t symbol\_size}\\
.\ \ \ \ \ \ \ \ \ \textbf{const size\_t max\_sub\_block}\\
\textbf{return: RFC6330\_ptr*}\\
Allocate an encoder. The encoder will work with uint8\_t, uint16\_t, uint32\_t or uint64\_t depending on which \texttt{RFC6330\_type} you choose. The best bet is usually to work with uint8\_t
\item[Decoder] \textbf{Input:const RFC6330\_type type}\\
.\ \ \textbf{const RFC6330\_OTI\_Common\_Data common}\\
.\ \ \textbf{const RFC6330\_OTI\_Scheme\_Specific\_Data scheme}\\
\textbf{return: RFC6330\_ptr*}\\
The \texttt{type} parameter works the same as in the encoder. The other two are parameters you get from the encoder.
\item[Decoder\_raw] \textbf{Input: RFC6330\_type type}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint64\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint16\_t symbol\_size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint16\_t sub\_blocks}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t blocks}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t alignment}\\
\textbf{return: struct RFC6330\_ptr*}\\
Same as before, but here you can specify the parameters by hand.
\item[initialized]\textbf{Input: const struct RFC6330\_ptr *ptr}\\
\textbf{return: bool}\\
check if the encoder or decoder was initialized properly.
\end{description}
\newpage
\subsubsection{Common functions for (de/en)coding}
These functions are used by both the encoder and the decoder, and will be helpful in tracking how much memory
you will need to allocate, or in general in managing the encoder and decoder.
The \textbf{ptr} must be a valid encoder or decoder.
The names for now are self-explanatory. Blocks can have different symbols, so the size of a block and the number of symbols in a block
depend on which block we are talking about.
\marginlabel{\textbf{symbols, blocks, memory}}\\
\begin{description}
\item[set\_thread\_pool] \textbf{Input: const size\_t threads}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint16\_t max\_block\_concurrency}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const RFC6330\_Work exit\_type}\\
\textbf{return: bool}\\
Set the size of the thread pool for concurrent work. Since the decoder can fail, but also retry again if there is more data available,
you can also specify how many times libRaptorQ will try to decode the same block concurrently. $1$ is a safe option.\\
The last parameter, \texttt{RFC6330\_Work} specify what to do when you are downsizing the thread pool and some threads are still working. The possible values are \texttt{RQ\_WORK\_KEEP\_WORKING} and \texttt{RQ\_WORK\_ABORT\_COMPUTATION}.
\item[blocks] \textbf{Input: const struct RFC6330\_ptr *ptr}\\
\textbf{return: uint8\_t}\\
The number of blocks in this RFC6330 instance
\item[symbols]\textbf{Input: const struct RFC6330\_ptr *ptr}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: uint16\_t}\\
The number of symbols in the specified block
\item[symbol\_size]\textbf{Input:const struct RFC6330\_ptr *ptr}\\
\textbf{return: size\_t}\\
The size of each symbol
\item[free\_block]\textbf{Input: struct RFC6330\_ptr **ptr}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: void}\\
Free the allocated space for a single block
\item[free]\textbf{Input: struct RFC6330\_ptr **ptr}\\
\textbf{return: void}\\
Free the specified decoder or decoder and all its blocks.
\end{description}
\newpage
\marginlabel{Computation}\label{computation}\\
\begin{description}
\item[compute] \textbf{Input: const struct RFC6330\_ptr *ptr}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const RFC6330\_Compute flags}\\
\textbf{return: RFC6330\_future*}\\
Start the computation as described in the flags. Returns a wrapper to the C++11 futures. You can wait or poll the state of the future in different ways (see right below)\\
\begin{lstlisting}[language=C]
typedef enum {
RQ_COMPUTE_NONE
// report every time there is more data, but only
// if that data starts at the beginning.
RQ_COMPUTE_PARTIAL_FROM_BEGINNING
RQ_COMPUTE_PARTIAL_ANY
RQ_COMPUTE_COMPLETE // only when all the data
// is available
RQ_COMPUTE_NO_BACKGROUND // only return after
// the computation is finished
RQ_COMPUTE_NO_POOL // do not use the thread pool
RQ_COMPUTE_NO_RETRY // do not retry if we failed,
// even if there is more data
} RFC6330_Compute;
\end{lstlisting}
\item[future\_state] \textbf{Input: const struct RFC6330\_future *f}\\
\textbf{return: RFC6330\_Error}\\
poll the state of the future. possible results:
\begin{lstlisting}[language=C]
RQ_ERR_WRONG_INPUT // null pointer?
RQ_ERR_NOT_NEEDED // you have already run
// future_get() on this future
RQ_ERR_WORKING // still working on it
RQ_ERR_NONE // ready to run future_get()
\end{lstlisting}
\item[future\_wait\_for] \textbf{Input: const struct RFC6330\_future *f}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint64\_t time}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const RFC6330\_Unit\_Time unit}\\
\textbf{return: RFC6330\_Error}\\
Wait for a future to become ready for X amount of time. the unit is specified in the
last parameter:
\begin{lstlisting}[language=C]
typedef enum {
RQ_TIME_NANOSEC,
RQ_TIME_MICROSEC,
RQ_TIME_MILLISEC,
RQ_TIME_SEC,
RQ_TIME_MIN,
RQ_TIME_HOUR
} RFC6330_Unit_Time;
\end{lstlisting}
\item[future\_wait] \textbf{Input: const struct RFC6330\_future *f}\\
\textbf{return: void}\\
Same as before, but wait indefinitely
\item[future\_get] \textbf{Input: struct RFC6330\_future *future}\\
\textbf{return: struct RFC6330\_Result}\\
Returns the state of the future. If the future is not ready it will wait indefinitely.
\begin{lstlisting}[language=C]
struct RAPTORQ_API RFC6330_Result {
RFC6330_Error error;
uint8_t sbn;
};
\end{lstlisting}
The sbn changes meaning depending to be consistent with the flags you passed to the \texttt{compute()} call.
\item[future\_free] \textbf{Input: struct RFC6330\_future **f}\\
\textbf{return: void}\\
Free the memory allocated for the future.
\end{description}
\subsubsection{\textbf{Encoding}}
\index{Encoder!C}
Now we will look at the calls specific to the encoder (that is: calls that need an encoder as the first parameter, and don't make sense in a decoder)
\marginlabel{OTI Data}\\
First, we need to tell the receiver all the parameters that the encoder is using, and for that two functions are provided:
\begin{lstlisting}[language=C]
typedef uint64_t RaptorQ_OTI_Common_Data;
typedef uint32_t RaptorQ_OTI_Scheme_Specific_Data;
\end{lstlisting}
\begin{description}
\item[OTI\_Common]\textbf{Input: struct RaptorQ\_ptr *enc}\\
\textbf{return: RFC6330\_OTI\_Common\_Data}\\
Get the OTI\_Common
\item[OTI\_Scheme\_Specific]\textbf{Input: struct RaptorQ\_ptr *enc}\\
\textbf{return: RFC6330\_OTI\_Scheme\_Specific\_Data}\\
Get the OTI\_Scheme\_Specific
\end{description}
\marginlabel{Encoding}
\begin{description}
\item[max\_repair]\textbf{Input: const struct RFC6330\_ptr *enc}\\
.\ \ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: uint32\_t}\\
return the max number of repair packets that block can have. This is around $2^{24}$, so you probably always want to be much, much lower than this. The total number of symbols (source+repair) is limited in the RFC, and since the bigger blocks have more source symbols, the max number of repair symbols has to be lower in bigger blocks. Again, this is always in the ballpark of $2^{24}$, you probably don't want to use this many repair symbols.
\item[precompute\_max\_memory]\textbf{Input: const struct RFC6330\_ptr *enc}\\
\textbf{return: size\_t}\\
Get an estimate of how much memory (bytes) will cost the encoding of a single block. Not 100\% accurate, but close enough.
\item[encode\_id]\textbf{Input: const struct RFC6330\_ptr *enc}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const size\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t id}\\
\textbf{return: size\_t}\\
Get one encoded symbol, and store it in \texttt{**data}, which holds a pointer to "\texttt{size}" elements of type uint8\_t, uint16\_t, uint32\_t or uint64\_t depending on how the encoder was initialized. See \texttt{RFC6330\_type} in the encoder initialization. Returns the number of elements written.\\
If you request repair symbols before the computation is finished, the call will block until the data is available. This calls works for both source and repair symbols, just increase the id until you finish the source symbols
\item[encode]\textbf{Input: const struct RFC6330\_ptr *enc}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const size\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t esi}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: size\_t}\\
Same as before, but you can specify the symbol and block explicitly.
\item[id]\textbf{Input: const uint32\_t esi}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: uint32\_t}\\
combine the esi and the block number to form an id.
\end{description}
\newpage
\subsubsection{\textbf{Decoding}}
As for the encoder, there are functions which are specific for a decoder. Let's look at them
\marginlabel{General status calls}
\begin{description}
\item[bytes]\textbf{Input: const struct RFC6330\_ptr *dec}\\
\textbf{return: uint64\_t}\\
Return the number of bytes that this decoder should output on complete, successful decoding.
\item[blocks\_ready]\textbf{Input: const struct RFC6330\_ptr *dec}\\
\textbf{return: uint8\_t}\\
Return the number of blocks ready to be returned. Useful if you don't want to wait for the whole data.\\
The number of blocks reported can mean either the number of sequential blocks ready, or the number
of blocks regardless of order, depending on how the \texttt{compute} function was called (see "\texttt{Computation}" on \ref{computation})
\item[is\_ready]\textbf{Input: const struct RFC6330\_ptr *dec}\\
\textbf{return: bool}\\
Test if the whole encoder is ready and all data decoded.
\item[is\_block\_ready]\textbf{Input: const struct RFC6330\_ptr *dec}\\
\.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t block}\\
\textbf{return: bool}\\
Test if a single block is ready and its data decoded.
\end{description}
\index{Decoder!C}\marginlabel{Decoding calls}
\begin{description}
\item[end\_of\_input]\textbf{Input: const struct RFC6330\_ptr *dec}\\
\textbf{return: void}\\
Tell the decoder that there will be no more input for this decoder. This way the decoder can stop waiting for more data and return error immediately
\item[end\_of\_block\_input]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t block}\\
\textbf{return: void}\\
Tell the decoder that there will be no more input for this block. This way the decoder can stop waiting for more data and return error immediately
\item[add\_symbol\_id]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uin32\_t id}\\
\textbf{return: RFC6330\_Error}\\
Add a symbol to the decoder. The \texttt{void **data} will be cast to the correct type as specified in the decoder construction (RQ\_DEC\_8, RQ\_DEC\_16 etc..). Afterwards data will point \textbf{after} the symbol.
\item[add\_symbol\_id]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uin32\_t esi}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uin8\_t sbn}\\
\textbf{return: RFC6330\_Error}\\
Same as with \texttt{add\_symbol\_id}, but now you can specify the esi and the block number manually
\item[decode\_aligned]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
\textbf{return: RFC6330\_Dec\_Result}\\
Decode everything as asked by the \texttt{compute()} call (see "\texttt{Computation}" on \ref{computation}).\\
The \texttt{void **data} will be cast to the correct type as specified in the decoder construction (\texttt{RQ\_DEC\_8}, \texttt{RQ\_DEC\_16} etc..). Afterwards data will point \textbf{after} the decoded data. You can skip "skip" bytes at the beginning of **data if the pointer
is not aligned with your data.
\begin{lstlisting}[language=C]
struct RAPTORQ_API RFC6330_Dec_Result {
uint64_t written;
uint8_t skip;
};
\end{lstlisting}
The result is the number of written \textbf{elements} (size depending on \texttt{RQ\_DEC\_8}, \texttt{RQ\_DEC\_16} etc).\\
The \texttt{skip} parameter is the amount of bytes written in the last element if the alignment used in the encoder does not fit the
alignment used in the decoder. Usually you keep those synchronized, so it should be zero (element fully written)
\item[decode\_block\_aligned]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t block}\\
\textbf{return: RFC6330\_Dec\_Result}\\
Same as before, but now you can decode a single block.
\newpage
\item[decode\_symbol]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t esi}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t sbn}\\
\textbf{return: uint64\_t}\\
As you can expect, decode a single symbol. The \texttt{void **data} will be cast to the correct type as specified in the decoder construction (\texttt{RQ\_DEC\_8}, \texttt{RQ\_DEC\_16} etc..). Afterwards data will point \textbf{after} the decoded data.\\
Returns the number of bytes written
\item[decode\_bytes]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\
\textbf{return: uint64\_t}\\
Decode everything as asked by the \texttt{compute()} call (see "\texttt{Computation}" on \ref{computation}).\\
The \texttt{void **data} will be cast to the correct type as specified in the decoder construction (\texttt{RQ\_DEC\_8}, \texttt{RQ\_DEC\_16} etc..). Afterwards data will point \textbf{after} the decoded data. You can skip "skip" bytes at the beginning of **data if the pointer is not aligned with your data.\\
Returns the number of written bytes.
\item[decode\_block\_bytes]\textbf{Input: const struct RFC6330\_ptr *dec}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const void **data}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint32\_t size}\\
.\ \ \ \ \ \ \ \ \ \ \textbf{const uint8\_t skip}\\