mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Porting the CBOR encoder from the YANG branch
Minor cleanups by commiter.
(source commit 43ff10204b
but expected
to be rebased later, don't worry if you fail to find it)
This commit is contained in:
parent
253ce95bc9
commit
9f27bfc6fc
@ -1,4 +1,4 @@
|
||||
src := bitmap.c bitops.c blake2s.c blake2b.c checksum.c defer.c event.c flowspec.c idm.c ip.c lists.c lockfree.c mac.c md5.c mempool.c net.c netindex.c patmatch.c printf.c rcu.c resource.c runtime.c sha1.c sha256.c sha512.c slab.c slists.c strtoul.c tbf.c timer.c xmalloc.c
|
||||
src := bitmap.c bitops.c blake2s.c blake2b.c cbor.c cbor_parse_tools.c cbor_shortcuts.c checksum.c defer.c event.c flowspec.c idm.c ip.c lists.c lockfree.c mac.c md5.c mempool.c net.c netindex.c patmatch.c printf.c rcu.c resource.c runtime.c sha1.c sha256.c sha512.c slab.c slists.c strtoul.c tbf.c timer.c xmalloc.c
|
||||
obj := $(src-o-files)
|
||||
$(all-lib)
|
||||
|
||||
@ -6,6 +6,6 @@ src := a-path.c a-set.c
|
||||
obj := $(src-o-files)
|
||||
$(all-daemon)
|
||||
|
||||
tests_src := a-set_test.c a-path_test.c attribute_cleanup_test.c bitmap_test.c heap_test.c buffer_test.c event_test.c flowspec_test.c bitops_test.c patmatch_test.c fletcher16_test.c slist_test.c checksum_test.c lists_test.c locking_test.c mac_test.c ip_test.c hash_test.c printf_test.c rcu_test.c slab_test.c tlists_test.c type_test.c
|
||||
tests_src := a-set_test.c a-path_test.c attribute_cleanup_test.c bitmap_test.c cbor_test.c heap_test.c buffer_test.c event_test.c flowspec_test.c bitops_test.c patmatch_test.c fletcher16_test.c slist_test.c checksum_test.c lists_test.c locking_test.c mac_test.c ip_test.c hash_test.c printf_test.c rcu_test.c slab_test.c tlists_test.c type_test.c
|
||||
tests_targets := $(tests_targets) $(tests-target-files)
|
||||
tests_objs := $(tests_objs) $(src-o-files)
|
||||
|
237
lib/cbor.c
Normal file
237
lib/cbor.c
Normal file
@ -0,0 +1,237 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/cbor.h"
|
||||
|
||||
|
||||
void write_item(struct cbor_writer *writer, uint8_t major, uint64_t num);
|
||||
void check_memory(struct cbor_writer *writer, int add_size);
|
||||
|
||||
struct cbor_writer *cbor_init(uint8_t *buff, uint32_t capacity, struct linpool *lp)
|
||||
{
|
||||
struct cbor_writer *writer = (struct cbor_writer*)lp_alloc(lp, sizeof(struct cbor_writer));
|
||||
writer->cbor = buff;
|
||||
writer->capacity = capacity;
|
||||
writer->pt = 0;
|
||||
writer->lp = lp;
|
||||
return writer;
|
||||
}
|
||||
|
||||
void cbor_open_block(struct cbor_writer *writer) { // We will need to close the block later manualy
|
||||
check_memory(writer, 2);
|
||||
writer->cbor[writer->pt] = 0xbf;
|
||||
writer->pt++;
|
||||
}
|
||||
|
||||
void cbor_open_list(struct cbor_writer *writer)
|
||||
{
|
||||
check_memory(writer, 2);
|
||||
writer->cbor[writer->pt] = 0x9f;
|
||||
writer->pt++;
|
||||
}
|
||||
|
||||
void cbor_close_block_or_list(struct cbor_writer *writer)
|
||||
{
|
||||
check_memory(writer, 2);
|
||||
writer->cbor[writer->pt] = 0xff;
|
||||
writer->pt++;
|
||||
}
|
||||
|
||||
void cbor_open_block_with_length(struct cbor_writer *writer, uint32_t length)
|
||||
{
|
||||
write_item(writer, 5, length);
|
||||
}
|
||||
|
||||
void cbor_open_list_with_length(struct cbor_writer *writer, uint32_t length)
|
||||
{
|
||||
write_item(writer, 4, length);
|
||||
}
|
||||
|
||||
|
||||
void cbor_add_int(struct cbor_writer *writer, int64_t item)
|
||||
{
|
||||
if (item >= 0)
|
||||
{
|
||||
write_item(writer, 0, item); // 0 is the "major" (three bits) introducing positive int, 1 is for negative
|
||||
}
|
||||
else
|
||||
{
|
||||
write_item(writer, 1, -item - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void cbor_epoch_time(struct cbor_writer *writer, int64_t time, int shift)
|
||||
{
|
||||
write_item(writer, 6, 1); // 6 is TAG, 1 is tag number for epoch time
|
||||
cbor_relativ_time(writer, time, shift);
|
||||
}
|
||||
|
||||
void cbor_relativ_time(struct cbor_writer *writer, int64_t time, int shift)
|
||||
{
|
||||
write_item(writer, 6, 4); // 6 is TAG, 4 is tag number for decimal fraction
|
||||
cbor_open_list_with_length(writer, 2);
|
||||
cbor_add_int(writer, shift);
|
||||
cbor_add_int(writer, time);
|
||||
}
|
||||
|
||||
void cbor_add_ipv4(struct cbor_writer *writer, ip4_addr addr)
|
||||
{
|
||||
write_item(writer, 6, 52); // 6 is TAG, 52 is tag number for ipv4
|
||||
write_item(writer, 2, 4); // bytestring of length 4
|
||||
put_ip4(&writer->cbor[writer->pt], addr);
|
||||
writer->pt += 4;
|
||||
}
|
||||
|
||||
void cbor_add_ipv6(struct cbor_writer *writer, ip6_addr addr)
|
||||
{
|
||||
write_item(writer, 6, 54); // 6 is TAG, 54 is tag number for ipv6
|
||||
write_item(writer, 2, 16); // bytestring of length 16
|
||||
put_ip6(&writer->cbor[writer->pt], addr);
|
||||
writer->pt += 16;
|
||||
}
|
||||
|
||||
|
||||
void cbor_add_ipv4_prefix(struct cbor_writer *writer, net_addr_ip4 *n)
|
||||
{
|
||||
write_item(writer, 6, 52); // 6 is TAG, 52 is tag number for ipv4
|
||||
cbor_open_block_with_length(writer, 2);
|
||||
cbor_add_int(writer, n->pxlen);
|
||||
write_item(writer, 2, 4); // bytestring of length 4
|
||||
put_ip4(&writer->cbor[writer->pt], n->prefix);
|
||||
writer->pt += 4;
|
||||
}
|
||||
|
||||
|
||||
void cbor_add_ipv6_prefix(struct cbor_writer *writer, net_addr_ip6 *n)
|
||||
{
|
||||
write_item(writer, 6, 54); // 6 is TAG, 54 is tag number for ipv6
|
||||
cbor_open_block_with_length(writer, 2);
|
||||
cbor_add_int(writer, n->pxlen);
|
||||
|
||||
write_item(writer, 2, 16);
|
||||
put_ip6(&writer->cbor[writer->pt], n->prefix);
|
||||
writer->pt += 16;
|
||||
}
|
||||
|
||||
|
||||
void cbor_add_uint(struct cbor_writer *writer, uint64_t item)
|
||||
{
|
||||
write_item(writer, 0, item);
|
||||
}
|
||||
|
||||
void cbor_add_tag(struct cbor_writer *writer, int item)
|
||||
{
|
||||
write_item(writer, 6, item);
|
||||
}
|
||||
|
||||
void cbor_add_string(struct cbor_writer *writer, const char *string)
|
||||
{
|
||||
int length = strlen(string);
|
||||
write_item(writer, 3, length); // 3 is major, then goes length of string and string
|
||||
check_memory(writer, length);
|
||||
memcpy(writer->cbor+writer->pt, string, length);
|
||||
writer->pt+=length;
|
||||
}
|
||||
|
||||
void cbor_nonterminated_string(struct cbor_writer *writer, const char *string, uint32_t length)
|
||||
{
|
||||
write_item(writer, 3, length); // 3 is major, then goes length of string and string
|
||||
check_memory(writer, length);
|
||||
memcpy(writer->cbor+writer->pt, string, length);
|
||||
writer->pt+=length;
|
||||
}
|
||||
|
||||
void write_item(struct cbor_writer *writer, uint8_t major, uint64_t num)
|
||||
{
|
||||
//log("write major %i %li", major, num);
|
||||
major = major<<5;
|
||||
check_memory(writer, 10);
|
||||
if (num > ((uint64_t)1<<(4*8))-1)
|
||||
{ // We need 8 bytes to encode the num
|
||||
major += 0x1b; // reserving those bytes
|
||||
writer->cbor[writer->pt] = major;
|
||||
writer->pt++;
|
||||
for (int i = 7; i>=0; i--)
|
||||
{ // write n-th byte of num
|
||||
uint8_t to_write = (num>>(i*8)) & 0xff;
|
||||
writer->cbor[writer->pt] = to_write;
|
||||
writer->pt++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (num > (1<<(2*8))-1)
|
||||
{ // We need 4 bytes to encode the num
|
||||
major += 0x1a; // reserving those bytes
|
||||
writer->cbor[writer->pt] = major;
|
||||
writer->pt++;
|
||||
for (int i = 3; i>=0; i--)
|
||||
{ // write n-th byte of num
|
||||
uint8_t to_write = (num>>(i*8)) & 0xff;
|
||||
writer->cbor[writer->pt] = to_write;
|
||||
writer->pt++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (num > (1<<(8))-1)
|
||||
{ // We need 2 bytes to encode the num
|
||||
major += 0x19; // reserving those bytes
|
||||
writer->cbor[writer->pt] = major;
|
||||
writer->pt++;
|
||||
for (int i = 1; i>=0; i--)
|
||||
{ // write n-th byte of num
|
||||
uint8_t to_write = (num>>(i*8)) & 0xff;
|
||||
writer->cbor[writer->pt] = to_write;
|
||||
writer->pt++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (num > 23)
|
||||
{ // byte is enough, but aditional value would be too big
|
||||
major += 0x18; // reserving that byte
|
||||
writer->cbor[writer->pt] = major;
|
||||
writer->pt++;
|
||||
uint8_t to_write = num & 0xff;
|
||||
writer->cbor[writer->pt] = to_write;
|
||||
writer->pt++;
|
||||
return;
|
||||
}
|
||||
//log("write item major %i num %i writer->pt %i writer->capacity %i writer %i", major, num, writer->pt, writer->capacity, writer);
|
||||
major += num; // we can store the num as additional value
|
||||
writer->cbor[writer->pt] = major;
|
||||
writer->pt++;
|
||||
}
|
||||
|
||||
void cbor_write_item_with_constant_val_length_4(struct cbor_writer *writer, uint8_t major, uint64_t num)
|
||||
{
|
||||
// this is only for headers which should be constantly long.
|
||||
major = major<<5;
|
||||
check_memory(writer, 10);
|
||||
major += 0x1a; // reserving those bytes
|
||||
writer->cbor[writer->pt] = major;
|
||||
writer->pt++;
|
||||
for (int i = 3; i>=0; i--)
|
||||
{ // write n-th byte of num
|
||||
uint8_t to_write = (num>>(i*8)) & 0xff;
|
||||
writer->cbor[writer->pt] = to_write;
|
||||
writer->pt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rewrite_4bytes_int(struct cbor_writer *writer, int pt, int num)
|
||||
{
|
||||
for (int i = 3; i>=0; i--)
|
||||
{
|
||||
uint8_t to_write = (num>>(i*8)) & 0xff;
|
||||
writer->cbor[pt] = to_write;
|
||||
pt++;
|
||||
}
|
||||
}
|
||||
|
||||
void check_memory(struct cbor_writer *writer, int add_size)
|
||||
{
|
||||
if (writer->capacity - writer->pt-add_size < 0)
|
||||
{
|
||||
bug("There is not enough space for cbor response in given buffer");
|
||||
}
|
||||
}
|
58
lib/cbor.h
Normal file
58
lib/cbor.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef CBOR_H
|
||||
#define CBOR_H
|
||||
|
||||
#include "nest/bird.h"
|
||||
|
||||
|
||||
struct cbor_writer {
|
||||
int pt; // where will next byte go
|
||||
int capacity;
|
||||
int8_t *cbor;
|
||||
struct linpool *lp;
|
||||
};
|
||||
|
||||
|
||||
struct cbor_writer *cbor_init(uint8_t *buff, uint32_t capacity, struct linpool *lp);
|
||||
|
||||
void cbor_open_block(struct cbor_writer *writer);
|
||||
|
||||
void cbor_open_list(struct cbor_writer *writer);
|
||||
|
||||
void cbor_close_block_or_list(struct cbor_writer *writer);
|
||||
|
||||
void cbor_open_block_with_length(struct cbor_writer *writer, uint32_t length);
|
||||
|
||||
void cbor_open_list_with_length(struct cbor_writer *writer, uint32_t length);
|
||||
|
||||
|
||||
void cbor_add_int(struct cbor_writer *writer, int64_t item);
|
||||
|
||||
void cbor_add_ipv4(struct cbor_writer *writer, ip4_addr);
|
||||
|
||||
void cbor_add_ipv6(struct cbor_writer *writer, ip6_addr);
|
||||
|
||||
void cbor_epoch_time(struct cbor_writer *writer, int64_t time, int shift);
|
||||
|
||||
void cbor_relativ_time(struct cbor_writer *writer, int64_t time, int shift);
|
||||
|
||||
void cbor_add_ipv4_prefix(struct cbor_writer *writer, net_addr_ip4 *n);
|
||||
|
||||
|
||||
void cbor_add_ipv6_prefix(struct cbor_writer *writer, net_addr_ip6 *n);
|
||||
|
||||
|
||||
void cbor_add_uint(struct cbor_writer *writer, uint64_t item);
|
||||
|
||||
void cbor_add_tag(struct cbor_writer *writer, int item);
|
||||
|
||||
void cbor_add_string(struct cbor_writer *writer, const char *string);
|
||||
|
||||
void cbor_nonterminated_string(struct cbor_writer *writer, const char *string, uint32_t length);
|
||||
|
||||
void write_item(struct cbor_writer *writer, uint8_t major, uint64_t num);
|
||||
|
||||
void cbor_write_item_with_constant_val_length_4(struct cbor_writer *writer, uint8_t major, uint64_t num);
|
||||
|
||||
void rewrite_4bytes_int(struct cbor_writer *writer, int pt, int num);
|
||||
|
||||
#endif
|
69
lib/cbor_parse_tools.c
Normal file
69
lib/cbor_parse_tools.c
Normal file
@ -0,0 +1,69 @@
|
||||
#include <string.h>
|
||||
#include "lib/cbor_parse_tools.h"
|
||||
|
||||
uint compare_buff_str(struct buff_reader *buf_read, uint length, char *string) {
|
||||
if (length != strlen(string)) {
|
||||
return 0;
|
||||
}
|
||||
for (size_t i = 0; i < strlen(string); i++) {
|
||||
if (buf_read->buff[i+buf_read->pt]!=string[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
};
|
||||
|
||||
struct value
|
||||
get_value(struct buff_reader *reader)
|
||||
{
|
||||
struct value val;
|
||||
byte *buff = reader->buff;
|
||||
val.major = buff[reader->pt]>>5;
|
||||
int first_byte_val = buff[reader->pt] - (val.major<<5);
|
||||
if (first_byte_val <=23) {
|
||||
val.val = first_byte_val;
|
||||
reader->pt++;
|
||||
} else if (first_byte_val == 0x18)
|
||||
{
|
||||
val.val = buff[reader->pt+1];
|
||||
reader->pt+=2;
|
||||
} else if (first_byte_val == 0x19)
|
||||
{
|
||||
val.val = buff[reader->pt+1];
|
||||
val.val = val.val << 8;
|
||||
val.val += buff[reader->pt+2];
|
||||
reader->pt += 3;
|
||||
} else if (first_byte_val == 0x1a)
|
||||
{
|
||||
val.val = 0;
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
val.val += buff[reader->pt+i];
|
||||
val.val = val.val << 8;
|
||||
}
|
||||
val.val += buff[reader->pt+4];
|
||||
reader->pt+=5;
|
||||
} else if (first_byte_val == 0x1b)
|
||||
{
|
||||
val.val = 0;
|
||||
for (int i = 1; i < 8; i++) {
|
||||
val.val += buff[reader->pt+i];
|
||||
val.val = val.val << 8;
|
||||
}
|
||||
val.val += buff[reader->pt+8];
|
||||
reader->pt += 9;
|
||||
} else if (first_byte_val == 0x1f)
|
||||
{
|
||||
val.val = -1;
|
||||
reader->pt++;
|
||||
}
|
||||
if (val.major == NEG_INT)
|
||||
val.val = -1 - val.val;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int val_is_break(struct value val)
|
||||
{
|
||||
return val.major == FLOAT && val.val == -1; // break code is 0xff, so the major is same for float and break
|
||||
}
|
42
lib/cbor_parse_tools.h
Normal file
42
lib/cbor_parse_tools.h
Normal file
@ -0,0 +1,42 @@
|
||||
#include "sysdep/config.h"
|
||||
#include "lib/birdlib.h"
|
||||
|
||||
enum functions {
|
||||
SHOW_STATUS = 0,
|
||||
SHOW_MEMORY = 1,
|
||||
SHOW_SYMBOLS = 2,
|
||||
SHOW_OSPF = 3,
|
||||
SHOW_PROTOCOLS = 4,
|
||||
};
|
||||
|
||||
enum cbor_majors {
|
||||
UINT = 0,
|
||||
NEG_INT = 1,
|
||||
BYTE_STR = 2,
|
||||
TEXT = 3,
|
||||
ARRAY = 4,
|
||||
BLOCK = 5,
|
||||
TAG = 6,
|
||||
FLOAT = 7,
|
||||
};
|
||||
|
||||
|
||||
struct value {
|
||||
int major;
|
||||
int64_t val;
|
||||
};
|
||||
|
||||
struct buff_reader {
|
||||
byte *buff;
|
||||
uint pt;
|
||||
uint size;
|
||||
};
|
||||
|
||||
|
||||
uint compare_buff_str(struct buff_reader *buf_read, uint length, char *string);
|
||||
|
||||
struct value
|
||||
get_value(struct buff_reader *reader);
|
||||
|
||||
|
||||
int val_is_break(struct value val);
|
87
lib/cbor_shortcuts.c
Normal file
87
lib/cbor_shortcuts.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lib/cbor_shortcuts.h"
|
||||
|
||||
|
||||
|
||||
void cbor_string_string(struct cbor_writer *writer, char *key, const char *value) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_add_string(writer, value);
|
||||
}
|
||||
|
||||
void cbor_string_int(struct cbor_writer *writer, char *key, int64_t value) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_add_int(writer, value);
|
||||
}
|
||||
|
||||
void cbor_string_uint(struct cbor_writer *writer, char *key, u64 value) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_add_uint(writer, value);
|
||||
}
|
||||
|
||||
void cbor_string_epoch_time(struct cbor_writer *writer, char *key, int64_t time, int shift) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_epoch_time(writer, time, shift);
|
||||
}
|
||||
|
||||
void cbor_string_relativ_time(struct cbor_writer *writer, char *key, int64_t time, int shift) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_relativ_time(writer, time, shift);
|
||||
}
|
||||
|
||||
void cbor_string_ip(struct cbor_writer *writer, char *key, ip_addr addr) {
|
||||
cbor_add_string(writer, key);
|
||||
if (ipa_is_ip4(addr))
|
||||
cbor_add_ipv4(writer, ipa_to_ip4(addr));
|
||||
else
|
||||
cbor_add_ipv6(writer, ipa_to_ip6(addr));
|
||||
}
|
||||
|
||||
void cbor_string_ipv4(struct cbor_writer *writer, char *key, ip4_addr addr) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_add_ipv4(writer, addr);
|
||||
}
|
||||
|
||||
void cbor_string_ipv6(struct cbor_writer *writer, char *key, ip6_addr addr) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_add_ipv6(writer, addr);
|
||||
}
|
||||
|
||||
void cbor_named_block_two_ints(struct cbor_writer *writer, char *key, char *name1, int val1, char *name2, int val2) {
|
||||
cbor_add_string(writer, key);
|
||||
cbor_open_block_with_length(writer, 2);
|
||||
cbor_add_string(writer, name1);
|
||||
cbor_add_int(writer, val1);
|
||||
cbor_add_string(writer, name2);
|
||||
cbor_add_int(writer, val2);
|
||||
}
|
||||
|
||||
void cbor_write_to_file(struct cbor_writer *writer, char *filename) {
|
||||
FILE *write_ptr;
|
||||
|
||||
write_ptr = fopen(filename, "wb");
|
||||
|
||||
fwrite(writer->cbor, writer->pt, 1, write_ptr);
|
||||
fclose(write_ptr);
|
||||
}
|
||||
|
||||
void cbor_add_net(struct cbor_writer *writer, const net_addr *N) {
|
||||
// Original switch comes from lib/net.c and contains more cases.
|
||||
net_addr_union *n = (void *) N;
|
||||
|
||||
switch (n->n.type)
|
||||
{
|
||||
case NET_IP4:
|
||||
cbor_add_ipv4_prefix(writer, &n->ip4);
|
||||
return;
|
||||
case NET_IP6:
|
||||
cbor_add_ipv6_prefix(writer, &n->ip6);
|
||||
return;
|
||||
default:
|
||||
bug("net type unsupported by cbor (yet).");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
26
lib/cbor_shortcuts.h
Normal file
26
lib/cbor_shortcuts.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef CBOR_SHORTCUTS_H
|
||||
#define CBOR_SHORTCUTS_H
|
||||
|
||||
#include "lib/cbor.h"
|
||||
#include "sysdep/config.h"
|
||||
#include "lib/birdlib.h"
|
||||
#include "nest/protocol.h"
|
||||
#include "lib/ip.h"
|
||||
|
||||
|
||||
void cbor_string_string(struct cbor_writer *writer, char *key, const char *value);
|
||||
|
||||
void cbor_string_int(struct cbor_writer *writer, char *key, int64_t value);
|
||||
|
||||
void cbor_string_epoch_time(struct cbor_writer *writer, char *key, int64_t time, int shift);
|
||||
void cbor_string_relativ_time(struct cbor_writer *writer, char *key, int64_t time, int shift);
|
||||
void cbor_string_uint(struct cbor_writer *writer, char *key, u64 value);
|
||||
void cbor_string_ip(struct cbor_writer *writer, char *key, ip_addr);
|
||||
void cbor_string_ipv4(struct cbor_writer *writer, char *key, ip4_addr);
|
||||
void cbor_string_ipv6(struct cbor_writer *writer, char *key, ip6_addr);
|
||||
void cbor_named_block_two_ints(struct cbor_writer *writer, char *key, char *name1, int val1, char *name2, int val2);
|
||||
void cbor_write_to_file(struct cbor_writer *writer, char *filename);
|
||||
|
||||
void cbor_add_net(struct cbor_writer *writer, const net_addr *N);
|
||||
|
||||
#endif
|
137
lib/cbor_test.c
Normal file
137
lib/cbor_test.c
Normal file
@ -0,0 +1,137 @@
|
||||
|
||||
#include "test/birdtest.h"
|
||||
#include "lib/cbor.h"
|
||||
#include "lib/cbor_parse_tools.h"
|
||||
|
||||
#define BUFF_LEN 100
|
||||
|
||||
struct cbor_writer *w;
|
||||
struct buff_reader reader;
|
||||
|
||||
void print_to_file_for_control_from_outside(void)
|
||||
{
|
||||
FILE *write_ptr;
|
||||
|
||||
write_ptr = fopen("a.cbor", "wb");
|
||||
|
||||
fwrite(w->cbor, w->pt, 1, write_ptr);
|
||||
fclose(write_ptr);
|
||||
|
||||
}
|
||||
|
||||
static int test_int(void)
|
||||
{
|
||||
reader.pt = w->pt = 0;
|
||||
int num_items = 13;
|
||||
int64_t test_int[] = {-123456789012345678, -1234567890, -12345, -123, -25, -13, 0, 13, 25, 123, 12345, 1234567890, 123456789012345678};
|
||||
byte bin_int[] = {0x8d, 0x3b, 0x1, 0xb6, 0x9b, 0x4b, 0xa6, 0x30, 0xf3, 0x4d, 0x3a, 0x49, 0x96, 0x2, 0xd1, 0x39, 0x30, 0x38, 0x38, 0x7a, 0x38, 0x18, 0x2c, 0x0, 0xd, 0x18, 0x19, 0x18, 0x7b, 0x19, 0x30, 0x39, 0x1a, 0x49, 0x96, 0x2, 0xd2, 0x1b, 0x1, 0xb6, 0x9b, 0x4b, 0xa6, 0x30, 0xf3, 0x4e};
|
||||
cbor_open_list_with_length(w, num_items);
|
||||
for (int i = 0; i < num_items; i++)
|
||||
{
|
||||
cbor_add_int(w, test_int[i]);
|
||||
}
|
||||
|
||||
for (long unsigned int i = 0; i < sizeof(bin_int); i++)
|
||||
{
|
||||
bt_assert((w->cbor[i] & 0xff) == (bin_int[i] & 0xff));
|
||||
}
|
||||
|
||||
struct value val = get_value(&reader);
|
||||
bt_assert(val.major = ARRAY);
|
||||
bt_assert(val.val = num_items);
|
||||
for (int i = 0; i < num_items; i++)
|
||||
{
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == NEG_INT || val.major == UINT);
|
||||
bt_assert(val.val == test_int[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int non_aligned_int(void)
|
||||
{
|
||||
w->pt = reader.pt = 0;
|
||||
int num_items = 4;
|
||||
cbor_open_list_with_length(w, num_items);
|
||||
|
||||
cbor_add_int(w, 30);
|
||||
w->cbor[w->pt - 1] = 1;
|
||||
|
||||
cbor_add_int(w, 300);
|
||||
w->cbor[w->pt - 2] = 0;
|
||||
w->cbor[w->pt - 1] = 1;
|
||||
|
||||
cbor_add_int(w, 300000000);
|
||||
for (int i = 4; i > 1; i--)
|
||||
{
|
||||
w->cbor[w->pt - i] = 0;
|
||||
}
|
||||
w->cbor[w->pt - 1] = 1;
|
||||
|
||||
cbor_add_int(w, 30000000000000000);
|
||||
for (int i = 8; i > 1; i--)
|
||||
{
|
||||
w->cbor[w->pt - i] = 0;
|
||||
}
|
||||
w->cbor[w->pt - 1] = 1;
|
||||
|
||||
struct value val = get_value(&reader);
|
||||
bt_assert(val.major = ARRAY);
|
||||
bt_assert(val.val = num_items);
|
||||
|
||||
for (int i = 0; i < num_items; i++)
|
||||
{
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == UINT);
|
||||
bt_assert(val.val == 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_majors(void)
|
||||
{
|
||||
w->pt = reader.pt = 0;
|
||||
cbor_open_block(w);
|
||||
cbor_open_list_with_length(w, 4);
|
||||
cbor_add_string(w, "b");
|
||||
cbor_add_int(w, 1);
|
||||
cbor_add_int(w, -1);
|
||||
cbor_add_ipv4(w, ip4_build(18, 4, 0, 0));
|
||||
cbor_close_block_or_list(w);
|
||||
|
||||
struct value val = get_value(&reader);
|
||||
bt_assert(val.major == BLOCK);
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == ARRAY);
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == TEXT);
|
||||
reader.pt += val.val;
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == UINT);
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == NEG_INT);
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == TAG);
|
||||
val = get_value(&reader);
|
||||
bt_assert(val.major == BYTE_STR);
|
||||
reader.pt += val.val;
|
||||
val = get_value(&reader);
|
||||
bt_assert(val_is_break(val));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
bt_init(argc, argv);
|
||||
byte buff[BUFF_LEN];
|
||||
w = cbor_init(buff, BUFF_LEN, tmp_linpool);
|
||||
reader.buff = buff;
|
||||
reader.size = BUFF_LEN;
|
||||
reader.pt = 0;
|
||||
|
||||
bt_test_suite(test_int, "Adding and reading integer from cbor.");
|
||||
bt_test_suite(non_aligned_int, "Reading non-alligned int from cbor.");
|
||||
bt_test_suite(test_majors, "Test cbor datatypes.");
|
||||
|
||||
return bt_exit_value();
|
||||
}
|
Loading…
Reference in New Issue
Block a user