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
|
#pragma once
#include <stdint.h>
#include <functional>
#include <optional>
#include "cbor.h"
#include "result.hpp"
namespace audio {
extern const int kEncoderFlags;
extern const int kDecoderFlags;
enum MessageType {
TYPE_UNKNOWN,
TYPE_CHUNK_HEADER,
TYPE_STREAM_INFO,
};
template <typename Writer>
auto WriteMessage(MessageType type,
Writer&& writer,
uint8_t* buffer,
size_t length) -> cpp::result<size_t, CborError> {
CborEncoder root;
CborEncoder container;
cbor_encoder_init(&root, buffer, length, kEncoderFlags);
cbor_encoder_create_array(&root, &container, 2);
cbor_encode_uint(&container, type);
std::optional<CborError> inner_err = std::invoke(writer, container);
if (inner_err) {
return cpp::fail(inner_err.value());
}
cbor_encoder_close_container(&root, &container);
return cbor_encoder_get_buffer_size(&root, buffer);
}
template <typename Result, typename Reader>
auto ReadMessage(Reader&& reader, uint8_t* buffer, size_t length)
-> cpp::result<Result, CborError> {
CborParser parser;
CborValue root;
CborValue container;
cbor_parser_init(buffer, length, kDecoderFlags, &parser, &root);
cbor_value_enter_container(&root, &container);
// Skip the type header
cbor_value_advance_fixed(&container);
return std::invoke(reader, container);
}
auto ReadMessageType(uint8_t* buffer, size_t length) -> MessageType;
} // namespace audio
|