ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
book_chunked.c
Go to the documentation of this file.
1
19#include "book_chunked.h"
20
21#include <string.h>
22
23#include "book_internal.h"
24#include "ra8_attributes.h"
25#include "ra8_check.h"
26
28static const char* const s_tag_chunked = "book_chunked";
29
58static ra8_err_t
59internal_table_check(const book_chunked_t* rd, const uint64_t* table_buf, uint64_t payload_len)
60{
61 if (table_buf[0] != 0U) {
63 }
64 uint64_t max_clen = 0U;
65 for (uint32_t i = 0U; i < rd->chunk_count; ++i) { /* bound: validated chunk_count */
66 if (table_buf[i + 1U] <= table_buf[i]) {
68 }
69 const uint64_t clen = table_buf[i + 1U] - table_buf[i];
70 if (clen > max_clen) {
71 max_clen = clen;
72 }
73 }
74 if (table_buf[rd->chunk_count] != payload_len) {
76 }
77 if (max_clen > (uint64_t)rd->staging_cap) {
79 }
80 return k_ra8_ok;
81}
82
118 uint64_t file_len,
119 uint64_t* table_buf,
120 uint32_t table_cap_entries)
121{
122 const uint64_t entries = (uint64_t)rd->chunk_count + 1U;
123 const uint64_t table_bytes = entries * k_book_container_entry_len;
124 if (entries > (uint64_t)table_cap_entries) {
126 }
127 if (table_bytes > (uint64_t)UINT32_MAX) {
129 }
130 if (file_len < ((uint64_t)k_book_container_header_len + table_bytes)) {
132 }
133 const ra8_err_t err = rd->file_read(rd->file_ctx,
135 (uint8_t*)table_buf,
136 (uint32_t)table_bytes);
137 if (err != k_ra8_ok) {
138 return err;
139 }
140 const uint64_t payload_off = (uint64_t)k_book_container_header_len + table_bytes;
141 const ra8_err_t shape = internal_table_check(rd, table_buf, file_len - payload_off);
142 if (shape != k_ra8_ok) {
143 return shape;
144 }
145 rd->table = table_buf;
146 rd->table_cap_entries = table_cap_entries;
147 rd->payload_off = payload_off;
148 return k_ra8_ok;
149}
150
182 uint64_t file_len,
183 uint64_t* table_buf,
184 uint32_t table_cap_entries)
185{
186 if (file_len < (uint64_t)k_book_container_header_len) {
188 }
189 uint8_t hdr[k_book_container_header_len] = {};
190 ra8_err_t err = rd->file_read(rd->file_ctx, 0U, hdr, (uint32_t)sizeof(hdr));
191 if (err != k_ra8_ok) {
192 return err;
193 }
194 err =
196 if (err != k_ra8_ok) {
197 return err;
198 }
199 return internal_load_table(rd, file_len, table_buf, table_cap_entries);
200}
201
203 ra8_vsource_read_fn file_read,
204 void* file_ctx,
205 uint64_t file_len,
206 book_inflate_fn inflate,
207 uint64_t* table_buf,
208 uint32_t table_cap_entries,
209 uint8_t* staging,
210 uint32_t staging_cap)
211{
212 RA8_CHECK_NULL_PTR(rd, s_tag_chunked, "open: null rd");
213 RA8_CHECK_NULL_PTR(file_read, s_tag_chunked, "open: null file_read");
214 RA8_CHECK_NULL_PTR(inflate, s_tag_chunked, "open: null inflate");
215 RA8_CHECK_NULL_PTR(table_buf, s_tag_chunked, "open: null table_buf");
216 RA8_CHECK_NULL_PTR(staging, s_tag_chunked, "open: null staging");
217
218 *rd = (book_chunked_t){};
219 rd->file_read = file_read;
220 rd->file_ctx = file_ctx;
221 rd->inflate_cb = inflate;
222 rd->staging = staging;
223 rd->staging_cap = staging_cap;
224 return internal_chunked_open_body(rd, file_len, table_buf, table_cap_entries);
225}
226
257static ra8_err_t
258internal_stage_and_inflate(const book_chunked_t* rd, uint32_t idx, uint8_t* buf, uint32_t len)
259{
260 const uint64_t clen = rd->table[idx + 1U] - rd->table[idx];
261 ra8_err_t err =
262 rd->file_read(rd->file_ctx, rd->payload_off + rd->table[idx], rd->staging, (uint32_t)clen);
263 if (err != k_ra8_ok) {
264 return err;
265 }
266 size_t produced = 0U;
267 err = rd->inflate_cb(rd->staging, (size_t)clen, buf, (size_t)len, &produced);
268 if (err != k_ra8_ok) {
269 return err;
270 }
271 if (produced != (size_t)len) {
273 }
274 return k_ra8_ok;
275}
276
277ra8_err_t book_chunked_read(void* ctx, uint64_t offset, uint8_t* buf, uint32_t len)
278{
279 RA8_CHECK_NULL_PTR(ctx, s_tag_chunked, "read: null ctx");
280 RA8_CHECK_NULL_PTR(buf, s_tag_chunked, "read: null buf");
281 const book_chunked_t* rd = (const book_chunked_t*)ctx;
282 if (rd->table == nullptr) {
284 }
285 if (offset >= rd->inflated_total) {
287 }
288 if ((offset % (uint64_t)rd->chunk_bytes) != 0U) {
290 }
291 uint64_t expected = rd->inflated_total - offset;
292 if (expected > (uint64_t)rd->chunk_bytes) {
293 expected = rd->chunk_bytes;
294 }
295 if ((uint64_t)len != expected) {
297 }
298 return internal_stage_and_inflate(rd, (uint32_t)(offset / (uint64_t)rd->chunk_bytes), buf, len);
299}
ra8_err_t priv_book_container_header_fields(const uint8_t *hdr, uint32_t *out_chunk_bytes, uint64_t *out_total, uint32_t *out_count)
Implementation of priv_book_container_header_fields() – memcpy field decode.
Definition book.c:290
@ k_book_container_header_len
Fixed header bytes ahead of the chunk table.
Definition book.h:115
@ k_book_container_entry_len
One chunk-table entry (uint64 LE offset).
Definition book.h:116
ra8_err_t(* book_inflate_fn)(const void *src, size_t src_len, void *dst, size_t dst_cap, size_t *out_len)
Caller-supplied DEFLATE inflater used by book_open().
Definition book.h:656
static ra8_err_t internal_table_check(const book_chunked_t *rd, const uint64_t *table_buf, uint64_t payload_len)
Validate a loaded chunk table's shape against the payload extent.
static ra8_err_t internal_stage_and_inflate(const book_chunked_t *rd, uint32_t idx, uint8_t *buf, uint32_t len)
Stage one chunk's compressed stream and inflate it into buf.
ra8_err_t book_chunked_read(void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
Serve one chunk-aligned read of the inflated flat blob.
static ra8_err_t internal_chunked_open_body(book_chunked_t *rd, uint64_t file_len, uint64_t *table_buf, uint32_t table_cap_entries)
The argument-checked body of book_chunked_open.
static ra8_err_t internal_load_table(book_chunked_t *rd, uint64_t file_len, uint64_t *table_buf, uint32_t table_cap_entries)
Load + validate the chunk table through the file reader.
static const char *const s_tag_chunked
Log tag for chunk-reader diagnostics.
ra8_err_t book_chunked_open(book_chunked_t *rd, ra8_vsource_read_fn file_read, void *file_ctx, uint64_t file_len, book_inflate_fn inflate, uint64_t *table_buf, uint32_t table_cap_entries, uint8_t *staging, uint32_t staging_cap)
Open a chunked .rabook container for demand-paged chunk reads.
Demand-paged chunk reader for the "RBKC" .rabook container.
book DOM-walk helpers shared across the library's translation units.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_invalid_state
Module in wrong state for requested operation.
Definition ra8_err.h:161
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_invalid_size
Invalid size parameter (too large, too small, or misaligned).
Definition ra8_err.h:167
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
ra8_err_t(* ra8_vsource_read_fn)(void *ctx, uint64_t offset, uint8_t *buf, uint32_t len)
Read len bytes at offset from a paged object's backing.
Definition ra8_vsource.h:79
One open chunked .rabook file: parsed geometry + caller storage.
uint64_t inflated_total
Served flat-blob length.
ra8_vsource_read_fn file_read
Container byte reader.
uint8_t * staging
Compressed-byte staging.
book_inflate_fn inflate_cb
zlib decompressor.
const uint64_t * table
Chunk offsets.
void * file_ctx
Reader context.
uint32_t chunk_count
Chunk count.
uint32_t table_cap_entries
Table entry capacity.
uint32_t chunk_bytes
Inflated bytes per chunk.
uint64_t payload_off
First stream file offset.
uint32_t staging_cap
Staging byte capacity.