ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
mdl_report.c
Go to the documentation of this file.
1
9#include "mdl_report.h"
10
11#include <stdint.h>
12#include <stdio.h>
13
14#include "mdl_fetch.h"
15#include "mdl_fetch_internal.h"
16#include "mdl_stream_internal.h"
17#include "ra8_attributes.h"
18
20typedef enum : uint32_t {
22 k_bytes_per_mib = 1024U * 1024U,
23 k_ms_per_sec = 1000U,
29
44RA8_INTERNAL static void internal_fmt_size(uint64_t bytes, char* buf, size_t cap)
45{
46 const double b = (double)bytes;
47 if (bytes >= (uint64_t)k_bytes_per_mib) {
48 (void)snprintf(buf, cap, "%.1f MB", b / (double)k_bytes_per_mib);
49 return;
50 }
51 if (bytes >= (uint64_t)k_bytes_per_kib) {
52 (void)snprintf(buf, cap, "%.1f KB", b / (double)k_bytes_per_kib);
53 return;
54 }
55 (void)snprintf(buf, cap, "%llu B", (unsigned long long)bytes);
56}
57
73RA8_INTERNAL static void
74internal_fmt_rate(uint64_t bytes, uint32_t elapsed_ms, char* buf, size_t cap)
75{
76 if (elapsed_ms == 0U) {
77 (void)snprintf(buf, cap, "-- KB/s");
78 return;
79 }
80 const double bps = ((double)bytes * (double)k_ms_per_sec) / (double)elapsed_ms;
81 if (bps >= (double)k_bytes_per_mib) {
82 (void)snprintf(buf, cap, "%.1f MB/s", bps / (double)k_bytes_per_mib);
83 return;
84 }
85 (void)snprintf(buf, cap, "%.1f KB/s", bps / (double)k_bytes_per_kib);
86}
87
106{
107 error = priv_mdl_stream_text(error, output, "[ch ");
108 error = priv_mdl_stream_u64(error, output, ev->chapter_index);
109 error = priv_mdl_stream_text(error, output, "/");
110 error = priv_mdl_stream_u64(error, output, ev->chapter_total);
111 error = priv_mdl_stream_text(error, output, " ");
112 error = priv_mdl_stream_text(error, output, ev->chapter_id);
113 error = priv_mdl_stream_text(error, output, "] page ");
114 error = priv_mdl_stream_u64(error, output, ev->page_index);
115 error = priv_mdl_stream_text(error, output, "/");
116 return priv_mdl_stream_u64(error, output, ev->page_total);
117}
118
120{
121 if (ev == nullptr) {
122 return k_ra8_ok;
123 }
124 ra8_io_stream_t* output = (ra8_io_stream_t*)ctx;
125 ra8_err_t error = priv_mdl_stream_text(k_ra8_ok, output, " ");
126 error = internal_report_position(error, output, ev);
127 if (ev->reused) {
128 return priv_mdl_stream_text(error, output, " reused\n");
129 }
130 char size[k_human_bytes];
131 char rate[k_human_bytes];
132 internal_fmt_size(ev->page_bytes, size, sizeof(size));
133 internal_fmt_rate(ev->page_bytes, ev->elapsed_ms, rate, sizeof(rate));
134 error = priv_mdl_stream_text(error, output, " ");
135 error = priv_mdl_stream_text(error, output, size);
136 error = priv_mdl_stream_text(error, output, " @ ");
137 error = priv_mdl_stream_text(error, output, rate);
138 return priv_mdl_stream_text(error, output, "\n");
139}
140
158RA8_INTERNAL static uint32_t internal_percent_pad_width(uint32_t pct)
159{
160 if (pct < k_percent_two_digits) {
161 return 2U;
162 }
163 if (pct < k_percent_scale) {
164 return 1U;
165 }
166 return 0U;
167}
168
170{
171 if (ev == nullptr) {
172 return k_ra8_ok;
173 }
174 ra8_io_stream_t* output = (ra8_io_stream_t*)ctx;
175 const size_t bar_width = (size_t)k_progress_bar_width;
176 size_t filled = 0U;
177 if (ev->page_total > 0U) {
178 filled = (ev->page_index * bar_width) / ev->page_total;
179 if (filled > bar_width) {
180 filled = bar_width;
181 }
182 }
183 const uint32_t pct = (ev->page_total > 0U)
184 ? (uint32_t)((ev->page_index * (size_t)k_percent_scale) / ev->page_total)
185 : 0U;
186
187 ra8_err_t error = priv_mdl_stream_text(k_ra8_ok, output, "\r [");
188 error = priv_mdl_stream_repeat(error, output, '=', filled);
189 error = priv_mdl_stream_repeat(error, output, ' ', bar_width - filled);
190 error = priv_mdl_stream_text(error, output, "] ");
191 error = priv_mdl_stream_repeat(error, output, ' ', internal_percent_pad_width(pct));
192 error = priv_mdl_stream_u64(error, output, pct);
193 error = priv_mdl_stream_text(error, output, "% ");
194 error = internal_report_position(error, output, ev);
195 if (ev->reused) {
196 error = priv_mdl_stream_text(error, output, " (reused)");
197 } else {
198 char size[k_human_bytes];
199 char rate[k_human_bytes];
200 internal_fmt_size(ev->page_bytes, size, sizeof(size));
201 internal_fmt_rate(ev->page_bytes, ev->elapsed_ms, rate, sizeof(rate));
202 error = priv_mdl_stream_text(error, output, " (");
203 error = priv_mdl_stream_text(error, output, size);
204 error = priv_mdl_stream_text(error, output, " @ ");
205 error = priv_mdl_stream_text(error, output, rate);
206 error = priv_mdl_stream_text(error, output, ")");
207 }
208 if (ev->page_index >= ev->page_total) {
209 error = priv_mdl_stream_text(error, output, "\n");
210 }
211 return priv_mdl_stream_flush(error, output);
212}
213
215{
216 if (log->total == 0U) {
217 return k_ra8_ok;
218 }
219 ra8_err_t error = priv_mdl_stream_u64(k_ra8_ok, diagnostic, log->total);
220 error = priv_mdl_stream_text(error, diagnostic, " failure(s) this run:\n");
221 for (size_t i = 0U; i < log->count; ++i) {
222 char reason[k_mdl_reason_max];
223 priv_mdl_fetch_reason(log->items[i].err, log->items[i].status, reason, sizeof(reason));
224 error = priv_mdl_stream_text(error, diagnostic, " FAILED ");
225 error = priv_mdl_stream_text(error, diagnostic, log->items[i].url);
226 error = priv_mdl_stream_text(error, diagnostic, " -- ");
227 error = priv_mdl_stream_text(error, diagnostic, reason);
228 error = priv_mdl_stream_text(error, diagnostic, "\n");
229 }
230 if (log->total > log->count) {
231 error = priv_mdl_stream_text(error, diagnostic, " ... and ");
232 error = priv_mdl_stream_u64(error, diagnostic, log->total - log->count);
233 error = priv_mdl_stream_text(error, diagnostic, " more (log truncated)\n");
234 }
235 return error;
236}
@ k_ms_per_sec
Milliseconds per second.
Definition main.c:51
void priv_mdl_fetch_reason(ra8_err_t err, long status, char *buf, size_t cap)
Render a human-readable reason for a transfer result and HTTP status.
Definition mdl_fetch.c:130
State-aware chapter/page download orchestrator for the media downloader.
Module-private fetch-loop decisions promoted for host unit tests and the CLI's end-of-run reporting.
@ k_mdl_reason_max
Failure-reason string buffer bytes.
static uint32_t internal_percent_pad_width(uint32_t pct)
Width of the space padding before a whole-percent value.
Definition mdl_report.c:158
ra8_err_t mdl_report_progress(void *ctx, const mdl_fetch_progress_t *ev)
Per-page progress sink: print one redirect-safe line per page.
Definition mdl_report.c:119
ra8_err_t mdl_report_progress_bar(void *ctx, const mdl_fetch_progress_t *ev)
Per-page progress bar sink: render an in-place terminal progress bar.
Definition mdl_report.c:169
static ra8_err_t internal_report_position(ra8_err_t error, ra8_io_stream_t *output, const mdl_fetch_progress_t *ev)
Append the common chapter and page coordinates for one event.
Definition mdl_report.c:105
static void internal_fmt_rate(uint64_t bytes, uint32_t elapsed_ms, char *buf, size_t cap)
Format a byte transfer rate as a compact string.
Definition mdl_report.c:74
static void internal_fmt_size(uint64_t bytes, char *buf, size_t cap)
Format a byte count as a compact human-readable string.
Definition mdl_report.c:44
mdl_report_scale_t
Human-readable size/rate scaling and buffer sizes.
Definition mdl_report.c:20
@ k_progress_bar_width
Rendered progress-bar cells.
Definition mdl_report.c:25
@ k_bytes_per_mib
Bytes in a mebibyte.
Definition mdl_report.c:22
@ k_percent_scale
Whole-percent conversion scale.
Definition mdl_report.c:26
@ k_percent_two_digits
First two-digit percentage.
Definition mdl_report.c:27
@ k_bytes_per_kib
Bytes in a kibibyte.
Definition mdl_report.c:21
@ k_human_bytes
Size/rate string buffer bytes.
Definition mdl_report.c:24
ra8_err_t mdl_report_failures(ra8_io_stream_t *diagnostic, const mdl_fetch_faillog_t *log)
End-of-run summary: list every failure with its URL and reason.
Definition mdl_report.c:214
Human-facing progress and failure reporting for the mdl CLI.
ra8_err_t priv_mdl_stream_text(ra8_err_t prior, ra8_io_stream_t *stream, const char *text)
Append text unless an earlier operation already failed.
Definition mdl_stream.c:16
ra8_err_t priv_mdl_stream_flush(ra8_err_t prior, ra8_io_stream_t *stream)
Flush a stream only when every earlier append succeeded.
Definition mdl_stream.c:52
ra8_err_t priv_mdl_stream_repeat(ra8_err_t prior, ra8_io_stream_t *stream, char byte, size_t count)
Append a bounded repeated byte after prior success.
Definition mdl_stream.c:31
ra8_err_t priv_mdl_stream_u64(ra8_err_t prior, ra8_io_stream_t *stream, uint64_t value)
Append one unsigned integer unless an earlier append failed.
Definition mdl_stream.c:21
Private bounded text helpers over the portable byte-stream contract.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
Bounded record of every failure in a run (declare at file scope).
Definition mdl_fetch.h:108
One per-page progress event the run emits through mdl_progress_fn.
Definition mdl_fetch.h:125
bool reused
Page served from an already-held file.
Definition mdl_fetch.h:133
size_t chapter_index
1-based chapter position in the run.
Definition mdl_fetch.h:126
uint64_t page_bytes
Bytes transferred (0 when reused).
Definition mdl_fetch.h:131
const char * chapter_id
Chapter identifier (URL leaf).
Definition mdl_fetch.h:128
uint32_t elapsed_ms
Wall time for the transfer (0 when reused).
Definition mdl_fetch.h:132
size_t chapter_total
Total chapters in the run.
Definition mdl_fetch.h:127
size_t page_index
1-based page position within the chapter.
Definition mdl_fetch.h:129
size_t page_total
Pages in the chapter.
Definition mdl_fetch.h:130
Caller-allocated byte-stream handle binding a sink to its context.