libpdraw-sys 7.5.0

Rust wrappers over Parrot's libpdraw library
Documentation
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
/**
 * @file libpomp.h
 *
 * @brief Printf Oriented Message Protocol.
 *
 * @author yves-marie.morgan@parrot.com
 *
 * Copyright (c) 2014 Parrot S.A.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the Parrot Company nor the
 *     names of its contributors may be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE PARROT COMPANY BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef _LIBPOMP_H_
#define _LIBPOMP_H_

#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/** Wrapper for gcc printf attribute */
#ifndef POMP_ATTRIBUTE_FORMAT_PRINTF
#  if defined(__GNUC__) && defined(__MINGW32__) && !defined(__clang__)
#    define POMP_ATTRIBUTE_FORMAT_PRINTF(_x, _y) \
		__attribute__((__format__(__gnu_printf__, _x, _y)))
#  elif defined(__GNUC__)
#    define POMP_ATTRIBUTE_FORMAT_PRINTF(_x, _y) \
		__attribute__((__format__(__printf__, _x, _y)))
#  else
#    define POMP_ATTRIBUTE_FORMAT_PRINTF(_x, _y)
#  endif
#endif /* !POMP_ATTRIBUTE_FORMAT_PRINTF */

/** Wrapper for gcc scanf attribute */
#ifndef POMP_ATTRIBUTE_FORMAT_SCANF
#  if defined(__GNUC__) && defined(__MINGW32__) && !defined(__clang__)
#    define POMP_ATTRIBUTE_FORMAT_SCANF(_x, _y) \
		__attribute__((__format__(__gnu_scanf__, _x, _y)))
#  elif defined(__GNUC__)
#    define POMP_ATTRIBUTE_FORMAT_SCANF(_x, _y) \
		__attribute__((__format__(__scanf__, _x, _y)))
#  else
#    define POMP_ATTRIBUTE_FORMAT_SCANF(_x, _y)
#  endif
#endif /* !POMP_ATTRIBUTE_FORMAT_SCANF */

/** To be used for all public API */
#ifdef POMP_API_EXPORTS
#  ifdef _WIN32
#    define POMP_API	__declspec(dllexport)
#  else /* !_WIN32 */
#    define POMP_API	__attribute__((visibility("default")))
#  endif /* !_WIN32 */
#else /* !POMP_API_EXPORTS */
#  define POMP_API
#endif /* !POMP_API_EXPORTS */

/* Forward declarations */
struct sockaddr;
struct pomp_ctx;
struct pomp_conn;
struct pomp_buffer;
struct pomp_msg;
struct pomp_loop;
struct pomp_evt;
struct pomp_timer;

#ifdef __PYBINDING_MACRO__
/* python binding requires the size of sockaddr_storage for memory allocation.*/
#include <sys/socket.h>
struct pomp_sockaddr_storage {
	char __data[sizeof(struct sockaddr_storage)];
};
#endif


/** Context event */
enum pomp_event {
	POMP_EVENT_CONNECTED = 0,	/**< Peer is connected */
	POMP_EVENT_DISCONNECTED,	/**< Peer is disconnected */
	POMP_EVENT_MSG,			/**< Message received from peer */
};

/**
 * Get the string description of a context event.
 * @param event : event to convert.
 * @return string description of the context event.
 */
POMP_API const char *pomp_event_str(enum pomp_event event);

/** Fd events */
enum pomp_fd_event {
	POMP_FD_EVENT_IN = 0x001,
	POMP_FD_EVENT_PRI = 0x002,
	POMP_FD_EVENT_OUT = 0x004,
	POMP_FD_EVENT_ERR = 0x008,
	POMP_FD_EVENT_HUP = 0x010,
};

/** Socket kind */
enum pomp_socket_kind {
	POMP_SOCKET_KIND_SERVER,	/**< Server socket */
	POMP_SOCKET_KIND_PEER,		/**< Peer (accepted) socket */
	POMP_SOCKET_KIND_CLIENT,	/**< Client socket */
	POMP_SOCKET_KIND_DGRAM,		/**< Dgram socket */
};

/**
 * Get the string description of a socket kind.
 * @param kind : socket kind to convert.
 * @return string description of the socket kind.
 */
POMP_API const char *pomp_socket_kind_str(enum pomp_socket_kind kind);

/** Send status flags */
enum pomp_send_status {
	POMP_SEND_STATUS_OK = 0x01,		/**< Send is OK */
	POMP_SEND_STATUS_ERROR = 0x02,		/**< Error during send */
	POMP_SEND_STATUS_ABORTED = 0x04,	/**< Send aborted */
	POMP_SEND_STATUS_QUEUE_EMPTY = 0x08,	/**< No more buffer in queue */
};

/** Peer credentials for local sockets */
struct pomp_cred {
	uint32_t	pid;	/**< PID of sending process */
	uint32_t	uid;	/**< UID of sending process */
	uint32_t	gid;	/**< GID of sending process */
};

/**
 * Context event callback prototype.
 * @param ctx : context.
 * @param event : event that occurred.
 * @param conn : connection on which the event occurred.
 * @param msg : received message when event is POMP_EVENT_MSG.
 * @param userdata : user data given in pomp_ctx_new.
 */
typedef void (*pomp_event_cb_t)(
		struct pomp_ctx *ctx,
		enum pomp_event event,
		struct pomp_conn *conn,
		const struct pomp_msg *msg,
		void *userdata);

/**
 * Context raw data reception callback prototype.
 * @param ctx : context.
 * @param conn : connection on which the event occurred.
 * @param buf : received data.
 * @param userdata : user data given in pomp_ctx_new.
 */
typedef void (*pomp_ctx_raw_cb_t)(
		struct pomp_ctx *ctx,
		struct pomp_conn *conn,
		struct pomp_buffer *buf,
		void *userdata);

/**
 * Context socket callback. If set, will be called after socket is created.
 * @param ctx : context.
 * @param fd : socket fd.
 * @param kind : socket kind.
 * @param userdata : user data given in pomp_ctx_new.
 */
typedef void (*pomp_socket_cb_t)(
		struct pomp_ctx *ctx,
		int fd,
		enum pomp_socket_kind kind,
		void *userdata);

/**
 * Send callback. If set, it is called to indicate that the given buffer has
 * been sent (or not).
 * @param ctx : context.
 * @param conn : connection on which the event occurred.
 * @param buf : buffer whose send status id notified. If in raw mode is it the
 * one given in send operation, otherwise it is the internal buffer associated
 * with the message sent.
 * @param status : set of flags (enum pomp_send_status) indicating the status.
 * one of OK, ERROR or ABORTED is always set. QUEUE_EMPTY indicates that there
 * is no more buffer queued internally.
 * @param cookie : NULL, reserved for future use.
 * @param userdata : user data given in pomp_ctx_new.
 *
 */
typedef void (*pomp_send_cb_t)(
		struct pomp_ctx *ctx,
		struct pomp_conn *conn,
		struct pomp_buffer *buf,
		uint32_t status,
		void *cookie,
		void *userdata);

/**
 * Fd event callback.
 * @param fd : triggered fd.
 * @param revents : event that occurred.
 * @param userdata : callback user data.
 */
typedef void (*pomp_fd_event_cb_t)(int fd, uint32_t revents, void *userdata);

/**
 * pomp_evt event callback.
 * @note The event will be cleared automatically before calling this.
 * @param evt : triggered event.
 * @param userdata : callback user data.
 */
typedef void (*pomp_evt_cb_t)(struct pomp_evt *evt, void *userdata);

/**
 * Timer callback
 * @param timer : timer.
 * @param userdata : callback user data.
 */
typedef void (*pomp_timer_cb_t) (struct pomp_timer *timer, void *userdata);

/**
 * Idle callback.
 * @param userdata : callback user data.
 */
typedef void (*pomp_idle_cb_t)(void *userdata);

/**
 * Watchdog callback
 * @param loop: associated loop.
 * @param userdata : callback user data.
 */
typedef void (*pomp_watchdog_cb_t)(struct pomp_loop *loop, void *userdata);

/*
 * Context API.
 */

/**
 * Create a new context structure.
 * @param cb : function to be called when connection/disconnection/message
 * events occur.
 * @param userdata : user data to give in cb.
 * @return context structure or NULL in case of error.
 */
POMP_API struct pomp_ctx *pomp_ctx_new(pomp_event_cb_t cb, void *userdata);

/**
 * Create a new context structure in an existing loop.
 * @param cb : function to be called when connection/disconnection/message
 * events occur.
 * @param userdata : user data to give in cb.
 * @param loop: loop to use.
 * @return context structure or NULL in case of error.
 */
POMP_API struct pomp_ctx *pomp_ctx_new_with_loop(pomp_event_cb_t cb,
		void *userdata, struct pomp_loop *loop);

/**
 * Mark the context as raw. Internal message protocol serialization will not
 * be used, only raw data can be sent/received. Connection/Disconnection
 * events will be notified with the generic context event callback.
 * message API.
 * @param ctx : context.
 * @param cb : function to call when data has been received. The userdata
 * argument will be the same as the one set when creating the context.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_set_raw(struct pomp_ctx *ctx, pomp_ctx_raw_cb_t cb);

/**
 * Set the function to call when socket fd are created. This allows application
 * to configure socket before it is used.
 * @param ctx : context.
 * @param cb : function to call when socket are created. The userdata
 * argument will be the same as the one set when creating the context.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_set_socket_cb(struct pomp_ctx *ctx, pomp_socket_cb_t cb);

/**
 * Set the function to call when send operations are completed. This allows
 * application to be notified of actual completion in case operations are
 * internally queued.
 * @param ctx : context.
 * @param cb : function to call when send operations are completed. The userdata
 * argument will be the same as the one set when creating the context.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_set_send_cb(struct pomp_ctx *ctx, pomp_send_cb_t cb);

/**
 * Setup TCP keepalive. Settings will be applied to all future TCP connections.
 * Current connections (if any) will not be affected.
 * @param ctx : context.
 * @param enable : 1 to enable, 0, to disable.
 * @param idle : start keepalives after this period (in seconds).
 * @param interval : Interval between keepalives (in seconds).
 * @param count : number of keepalives before death.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks Default values if nothing else is specified is (1, 5, 1, 2).
 */
POMP_API int pomp_ctx_setup_keepalive(struct pomp_ctx *ctx, int enable,
		int idle, int interval, int count);

/**
 * Destroy a context.
 * @param ctx : context.
 * @return 0 in case of success, negative errno value in case of error.
 * If the client or server is still running, -EBUSY is returned.
 */
POMP_API int pomp_ctx_destroy(struct pomp_ctx *ctx);

/**
 * Start a server.
 * @param ctx : context.
 * @param addr : local address to listen on.
 * @param addrlen : local address size.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_listen(struct pomp_ctx *ctx,
		const struct sockaddr *addr, uint32_t addrlen);

/**
 * Start a server, but changing the access mode for unix socket address.
 * @param ctx : context.
 * @param addr : local address to listen on.
 * @param addrlen : local address size.
 * @param mode : acces mode to set (see CHMOD(2)). if 0 is given this effect is
 * the same as simply calling pomp_ctx_listen, it will use default access mode
 * depending on current value of UMASK(2).
 * @return 0 in case of success, negative errno value in case of error.
 * @remarks the 'mode' argument is ignored for non unix socket address.
 */
POMP_API int pomp_ctx_listen_with_access_mode(struct pomp_ctx *ctx,
		const struct sockaddr *addr, uint32_t addrlen, uint32_t mode);

/**
 * Start a client.
 * If connection can not be completed immediately, it will try again later
 * automatically. Call pomp_ctx_stop to disconnect and stop everything.
 * @param ctx : context.
 * @param addr : remote address to connect to.
 * @param addrlen : remote address size.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_connect(struct pomp_ctx *ctx,
		const struct sockaddr *addr, uint32_t addrlen);

/**
 * Bind a connection-less context (inet-udp).
 * @param ctx : context.
 * @param addr : address to bind to.
 * @param addrlen : address size.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_bind(struct pomp_ctx *ctx,
		const struct sockaddr *addr, uint32_t addrlen);

/**
 * Stop the context. It will disconnects all peers (with notification). The
 * context structure itself is not freed. It can be used again with listen or
 * connect.
 * @param ctx : context.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_stop(struct pomp_ctx *ctx);

/**
 * Get the internal loop structure of the context.
 * @param ctx : context.
 * @return loop structure or NULL in case of error.
 */
POMP_API struct pomp_loop *pomp_ctx_get_loop(struct pomp_ctx *ctx);

/**
 * Get the fd/event of the loop associated with the context.
 *
 * This fd/event shall be put in the user main loop (select, poll, epoll, glib,
 * win32...) and monitored for input events. When it becomes readable, the
 * function pomp_ctx_process_fd shall be called to dispatch internal events.
 *
 * @param ctx : context.
 * @return file descriptor (or event handle for win32), negative errno value
 * in case of error.
 *
 * @remarks see pomp_loop_getfd for more information.
 */
POMP_API intptr_t pomp_ctx_get_fd(const struct pomp_ctx *ctx);

/**
 * Function to be called when the loop of the context is signaled.
 * @param ctx : context.
 * @return 0 in case of success, negative errno value in case of error.
 * @remarks this is equivalent to calling pomp_ctx_wait_and_process with a
 * timeout of 0 (no wait).
 */
POMP_API int pomp_ctx_process_fd(struct pomp_ctx *ctx);

/**
 * Wait for events to occur in the context and process them.
 * @param ctx : context.
 * @param timeout : timeout of wait (in ms) or -1 for infinite wait.
 * @return 0 in case of success, -ETIMEDOUT if timeout occurred,
 * negative errno value in case of error.
 */
POMP_API int pomp_ctx_wait_and_process(struct pomp_ctx *ctx, int timeout);

/**
 * Wakeup a context from a wait in pomp_ctx_wait_and_process.
 * @param ctx : context.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks: this function is safe to call from another thread that the one
 * associated normally with the context. It is also safe to call it from a
 * signal handler. However caller must ensure that the given context will be
 * valid for the complete duration of the call.
 */
POMP_API int pomp_ctx_wakeup(struct pomp_ctx *ctx);

/**
 * Get next connection structure for a server context.
 * @param ctx : context (shall be a server one).
 * @param prev : previous connection structure or NULL to get the first one.
 * @return connection structure or NULL if there is no more connection.
 */
POMP_API struct pomp_conn *pomp_ctx_get_next_conn(const struct pomp_ctx *ctx,
		const struct pomp_conn *prev);

/**
 * Get the connection structure for a client context.
 * @param ctx : context (shall be a client one).
 * @return connection structure or NULL if there is no connection with server.
 */
POMP_API struct pomp_conn *pomp_ctx_get_conn(const struct pomp_ctx *ctx);

/**
 * Get context local address (for server or udp context started with listen or
 * bind ).
 * @param ctx : context (shall be a server or udp one).
 * @param addrlen : returned address size.
 * @return local address or NULL in case of error.
 */
POMP_API const struct sockaddr *pomp_ctx_get_local_addr(struct pomp_ctx *ctx,
		uint32_t *addrlen);

/**
 * Send a message to a context.
 * For server it will broadcast to all connected clients. If there is no
 * connection, the message is lost and no error is returned.
 * For client, if there is no connection, -ENOTCONN is returned.
 * @param ctx : context.
 * @param msg : message to send.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_ctx_send_msg(struct pomp_ctx *ctx,
		const struct pomp_msg *msg);

/**
 * Send a message on dgram context to a remote address.
 * @param ctx : context.
 * @param msg : message to send.
 * @param addr : destination address.
 * @param addrlen : address size.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_ctx_send_msg_to(struct pomp_ctx *ctx,
		const struct pomp_msg *msg,
		const struct sockaddr *addr, uint32_t addrlen);

/**
 * Format and send a message to a context.
 * For server it will broadcast to all connected clients. If there is no
 * connection, no message is sent and no error is returned.
 * For client, if there is no connection, -ENOTCONN is returned.
 * @param ctx : context.
 * @param msgid : message id.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param ... : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_ctx_send(struct pomp_ctx *ctx, uint32_t msgid,
		const char *fmt, ...) POMP_ATTRIBUTE_FORMAT_PRINTF(3, 4);


/**
 * Format and send a message to a context.
 * For server it will broadcast to all connected clients. If there is no
 * connection, the message is lost and no error is returned.
 * For client, if there is no connection, -ENOTCONN is returned.
 * @param ctx : context.
 * @param msgid : message id.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param args : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_ctx_sendv(struct pomp_ctx *ctx, uint32_t msgid,
		const char *fmt, va_list args);

/**
 * Send a buffer to a raw context.
 * For server it will broadcast to all connected clients. If there is no
 * connection, no buffer is sent and no error is returned.
 * For client, if there is no connection, -ENOTCONN is returned.
 * @param ctx : context.
 * @param buf : buffer to send.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_ctx_send_raw_buf(struct pomp_ctx *ctx,
		struct pomp_buffer *buf);

/**
 * Send a buffer on dgram raw context to a remote address.
 * @param ctx : context.
 * @param buff : buffer to send.
 * @param addr : destination address.
 * @param addrlen : address size.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_ctx_send_raw_buf_to(struct pomp_ctx *ctx,
		struct pomp_buffer *buf,
		const struct sockaddr *addr, uint32_t addrlen);

/**
 * Set the context default read buffer length.
 * For server and client contexts, this value can be overriden for each
 * connection with pomp_conn_set_read_buffer_len.
 * @note The default read buffer length is 4096 bytes.
 * @note Read buffers of existing connections are not affected by this function,
 * use pomp_conn_set_read_buffer_len() instead for them.
 * @param ctx : context.
 * @param len : the length in bytes of the read buffer.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_ctx_set_read_buffer_len(struct pomp_ctx *ctx,
		size_t len);

/*
 * Connection API.
 */

/**
 * Force disconnection of an established connection.
 * @param conn : connection
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_conn_disconnect(struct pomp_conn *conn);

/**
 * Get connection local address.
 * @param conn : connection
 * @param addrlen : returned address size.
 * @return local address or NULL in case of error.
 */
POMP_API const struct sockaddr *pomp_conn_get_local_addr(struct pomp_conn *conn,
		uint32_t *addrlen);

/**
 * Get connection remote peer address.
 * @param conn : connection
 * @param addrlen : returned address size.
 * @return remote peer address or NULL in case of error.
 */
POMP_API const struct sockaddr *pomp_conn_get_peer_addr(struct pomp_conn *conn,
		uint32_t *addrlen);

/**
 * Get connection remote peer credentials for local sockets.
 * @param conn : connection
 * @return connection remote peer credentials or NULL if not a local socket.
 */
POMP_API const struct pomp_cred *pomp_conn_get_peer_cred(
		struct pomp_conn *conn);

/**
 * Get file descriptor associated with the connection.
 * @param conn : connection.
 * @return fd of the connection or -EINVAL in case of error.
 */
POMP_API int pomp_conn_get_fd(struct pomp_conn *conn);

/**
 * Suspend read operation on connection.
 * @param conn : connection.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_conn_suspend_read(struct pomp_conn *conn);

/**
 * Resume read operation on connection.
 * @param conn : connection.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_conn_resume_read(struct pomp_conn *conn);

/**
 * Send a message to the peer of the connection.
 * @param conn : connection.
 * @param msg : message to send.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_conn_send_msg(struct pomp_conn *conn,
		const struct pomp_msg *msg);

/**
 * Format and send a message to the peer of the connection.
 * @param conn : connection.
 * @param msgid : message id.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param ... : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_conn_send(struct pomp_conn *conn, uint32_t msgid,
		const char *fmt, ...) POMP_ATTRIBUTE_FORMAT_PRINTF(3, 4);

/**
 * Format and send a message to the peer of the connection.
 * @param conn : connection.
 * @param msgid : message id.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param args : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_conn_sendv(struct pomp_conn *conn, uint32_t msgid,
		const char *fmt, va_list args);

/**
 * Send a buffer to the peer of the raw connection.
 * @param conn : connection.
 * @param buf : buffer to send.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the operation will be queued automatically for later processing
 * in case the underlying socket buffer is full. Use 'pomp_ctx_set_socket_cb'
 * to have more information about completion.
 */
POMP_API int pomp_conn_send_raw_buf(struct pomp_conn *conn,
		struct pomp_buffer *buf);

/**
 * Set the connection read buffer length
 * @param conn : connection.
 * @param len : the length in bytes of the read buffer.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_conn_set_read_buffer_len(struct pomp_conn *conn,
		size_t len);

/*
 * Buffer API.
 */

/**
 * Allocate a new buffer.
 * @param capacity : initial capacity of the buffer.
 * @return new buffer with initial ref count at 1 or NULL in case of error.
 */
POMP_API struct pomp_buffer *pomp_buffer_new(size_t capacity);

/**
 * Create a new buffer with content copied from another buffer.
 * @param buf : buffer to copy.
 * @return new buffer with initial ref count at 1 and internal data copied from
 * given buffer or NULL in case of error.
 */
POMP_API struct pomp_buffer *pomp_buffer_new_copy(
		const struct pomp_buffer *buf);

/**
 * Create a new buffer with content copied from given data. Internal length and
 * capacity will be set to given data length.
 * @param data : data to copy.
 * @param len : length to copy.
 * @return new buffer with initial ref count at 1 and internal data copied from
 * given buffer or NULL in case of error.
 */
POMP_API struct pomp_buffer *pomp_buffer_new_with_data(
		const void *data, size_t len);

/**
 * Same as pomp_buffer_new but retrieved internal data pointer at the same time.
 * @param capacity : initial capacity of the buffer.
 * @param data : data of buffer (optional can be NULL).
 * @return new buffer with initial ref count at 1 or NULL in case of error.
 */
POMP_API struct pomp_buffer *pomp_buffer_new_get_data(
		size_t capacity, void **data);

/**
 * Increase ref count of buffer.
 * @param buf : buffer.
 */
POMP_API void pomp_buffer_ref(struct pomp_buffer *buf);

/**
 * Decrease ref count of buffer. When it reaches 0, internal data as well as
 * buffer structure itself is freed.
 * @param buf : buffer.
 */
POMP_API void pomp_buffer_unref(struct pomp_buffer *buf);

/**
 * Determine if the buffer is shared
 * @param buf : buffer.
 * @return 1 if the buffer is shared (ref count greater than 1), 0 otherwise.
 */
POMP_API int pomp_buffer_is_shared(const struct pomp_buffer *buf);

/**
 * Set the capacity of the buffer.
 * @param buf : buffer.
 * @param capacity : new capacity of buffer (shall be greater than used length).
 * @return 0 in case of success, negative errno value in case of error.
 * -EPERM is returned if the buffer is shared (ref count is greater than 1).
 */
POMP_API int pomp_buffer_set_capacity(struct pomp_buffer *buf, size_t capacity);

/**
 * Make sure internal data has enough room for the given size.
 * @param buf : buffer.
 * @param capacity : new capacity of buffer.
 * @return 0 in case of success, negative errno value in case of error.
 * -EPERM is returned if the buffer is shared (ref count is greater than 1).
 *
 * @remarks : internally the size will be aligned to POMP_BUFFER_ALLOC_STEP.
 */
POMP_API int pomp_buffer_ensure_capacity(struct pomp_buffer *buf,
		size_t capacity);

/**
 * Set the used length of the buffer.
 * @param buf : buffer.
 * @param len : used length of data (shall be lesser than allocated size).
 * @return 0 in case of success, negative errno value in case of error.
 * -EPERM is returned if the buffer is shared (ref count is greater than 1) or
 * readonly.
 */
POMP_API int pomp_buffer_set_len(struct pomp_buffer *buf, size_t len);

/**
 * Get internal buffer data for read/write.
 * @param buf : buffer.
 * @param data : data of buffer (optional can be NULL).
 * @param len : used length of buffer (optional can be NULL).
 * @param capacity : capacity of buffer (optional can be NULL).
 * @return 0 in case of success, negative errno value in case of error.
 * -EPERM is returned if the buffer is shared.
 */
POMP_API int pomp_buffer_get_data(const struct pomp_buffer *buf,
		void **data, size_t *len, size_t *capacity);

/**
 * Get internal buffer data for read-only.
 * @param buf : buffer
 * @param cdata : data of buffer (optional can be NULL).
 * @param len : used length of buffer (optional can be NULL).
 * @param capacity : capacity of buffer (optional can be NULL).
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_buffer_get_cdata(const struct pomp_buffer *buf,
		const void **cdata, size_t *len, size_t *capacity);

/**
 * Append data to the buffer.
 * @param buf : buffer.
 * @param data : data to append.
 * @param len : length of the data to append.
 * @return 0 in case of success, negative errno value in case of error.
 * -EPERM is returned if the buffer is shared.
 *
 * @remarks Can re-allocate the internal data buffer and invalidate the
 * data/cdata retrieved before.
 */
POMP_API int pomp_buffer_append_data(struct pomp_buffer *buf,
		const void *data, size_t len);

/**
 * Append source buffer data to the buffer.
 * @param buf : destination buffer.
 * @param src : source buffer to append.
 * @return 0 in case of success, negative errno value in case of error.
 * -EPERM is returned if the buffer is shared.
 *
 * @remarks Can re-allocate the internal data buffer and invalidate the
 * data/cdata retrieved before.
 */
POMP_API int pomp_buffer_append_buffer(struct pomp_buffer *buf,
		struct pomp_buffer *src);

/**
 * Write data to the buffer at the given position.
 * @param buf : buffer.
 * @param pos : position in the buffer (will be updated after success)
 * @param data : data to write.
 * @param len : length of the data to write.
 * @return 0 in case of success, negative errno value in case of error.
 * -EPERM is returned if the buffer is shared.
 *
 * @remarks Can re-allocate the internal data buffer and invalidate the
 * data/cdata retrieved before.
 */
POMP_API int pomp_buffer_write(struct pomp_buffer *buf, size_t *pos,
		const void *data, size_t len);

/**
 * Read data from buffer at the given position.
 * @param buf : buffer.
 * @param pos : read position. It will be updated in case of success.
 * @param data : pointer to data to read.
 * @param len : number of bytes to read.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_buffer_read(const struct pomp_buffer *buf, size_t *pos,
		void *p, size_t n);

/**
 * Read data from buffer without copy.
 * @param buf : buffer.
 * @param pos : read position. It will be updated in case of success.
 * @param cdata : will receive pointer to data inside buffer. It is valid as
 * long as the buffer is valid and no write or resize operation is performed.
 * @param len : number of bytes to read.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_buffer_cread(const struct pomp_buffer *buf, size_t *pos,
		const void **cdata, size_t len);

/*
 * Message API.
 */

/**
 * Create a new message structure.
 * Message is initially empty.
 * @return new message structure or NULL in case of error.
 */
POMP_API struct pomp_msg *pomp_msg_new(void);

/**
 * Create a new message structure.
 * Message will be a copy of given message (with internal buffer copied as
 * well, not just shared).
 * @param msg : message to copy.
 * @return new message structure or NULL in case of error.
 *
 * @remarks : if the message contains file descriptors, they are duplicated in
 * the new message.
 */
POMP_API struct pomp_msg *pomp_msg_new_copy(const struct pomp_msg *msg);

/**
 * Create a new message structure from a buffer with data.
 * @param buf : buffer with message content (header + playload).
 * @return new message structure or NULL in case of error.
 */
POMP_API struct pomp_msg *pomp_msg_new_with_buffer(struct pomp_buffer *buf);

/**
 * Destroy a message.
 * @param msg : message.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_destroy(struct pomp_msg *msg);

/**
 * Get the id of the message.
 * @param msg : message.
 * @return id of the message or 0 in case of error.
 */
POMP_API uint32_t pomp_msg_get_id(const struct pomp_msg *msg);

/**
 * Get the internal buffer of the message.
 * @param msg : message.
 * @return internal buffer of the message or NULL in case of error.
 *
 * @remarks this function is useful when only the serialization of the library
 * is needed, not the transport part. This way one can write the data to another
 * transport layer.
 */
POMP_API struct pomp_buffer *pomp_msg_get_buffer(const struct pomp_msg *msg);

/**
 * Write and encode a message.
 * @param msg : message.
 * @param msgid : message id.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param ... : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_write(struct pomp_msg *msg, uint32_t msgid,
		const char *fmt, ...) POMP_ATTRIBUTE_FORMAT_PRINTF(3, 4);

/**
 * Write and encode a message.
 * @param msg : message.
 * @param msgid : message id.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param args : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_writev(struct pomp_msg *msg, uint32_t msgid,
		const char *fmt, va_list args);

/**
 * Write and encode a message.
 * @param msg : message.
 * @param msgid : message id.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param argc : number of arguments.
 * @param argv : array of arguments as strings. Each string will be converted
 *               according to its real type specified in format.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks this is mainly used by the command line tool.
 */
POMP_API int pomp_msg_write_argv(struct pomp_msg *msg, uint32_t msgid,
		const char *fmt, int argc, const char * const *argv);

/**
 * Read and decode a message.
 * If the format is shorter (less arguments) than the message written, the last
 * arguments written will be silently ignored and only the first arguments in
 * the read format will be filled.
 * @param msg : message.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param ... : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_read(const struct pomp_msg *msg,
		const char *fmt, ...) POMP_ATTRIBUTE_FORMAT_SCANF(2, 3);

/**
 * Read and decode a message.
 * If the format is shorter (less arguments) than the message written, the last
 * arguments written will be silently ignored and only the first arguments in
 * the read format will be filled.
 * @param msg : message.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param args : message arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_readv(const struct pomp_msg *msg,
		const char *fmt, va_list args);

/**
 * Dump a message in a human readable form.
 * @param msg : message.
 * @param dst : destination buffer.
 * @param maxdst : max length of destination buffer.
 * @return 0 in case of success, negative errno value in case of error.

 * @remarks if the buffer is too small, it will be ended with ellipsis '...' if
 * possible. It will also always be null terminated (unless maxlen is 0)
 */
POMP_API int pomp_msg_dump(const struct pomp_msg *msg,
		char *dst, uint32_t maxdst);

/**
 * Dump a message in a human readable form. Similar to pomp_msg_dump() but
 * allocates the output buffer dynamically.
 * Dump a message in a human readable form.
 * @param msg : message.
 * @param dst : destination buffer, which will be allocated to a suitable size
 * dynamically. Must be freed with free(), after usage.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_adump(const struct pomp_msg *msg, char **dst);

/*
 * Loop API.
 */

/**
 * Create a new loop structure.
 * @return loop structure or NULL in case of error.
 */
POMP_API struct pomp_loop *pomp_loop_new(void);

/**
 * Destroy a loop.
 * @param loop : loop to destroy.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_destroy(struct pomp_loop *loop);

/**
 * Register a new fd in loop.
 * @param loop : loop.
 * @param fd : fd to register.
 * @param events : events to monitor. @see pomp_fd_event.
 * @param cb : callback for notifications.
 * @param userdata user data for callback.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_add(struct pomp_loop *loop, int fd, uint32_t events,
		pomp_fd_event_cb_t cb, void *userdata);

/**
 * Modify the set of events to monitor for a registered fd.
 * @param loop : loop.
 * @param fd : fd to modify.
 * @param events : new events to monitor. @see pomp_fd_event.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_update(struct pomp_loop *loop, int fd, uint32_t events);

/**
 * Modify the set of events to monitor for a registered fd.
 * @param loop : loop.
 * @param fd : fd to modify.
 * @param events_to_add : events to add. @see pomp_fd_event.
 * @param events_to_remove : events to remove. @see pomp_fd_event.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_update2(struct pomp_loop *loop, int fd,
		uint32_t events_to_add, uint32_t events_to_remove);

/**
 * Unregister a fd from the loop
 * @param loop : loop.
 * @param fd : fd to unregister.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_remove(struct pomp_loop *loop, int fd);

/**
 * Check if fd has been added in loop.
 * @param loop : loop.
 * @param fd : fd to check.
 * @return 1 if fd is in loop 0 otherwise.
 */
POMP_API int pomp_loop_has_fd(struct pomp_loop *loop, int fd);

/**
 * Get a file descriptor (or event handle for win32) that can be monitored for
 * reading (or waited for) when there is some activity in the loop.
 *
 * This fd/event shall be put in the user main loop (select, poll, epoll, glib,
 * win32...) and monitored for input events. When it becomes readable, the
 * function pomp_loop_wait_and_process shall be called to dispatch internal
 * events.
 *
 * @param loop : loop.
 * @return file descriptor (or event handle for win32), negative errno value
 * in case of error.
 *
 * @remarks for poll/win32 implementation this will create an internal worker
 * thread that will monitor all registered fd/handles and signal the single
 * fd/event returned by this function.
 */
POMP_API intptr_t pomp_loop_get_fd(struct pomp_loop *loop);

/**
 * Function to be called when the loop is signaled for readiness.
 * @param loop : loop.
 * @return 0 in case of success, negative errno value in case of error.
 * @remarks this is equivalent to calling pomp_loop_wait_and_process with a
 * timeout of 0 (no wait).
 */
POMP_API int pomp_loop_process_fd(struct pomp_loop *loop);

/**
 * Wait for events to occur in loop and process them.
 * @param loop : loop.
 * @param timeout : timeout of wait (in ms) or -1 for infinite wait.
 * @return 0 in case of success, -ETIMEDOUT if timeout occurred,
 * negative errno value in case of error.
 */
POMP_API int pomp_loop_wait_and_process(struct pomp_loop *loop, int timeout);

/**
 * Wakeup a loop from a wait in pomp_loop_wait_and_process.
 * @param loop : loop.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks: this function is safe to call from another thread that the one
 * associated normally with the loop. It is also safe to call it from a
 * signal handler. However caller must ensure that the given context will be
 * valid for the complete duration of the call.
 */
POMP_API int pomp_loop_wakeup(struct pomp_loop *loop);

/**
 * Register a function to be called when loop is idle, i.e. there is no event
 * to be processed. The registered function will be called only once and in
 * the order they are registered.
 * @param loop : loop.
 * @param cb : callback to call.
 * @param userdata : user data for callback.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks: this function is useful to register cleanup functions when called
 * by an fd event callback for example.
 * @remarks: this function is safe to call from another thread that the one
 * associated normally with the loop. However caller must ensure that the
 * given loop will be valid for the complete duration of the call.
 */
POMP_API int pomp_loop_idle_add(struct pomp_loop *loop, pomp_idle_cb_t cb,
		void *userdata);

/**
 * Similar to pomp_loop_idle_add but associate a cookie with the idle entry
 * that can be used with pomp_loop_idle_remove_by_cookie or
 * pomp_loop_idle_flush_by_cookie.
 * @param loop : loop.
 * @param cb : callback to call.
 * @param userdata : user data for callback.
 * @param cookie : cookie to better identify the idle entry.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_idle_add_with_cookie(struct pomp_loop *loop,
		pomp_idle_cb_t cb,
		void *userdata,
		void *cookie);

/**
 * Unregister a function registered with pomp_loop_idle_add.
 * @param loop : loop.
 * @param cb : callback given in pomp_loop_idle_add.
 * @param userdata : user data given in pomp_loop_idle_add.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks: if nothing match the given criteria, no error is returned.
 * @remarks: if several match the given criteria, all are removed.
 * @remarks: this function is safe to call from another thread that the one
 * associated normally with the loop. However caller must ensure that the
 * given loop will be valid for the complete duration of the call.
 */
POMP_API int pomp_loop_idle_remove(struct pomp_loop *loop, pomp_idle_cb_t cb,
		void *userdata);

/**
 * Similar to pomp_loop_idle_remove but remove all idle functions registered
 * with the given cookie.
 * @param loop : loop.
 * @param cookie : cookie given in pomp_loop_idle_add_with_cookie.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_idle_remove_by_cookie(struct pomp_loop *loop,
		void *cookie);

/**
 * Flush idle entries. Calls all pending idles.
 *
 * @param loop : loop.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_idle_flush(struct pomp_loop *loop);

/**
 * Similar to pomp_loop_idle_flush but with a filter on the cookie.
 * @param loop : loop.
 * @param cookie : cookie given in pomp_loop_idle_add.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_idle_flush_by_cookie(struct pomp_loop *loop,
		void *cookie);

/**
 * Enable watchdog on the loop. If the dispatch of the events on the loop takes
 * longer than the given delay, the given function will be called
 * (in an internal thread) to notify that processing is stuck.
 * @param loop : loop.
 * @param delay : maximum time (in ms allowed for the processing of events)
 * @param cb :  function to call when the processing took too long.
 * @param userdata : user data for the callback.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks: the function is called in the context of an internal thread and
 * should therefore nor call other functions of the library. The intent is to
 * provide a way to log something or kill the offending process.
 * @remarks: it should be called only once before caling once of the 'process'
 * functions.
 */
POMP_API int pomp_loop_watchdog_enable(struct pomp_loop *loop,
		uint32_t delay,
		pomp_watchdog_cb_t cb,
		void *userdata);

/**
 * Disable the watchdog on the loop.
 * @param loop : loop.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_loop_watchdog_disable(struct pomp_loop *loop);

/*
 * Event API.
 */

/**
 * Create a new event.
 * @return new event or NULL in case of error.
 */
POMP_API struct pomp_evt *pomp_evt_new(void);

/**
 * Destroy an event.
 * @param evt : event to destroy.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_evt_destroy(struct pomp_evt *evt);

/**
 * Attach a pomp_evt to a loop.
 * @param evt : event to attach.
 * @param loop : loop to attach to.
 * @param cb : callback for notifications.
 * @param userdata user data for callback.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_evt_attach_to_loop(struct pomp_evt *evt,
		struct pomp_loop *loop, pomp_evt_cb_t cb, void *userdata);

/**
 * Detach an event from a loop.
 * @param evt : event to detach.
 * @param loop : loop.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_evt_detach_from_loop(struct pomp_evt *evt,
		struct pomp_loop *loop);

/**
 * Check if the event is attached to the given loop.
 * @param evt : event to check.
 * @param loop : loop to check.
 *               If NULL, check if the event is attached to any loop.
 * @return 1 if event is attached to the given loop, 0 otherwise.
 */
POMP_API int pomp_evt_is_attached(struct pomp_evt *evt, struct pomp_loop *loop);

/**
 * Signal an event.
 *
 * The fd associated with the pomp_evt will become readable.
 *
 * @param evt : event.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_evt_signal(struct pomp_evt *evt);

/**
 * Clear an event.
 *
 * The fd associated with the pomp_evt will no longer be readable.
 *
 * @param evt : event.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_evt_clear(struct pomp_evt *event);

/*
 * Timer API.
 */

/**
 * Create a new timer.
 * @param loop : fd loop to use for notifications.
 * @param cb : callback to use for notifications.
 * @param userdata : user data for callback.
 * @return new timer or NULL in case of error.
 */
POMP_API struct pomp_timer *pomp_timer_new(struct pomp_loop *loop,
		pomp_timer_cb_t cb, void *userdata);

/**
 * Destroy a timer.
 * @param timer : timer to destroy.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_timer_destroy(struct pomp_timer *timer);

/**
 * Set a one shot timer.
 * @param timer : timer to set.
 * @param delay : expiration delay in milliseconds.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_timer_set(struct pomp_timer *timer, uint32_t delay);

/**
 * Set a periodic timer.
 * @param timer : timer to set.
 * @param delay : initial expiration delay in milliseconds.
 * @param period : period in milliseconds.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_timer_set_periodic(struct pomp_timer *timer, uint32_t delay,
		uint32_t period);

/**
 * Clear a timer.
 * @param timer : timer to clear.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_timer_clear(struct pomp_timer *timer);

/*
 * Address string parsing/formatting utilities.
 */

/**
 * Parse a socket address given as a string and convert it to sockaddr.
 * @param buf: input string.
 * @param addr: destination structure.
 * @param addrlen: maximum size of destination structure as input, real size
 * converted as output. Should be at least sizeof(struct sockaddr_storage)
 * @return 0 in case of success, negative errno value in case of error.
 *
 * Format of string is:
 * - inet:<host>:<port>: ipv4 address with host name and port.
 * - inet6:<host>:<port>: ipv6 address with host name and port
 * - unix:<pathname>: unix local address with file system name.
 * - unix:@<name>: unix local address with abstract name.
 */
POMP_API int pomp_addr_parse(const char *buf, struct sockaddr *addr,
		uint32_t *addrlen);

/**
 * Format a socket address into a string.
 * @param buf: destination buffer
 * @param buflen: maximum size of destination buffer.
 * @param addr: address to format.
 * @param addrlen: size of address.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_addr_format(char *buf, uint32_t buflen,
		const struct sockaddr *addr, uint32_t addrlen);

/**
 * Determine if a socket address is a unix local one.
 * @param addr: address to check.
 * @param addrlen: size of address.
 * @return 1 if socket is unix local, 0 otherwise.
 */
POMP_API int pomp_addr_is_unix(const struct sockaddr *addr, uint32_t addrlen);

/**
 * Prepend the product root path to a unix local address with file system name.
 * @param buf: input string.
 * @param dst: destination buffer, which will be allocated to a suitable size
 * dynamically. Must be freed with free(), after usage.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * Format of string is:
 * - unix:<pathname>: unix local address with file system name.
 */
POMP_API int pomp_addr_get_real_addr(const char *buf, char **dst);

/*
 * Advanced API.
 *
 * Basic API is sufficient for normal usage. Advanced API offers better
 * tuning of encoding/decoding.
 */

/* Forward declarations */
struct pomp_encoder;
struct pomp_decoder;
struct pomp_prot;

/*
 * message API (Advanced).
 */

/**
 * Initialize a message object before starting to encode it.
 * @param msg : message.
 * @param msgid : message id.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_init(struct pomp_msg *msg, uint32_t msgid);

/**
 * Finish message encoding by writing the header. It shall be called after
 * encoding is done and before sending it. Any write operation on the message
 * will return -EPERM after this function is called.
 * @param msg : message.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_finish(struct pomp_msg *msg);

/**
 * Clear message object. It only free the internal data, not the message itself.
 * It shall be called before pomp_msg_init can be called again after a previous
 * encoding.
 * @param msg : message.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_msg_clear(struct pomp_msg *msg);

/*
 * Encoder API (Advanced).
 */

/**
 * Create a new encoder object.
 * @return new encoder object or NULL in case of error.
 */
POMP_API struct pomp_encoder *pomp_encoder_new(void);

/**
 * Destroy an encoder object.
 * @param enc : encoder.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the associated message is NOT destroyed.
 */
POMP_API int pomp_encoder_destroy(struct pomp_encoder *enc);

/**
 * Initialize an encoder object before starting to encode a message.
 * @param enc : encoder.
 * @param msg : message to encode.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the message ownership is not transferred, it will NOT be destroyed
 * when encoder object is destroyed.
 */
POMP_API int pomp_encoder_init(struct pomp_encoder *enc, struct pomp_msg *msg);

/**
 * Clear encoder object.
 * @param enc : encoder.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the associated message is NOT destroyed.
 */
POMP_API int pomp_encoder_clear(struct pomp_encoder *enc);

/**
 * Encode arguments according to given format string.
 * @param enc : encoder.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param ... : arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write(struct pomp_encoder *enc,
		const char *fmt, ...) POMP_ATTRIBUTE_FORMAT_PRINTF(2, 3);

/**
 * Encode arguments according to given format string.
 * @param enc : encoder.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param args : arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_writev(struct pomp_encoder *enc,
		const char *fmt, va_list args);

/**
 * Encode arguments according to given format string.
 * @param enc : encoder.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param argc : number of arguments.
 * @param argv : array of arguments as strings. Each string will be converted
 *               according to its real type specified in format.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks this is mainly used by the command line tool.
 */
POMP_API int pomp_encoder_write_argv(struct pomp_encoder *enc,
		const char *fmt, int argc, const char * const *argv);

/**
 * Encode a 8-bit signed integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_i8(struct pomp_encoder *enc, int8_t v);

/**
 * Encode a 8-bit unsigned integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_u8(struct pomp_encoder *enc, uint8_t v);

/**
 * Encode a 16-bit signed integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_i16(struct pomp_encoder *enc, int16_t v);

/**
 * Encode a 16-bit unsigned integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_u16(struct pomp_encoder *enc, uint16_t v);

/**
 * Encode a 32-bit signed integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_i32(struct pomp_encoder *enc, int32_t v);

/**
 * Encode a 32-bit unsigned integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_u32(struct pomp_encoder *enc, uint32_t v);

/**
 * Encode a 64-bit signed integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_i64(struct pomp_encoder *enc, int64_t v);

/**
 * Encode a 64-bit unsigned integer.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_u64(struct pomp_encoder *enc, uint64_t v);

/**
 * Encode a string.
 * @param enc : encoder.
 * @param v : string to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_str(struct pomp_encoder *enc, const char *v);

/**
 * Encode a buffer.
 * @param enc : encoder.
 * @param v : buffer to encode.
 * @param n : buffer size.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_buf(struct pomp_encoder *enc, const void *v,
		uint32_t n);

/**
 * Encode a 32-bit floating point.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_f32(struct pomp_encoder *enc, float v);

/**
 * Encode a 64-bit floating point.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_encoder_write_f64(struct pomp_encoder *enc, double v);

/**
 * Encode a file descriptor. It will be internally duplicated and close when
 * associated message is released.
 * @param enc : encoder.
 * @param v : value to encode.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks : the encoded message will only be able to be exchanged over
 * unix local socket.
 */
POMP_API int pomp_encoder_write_fd(struct pomp_encoder *enc, int v);

/*
 * Decoder API (Advanced).
 */

/**
 * Create a new decoder object.
 * @return new decoder object or NULL in case of error.
 */
POMP_API struct pomp_decoder *pomp_decoder_new(void);

/**
 * Destroy a decoder object.
 * @param dec : decoder.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the associated message is NOT destroyed.
 */
POMP_API int pomp_decoder_destroy(struct pomp_decoder *dec);

/**
 * Initialize a decoder object before starting to decode a message.
 * @param dec : encoder.
 * @param msg : message to decode.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the message ownership is not transferred, it will NOT be destroyed
 * when decoder object is destroyed.
 */
POMP_API int pomp_decoder_init(struct pomp_decoder *dec,
		const struct pomp_msg *msg);

/**
 * Clear decoder object.
 * @param dec : encoder.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks the associated message is NOT destroyed.
 */
POMP_API int pomp_decoder_clear(struct pomp_decoder *dec);

/**
 * Decode arguments according to given format string.
 * @param dec : decoder.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param ... : arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read(struct pomp_decoder *dec,
		const char *fmt, ...) POMP_ATTRIBUTE_FORMAT_SCANF(2, 3);

/**
 * Decode arguments according to given format string.
 * @param dec : decoder.
 * @param fmt : format string. Can be NULL if no arguments given.
 * @param args : arguments.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_readv(struct pomp_decoder *dec,
		const char *fmt, va_list args);

/**
 * Dump arguments in a human readable form.
 * @param dec : decoder.
 * @param dst : destination buffer.
 * @param maxdst : max length of destination buffer.
 * @return 0 in case of success, negative errno value in case of error.

 * @remarks if the buffer is too small, it will be ended with ellipsis '...' if
 * possible. It will also always be null terminated (unless maxlen is 0)
 */
POMP_API int pomp_decoder_dump(struct pomp_decoder *dec,
		char *dst, uint32_t maxdst);

/**
 * Dump arguments in a human readable form. Similar to pomp_decoder_dump() but
 * allocates the output buffer dynamically.
 * @param dec : decoder.
 * @param dst : destination buffer, which will be allocated to a suitable size
 * dynamically. Must be freed with free(), after usage.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_adump(struct pomp_decoder *dec, char **dst);

/**
 * Decode a 8-bit signed integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_i8(struct pomp_decoder *dec, int8_t *v);

/**
 * Decode a 8-bit unsigned integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_u8(struct pomp_decoder *dec, uint8_t *v);

/**
 * Decode a 16-bit signed integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_i16(struct pomp_decoder *dec, int16_t *v);

/**
 * Decode a 16-bit unsigned integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_u16(struct pomp_decoder *dec, uint16_t *v);

/**
 * Decode a 32-bit signed integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_i32(struct pomp_decoder *dec, int32_t *v);

/**
 * Decode a 32-bit unsigned integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_u32(struct pomp_decoder *dec, uint32_t *v);

/**
 * Decode a 64-bit signed integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_i64(struct pomp_decoder *dec, int64_t *v);

/**
 * Decode a 64-bit unsigned integer.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_u64(struct pomp_decoder *dec, uint64_t *v);

/**
 * Decode a string.
 * @param dec : decoder.
 * @param v : decoded string. Call 'free' when done.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_str(struct pomp_decoder *dec, char **v);

/**
 * Decode a string without any extra allocation or copy.
 * @param dec : decoder.
 * @param v : decoded string. Shall NOT be modified or freed as it points
 * directly to internal storage. Scope is the same as the associated message.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_cstr(struct pomp_decoder *dec, const char **v);

/**
 * Decode a buffer.
 * @param dec : decoder.
 * @param v : decoded buffer. Call 'free' when done.
 * @param n : decoded buffer size.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_buf(struct pomp_decoder *dec, void **v,
		uint32_t *n);

/**
 * Decode a buffer without any extra allocation or copy.
 * @param dec : decoder.
 * @param v : decoded buffer. Shall NOT be modified or freed as it points
 * directly to internal storage. Scope is the same as the associated message.
 * @param n : decoded buffer size.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_cbuf(struct pomp_decoder *dec, const void **v,
		uint32_t *n);

/**
 * Decode a 32-bit floating point.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_f32(struct pomp_decoder *dec, float *v);

/**
 * Decode a 64-bit floating point.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_decoder_read_f64(struct pomp_decoder *dec, double *v);

/**
 * Decode a file descriptor.
 * @param dec : decoder.
 * @param v : decoded value.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks : the returned file descriptor shall NOT be closed. Duplicate it if
 * you need to use it after the decoder or the message is released.
 */
POMP_API int pomp_decoder_read_fd(struct pomp_decoder *dec, int *v);

/*
 * Protocol Parsing API (Advanced).
 */

/**
 * Create a new protocol decoder object.
 * @return protocol decoder object or NULL in case of error.
 */
POMP_API struct pomp_prot *pomp_prot_new(void);

/**
 * Destroy a protocol decoder object.
 * @param prot : protocol decoder.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_prot_destroy(struct pomp_prot *prot);

/**
 * Try to decode a message with given input data.
 * @param prot : protocol decoder.
 * @param buf : input data.
 * @param len : size of input data.
 * @param msg : will receive decoded message. If more input data is required
 * to decode the message, NULL will be returned. The message needs to be
 * released either by calling 'pomp_msg_destroy' or 'pomp_prot_release_msg'.
 * Calling 'pomp_prot_release_msg' allows reuse of allocated message structure.
 * @return number of bytes processed. It can be less that input size in which
 * case caller shall call again this function with remaining bytes.
 */
POMP_API int pomp_prot_decode_msg(struct pomp_prot *prot, const void *buf,
		size_t len, struct pomp_msg **msg);

/**
 * Release a previously decoded message. This is to reuse message structure
 * if possible and avoid some malloc/free at each decoded message. If there
 * is already a internal message structure, it is simply destroyed.
 * @param prot : protocol decoder.
 * @param msg : message to release.
 * @return 0 in case of success, negative errno value in case of error.
 */
POMP_API int pomp_prot_release_msg(struct pomp_prot *prot,
		struct pomp_msg *msg);

/*
 * Internal API.
 */

enum pomp_loop_impl {
	POMP_LOOP_IMPL_EPOLL,		/**< epoll impl. (linux only) */
	POMP_LOOP_IMPL_POLL,		/**< poll impl. */
	POMP_LOOP_IMPL_WIN32,		/**< win32 impl. */
};

enum pomp_timer_impl {
	POMP_TIMER_IMPL_TIMER_FD,	/**< timer fd impl. (linux only) */
	POMP_TIMER_IMPL_KQUEUE,		/**< kqueue impl. (darwin,bsd only) */
	POMP_TIMER_IMPL_POSIX,		/**< posix (signals) impl. */
	POMP_TIMER_IMPL_WIN32,		/**< win32 impl. */

};

/**
 * Force the loop implementation to use.
 * @param impl: the implementation to use.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks : This function modifies the implementation of ALL loops. It shall
 * only be called BEFORE creating anything and ONLY for tests or specific use
 * cases. Not all implementations are available on all platforms.
 */
POMP_API int pomp_internal_set_loop_impl(enum pomp_loop_impl impl);

/**
 * Force the timer implementation to use.
 * @param impl: the implementation to use.
 * @return 0 in case of success, negative errno value in case of error.
 *
 * @remarks : This function modifies the implementation of ALL timers. It shall
 * only be called BEFORE creating anything and ONLY for tests or specific use
 * cases. Not all implementations are available on all platforms.
 */
POMP_API int pomp_internal_set_timer_impl(enum pomp_timer_impl impl);


#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* !_LIBPOMP_H_ */