PatchworkOS
Loading...
Searching...
No Matches
package_length.c
Go to the documentation of this file.
2
6
7#include <errno.h>
8#include <stdint.h>
9
11{
12 uint8_t pkgLeadByte;
13 if (aml_byte_data_read(ctx, &pkgLeadByte) == ERR)
14 {
15 AML_DEBUG_ERROR(ctx, "Failed to read ByteData");
16 return ERR;
17 }
18
19 out->byteDataCount = (pkgLeadByte >> 6) & 0x03; // bits (7-6)
20 out->smallLengthBits = pkgLeadByte & 0x3F; // bits (5-0)
21 out->leastSignificantNybble = pkgLeadByte & 0x0F; // bits (3-0)
22
23 // If more bytes follow, then bits 4 and 5 must be zero.
24 if (out->byteDataCount != 0 && ((pkgLeadByte >> 4) & 0x03) != 0)
25 {
26 AML_DEBUG_ERROR(ctx, "Invalid PkgLeadByte '0x%x'", pkgLeadByte);
27 errno = EILSEQ;
28 return ERR;
29 }
30
31 return 0;
32}
33
35{
36 const uint8_t* start = ctx->current;
37
38 aml_pkg_lead_byte_t pkgLeadByte;
39 if (aml_pkg_lead_byte_read(ctx, &pkgLeadByte) == ERR)
40 {
41 AML_DEBUG_ERROR(ctx, "Failed to read PkgLeadByte");
42 return ERR;
43 }
44
45 // If no bytes follow, then the smallLengthBits store the package length.
46 if (pkgLeadByte.byteDataCount == 0)
47 {
48 *out = pkgLeadByte.smallLengthBits;
49 return 0;
50 }
51
52 // Bits 0 to 3 in pkgLeadByte becomes the least significant bits in the length, followed by the next bytes.
53 aml_pkg_length_t length = pkgLeadByte.leastSignificantNybble;
54 for (uint32_t i = 0; i < pkgLeadByte.byteDataCount; i++)
55 {
56 uint8_t byte;
57 if (aml_byte_data_read(ctx, &byte) == ERR)
58 {
59 AML_DEBUG_ERROR(ctx, "Failed to read ByteData");
60 return ERR;
61 }
62 length |= ((uint32_t)byte) << (4 + i * 8);
63 }
64
65 // Output must not be greater than 2^28.
66 if (length > (1ULL << 28))
67 {
68 AML_DEBUG_ERROR(ctx, "Package length out of range: %lu", length);
69 errno = ERANGE;
70 return ERR;
71 }
72
73 *out = length;
74 return 0;
75}
#define AML_DEBUG_ERROR(ctx, format,...)
Macro to simplify calling aml_debug_error() with the current function name.
Definition debug.h:30
uint64_t aml_byte_data_read(aml_term_list_ctx_t *ctx, uint8_t *out)
Read a ByteData structure from the AML stream.
Definition data.c:16
uint32_t aml_pkg_length_t
PkgLength structure.
uint64_t aml_pkg_length_read(aml_term_list_ctx_t *ctx, aml_pkg_length_t *out)
Reads a PkgLength structure from the AML byte stream.
uint64_t aml_pkg_lead_byte_read(aml_term_list_ctx_t *ctx, aml_pkg_lead_byte_t *out)
Reads a PkgLeadByte structure from the AML byte stream.
#define ERANGE
Math result not representable.
Definition errno.h:202
#define errno
Error number variable.
Definition errno.h:27
#define EILSEQ
Illegal byte sequence.
Definition errno.h:447
#define ERR
Integer error value.
Definition ERR.h:17
static void start()
Definition main.c:542
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
PkgLeadByte structure.
uint8_t byteDataCount
Amount of ByteData structures that come after the lead byte.
uint8_t leastSignificantNybble
Least significant nybble of the package length.
Context for reading a TermList.
Definition term.h:37
const uint8_t * current
Definition term.h:42