Skip to content

Commit

Permalink
Merge pull request #31 from vteromero/new-api
Browse files Browse the repository at this point in the history
New VTEnc API
  • Loading branch information
vteromero authored Feb 25, 2022
2 parents aeb6213 + 48d4b05 commit fa06cd4
Show file tree
Hide file tree
Showing 18 changed files with 855 additions and 770 deletions.
126 changes: 63 additions & 63 deletions CODING_STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,97 +11,97 @@ The rules don't follow any particular order and don't intend to cover every sing
1. Use 2-spaced indentation.

2. This is the preferred style for statement braces (`if`, `for`, `switch`, etc.):
```c
if (condition) {
```c
if (condition) {
do_x();
} else {
} else {
do_y();
}
```
}
```

3. Braces can be skipped when there's only one statement:
```c
if (condition)
do_x();
```
```c
if (condition)
do_x();
```

4. This is also acceptable when line is not too long:
```c
if (condition) return -1;
```
```c
if (condition) return -1;
```

5. Functions are a special case, with opening brace at the beginning of a new line:
```c
int function(int x)
{
/* Body goes here */
}
```
```c
int function(int x)
{
/* Body goes here */
}
```

6. Put a space after these keywords: `if, switch, case, for, do, while`

7. When declaring pointers, the preferred use of * is adjacent to the data name or function name and not adjacent to the type name:
```c
char *str;
char *copy_str(const char *str);
```
```c
char *str;
char *copy_str(const char *str);
```

8. Avoid using typedefs as much as possible. Read rationale here: https://www.kernel.org/doc/html/v4.10/process/coding-style.html#typedefs

9. Function names are `snake_case`:
```c
int process_request(const struct *request);
```
```c
int process_request(const struct *request);
```

10. Variable names are `snake_case`:
```c
size_t arr_len;
char *tmp, *filter_name;
```
```c
size_t arr_len;
char *tmp, *filter_name;
```

11. Struct names are `snake_case`:
```c
struct decoding_ctx {
size_t processed;
size_t remaining;
};
```
```c
struct decoding_ctx {
size_t processed;
size_t remaining;
};
```

12. Enum names are `snake_case`:
```c
enum response_error {
BAD_REQUEST_ERROR,
UNREACHABLE_ERROR
};
```
```c
enum response_error {
BAD_REQUEST_ERROR,
UNREACHABLE_ERROR
};
```

13. Names of macros defining constants are `CAPITALISED`:
```c
#define MAGIC_NUMBER 42
```
```c
#define MAGIC_NUMBER 42
```

14. Labels in enums are `CAPITALISED`:
```c
enum {
PERSIST,
CONTINUE,
ABORT
};
```
```c
enum {
PERSIST,
CONTINUE,
ABORT
};
```

15. Macros resembling functions may be named in lower case:
```c
#define list_add(list, element)
```
```c
#define list_add(list, element)
```

16. The preferred style for multi-line comments is:
```c
/*
* This is a multi-line comment that doesn't fit in a
* single line.
*
* Leave a blank line between paragraphs within the block
* comment.
*/
```
```c
/*
* This is a multi-line comment that doesn't fit in a
* single line.
*
* Leave a blank line between paragraphs within the block
* comment.
*/
```

136 changes: 77 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,96 +27,114 @@ For reference, VTEnc has been tested on a laptop Ubuntu Desktop 19.10 with a Cor

The documented interface is found in the header file `vtenc.h`.

## Examples

Encoding example:
## Example

```c
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "vtenc.h"

int main()
int encode(
vtenc *handler,
const uint8_t *values,
size_t values_len,
uint8_t **out,
size_t *out_len)
{
const uint8_t in[] = {13, 14, 29, 39, 65, 80, 88, 106, 152, 154, 155, 177};
const size_t in_len = sizeof(in) / sizeof(in[0]);
const size_t out_cap = vtenc_max_encoded_size8(in_len); /* output capacity */
uint8_t *out=NULL;
size_t out_len;
VtencEncoder encoder;

/* initialise `encoder` */
vtenc_encoder_init(&encoder);

/* allocate `out_cap` bytes */
out = (uint8_t *) malloc(out_cap * sizeof(uint8_t));
if (out == NULL) {
const size_t out_cap = vtenc_max_encoded_size8(values_len); /* output capacity */
int rc;

*out = (uint8_t *) malloc(out_cap * sizeof(uint8_t));
if (*out == NULL) {
fprintf(stderr, "allocation error\n");
return 1;
return 0;
}

/* encode `in` list into `out` stream of bytes */
out_len = vtenc_encode8(&encoder, in, in_len, out, out_cap);
if (encoder.last_error_code != VtencErrorNoError) {
fprintf(stderr, "encode failed with code: %d\n", encoder.last_error_code);
free(out);
return 1;
rc = vtenc_encode8(handler, values, values_len, *out, out_cap);
if (rc != VTENC_OK) {
fprintf(stderr, "encode failed with code: %d\n", rc);
return 0;
}

/* here `out` holds the encoded output, which is `out_len` bytes long */

free(out);
*out_len = vtenc_encoded_size(handler);

return 0;
return 1;
}
```

Decoding example:
int decode(
vtenc *handler,
const uint8_t *in,
size_t in_len,
uint8_t **out,
size_t out_len)
{
int rc;

```c
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
*out = (uint8_t *) malloc(out_len * sizeof(uint8_t));
if (*out == NULL) {
fprintf(stderr, "allocation error\n");
return 0;
}

#include "vtenc.h"
rc = vtenc_decode8(handler, in, in_len, *out, out_len);
if (rc != VTENC_OK) {
fprintf(stderr, "decode failed with code: %d\n", rc);
return 0;
}

return 1;
}

int main()
{
const uint8_t in[] = {0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x26,
0x24, 0x8d, 0x75, 0xfd, 0x95, 0x83, 0x9b, 0x03};
const size_t in_len = sizeof(in) / sizeof(in[0]);
uint8_t *out = NULL;
size_t out_len = 12; /* the decoded sequence's size needs to be known here */
VtencDecoder decoder;

/* initialise decoder */
vtenc_decoder_init(&decoder);

/* allocate `out_len` items */
out = (uint8_t *) malloc(out_len * sizeof(uint8_t));
if (out == NULL) {
fprintf(stderr, "allocation error\n");
const uint8_t values[] = {13, 14, 29, 39, 65, 80, 88, 106, 152, 154, 155, 177};
const size_t values_len = sizeof(values) / sizeof(values[0]);
uint8_t *enc_out=NULL, *dec_out=NULL;
size_t enc_out_len;
int rc = 0;
vtenc *handler = vtenc_create();

if (handler == NULL) {
fprintf(stderr, "It failed to create the handler\n");
return 1;
}

/* decode `in` stream of bytes into `out` list */
vtenc_decode8(&decoder, in, in_len, out, out_len);
if (decoder.last_error_code != VtencErrorNoError) {
fprintf(stderr, "decode failed with code: %d\n", decoder.last_error_code);
free(out);
return 1;
if (!encode(handler, values, values_len, &enc_out, &enc_out_len)) {
rc = 1;
goto free_and_return;
}

/* here `out` holds the decoded list of integers, of size `out_len` */
if (!decode(handler, enc_out, enc_out_len, &dec_out, values_len)) {
rc = 1;
goto free_and_return;
}

printf("Original list: %lu bytes\n", values_len);
printf("Encoded stream: %lu bytes\n", enc_out_len);

if (memcmp(values, dec_out, values_len) == 0) {
printf("Decoded output matches original list\n");
} else {
printf("Decoded output different from original list\n");
rc = 1;
}

free(out);
free_and_return:
if (enc_out != NULL)
free(enc_out);

return 0;
if (dec_out != NULL)
free(dec_out);

vtenc_destroy(handler);

return rc;
}

```
## Limitations
Expand Down
Loading

0 comments on commit fa06cd4

Please sign in to comment.