ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
fw_if_fs_dir.c
Go to the documentation of this file.
1
15
16#include <stddef.h>
17#include <stdint.h>
18#include <string.h>
19
20#include "fw_if_fs.h"
21#include "fw_if_fs_backend.h"
22#include "ra8_attributes.h"
23#include "ra8_err.h"
24
42{
43 if (names == nullptr) {
44 return k_ra8_err_null_ptr;
45 }
46 return (names->iface == nullptr) ? k_ra8_err_not_initialized : k_ra8_ok;
47}
48
71internal_cursor_workspace(void* workspace, uint32_t bytes, uint32_t need, uint8_t align)
72{
73 if (workspace == nullptr) {
74 return k_ra8_err_null_ptr;
75 }
76 if (bytes < need) {
77 return k_ra8_err_no_mem;
78 }
79 if ((align == 0U) || (((uint32_t)align & ((uint32_t)align - 1U)) != 0U)) {
81 }
82 return (((uintptr_t)workspace % (uintptr_t)align) == 0U) ? k_ra8_ok : k_ra8_err_invalid_arg;
83}
84
103{
104 if (directory == nullptr) {
105 return k_ra8_err_null_ptr;
106 }
107 if (!directory->is_open) {
109 }
110 return (directory->iface == nullptr) ? k_ra8_err_not_initialized : k_ra8_ok;
111}
112
130 const fw_fs_dirent_value_t* entry)
131{
132 if ((entry->name_bytes == 0U) || (entry->name_bytes > caps->name_max_bytes) ||
133 (entry->name_bytes >= (uint16_t)k_fw_fs_path_cap)) {
135 }
136 if ((entry->name[entry->name_bytes] != '\0') ||
137 (strnlen(entry->name, (size_t)k_fw_fs_path_cap) != (size_t)entry->name_bytes)) {
139 }
140 if ((entry->type == k_fw_fs_node_none) ||
141 ((uint32_t)entry->type > (uint32_t)k_fw_fs_node_other) ||
142 ((entry->type == k_fw_fs_node_directory) && (entry->size_bytes != 0U))) {
144 }
145 char path[k_fw_fs_path_cap] = {'/'};
146 (void)memcpy(&path[1], entry->name, (size_t)entry->name_bytes + 1U);
148}
149
151 const char* path,
152 fw_fs_dir_t* directory,
153 void* workspace,
154 uint32_t workspace_size)
155{
156 const ra8_err_t valid = internal_cursor_names(names);
157 if (valid != k_ra8_ok) {
158 return valid;
159 }
160 if (directory == nullptr) {
161 return k_ra8_err_null_ptr;
162 }
163 if (directory->is_open) {
164 return k_ra8_err_busy;
165 }
166 const ra8_err_t path_err = fw_fs_path_validate(&names->caps, path);
167 if (path_err != k_ra8_ok) {
168 return path_err;
169 }
170 const ra8_err_t work = internal_cursor_workspace(workspace,
171 workspace_size,
174 if (work != k_ra8_ok) {
175 return work;
176 }
177 const ra8_err_t opened = names->iface->dir_open(names->ctx, path, workspace, workspace_size);
178 if (opened != k_ra8_ok) {
179 return opened;
180 }
181 *directory = (fw_fs_dir_t){.iface = names->iface,
182 .ctx = names->ctx,
183 .state = workspace,
184 .state_bytes = workspace_size,
185 .caps = names->caps,
186 .is_open = true};
187 return k_ra8_ok;
188}
189
191{
192 const ra8_err_t valid = internal_cursor_handle(directory);
193 if (valid != k_ra8_ok) {
194 return valid;
195 }
196 if ((out == nullptr) || (out_entry == nullptr)) {
197 return k_ra8_err_null_ptr;
198 }
199 *out = (fw_fs_dirent_value_t){};
200 *out_entry = false;
201 fw_fs_dirent_value_t candidate = {};
202 bool present = false;
203 const ra8_err_t result =
204 directory->iface->dir_next(directory->ctx, directory->state, &candidate, &present);
205 if ((result != k_ra8_ok) || !present) {
206 return result;
207 }
208 const ra8_err_t coherent = internal_cursor_entry(&directory->caps, &candidate);
209 if (coherent != k_ra8_ok) {
210 return coherent;
211 }
212 *out = candidate;
213 *out_entry = true;
214 return k_ra8_ok;
215}
216
218{
219 const ra8_err_t valid = internal_cursor_handle(directory);
220 if (valid != k_ra8_ok) {
221 return valid;
222 }
223 const ra8_err_t closed = directory->iface->dir_close(directory->ctx, directory->state);
224 *directory = (fw_fs_dir_t){};
225 return closed;
226}
Architecture-neutral filesystem namespace, stream, and transaction ports.
ra8_err_t fw_fs_path_validate(const fw_fs_caps_t *caps, const char *path)
Validate a canonical portable path against a binding's limits.
Definition fw_if_fs.c:286
Backend-author interface for binding concrete filesystem ports.
static ra8_err_t internal_cursor_names(const fw_fs_namespace_t *names)
Validate one namespace facade used for cursor dispatch.
static ra8_err_t internal_cursor_workspace(void *workspace, uint32_t bytes, uint32_t need, uint8_t align)
Validate cursor workspace size and alignment.
static ra8_err_t internal_cursor_handle(const fw_fs_dir_t *directory)
Validate an open directory cursor before dispatch.
static ra8_err_t internal_cursor_entry(const fw_fs_caps_t *caps, const fw_fs_dirent_value_t *entry)
Validate one backend-produced stable directory value.
ra8_err_t fw_fs_dir_next(fw_fs_dir_t *directory, fw_fs_dirent_value_t *out, bool *out_entry)
Copy one stable directory entry from an open cursor.
ra8_err_t fw_fs_dir_close(fw_fs_dir_t *directory)
Close and consume an open directory cursor, including on close error.
ra8_err_t fw_fs_dir_open(const fw_fs_namespace_t *names, const char *path, fw_fs_dir_t *directory, void *workspace, uint32_t workspace_size)
Open one directory cursor into caller-owned backend workspace.
@ k_fw_fs_node_none
No node exists at the path.
@ k_fw_fs_node_directory
Directory.
@ k_fw_fs_node_other
Backend-specific non-file node.
@ k_fw_fs_path_cap
Largest portable path including its NUL.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Error Code Definitions for ra8-firmware.
@ k_ra8_err_no_mem
Static buffer exhausted (no dynamic memory on this project).
Definition ra8_err.h:142
@ k_ra8_err_busy
Resource busy – blocking operation cannot proceed.
Definition ra8_err.h:195
@ 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_err_not_initialized
Module not initialized – _init() not yet called successfully.
Definition ra8_err.h:235
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_null_ptr
Pointer was NULL where a valid pointer was required.
Definition ra8_err.h:478
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
void * memcpy(void *dst, const void *src, size_t n)
Copy memory area between non-overlapping regions.
size_t strnlen(const char *s, size_t maxlen)
Calculate bounded string length.
Static properties and workspace requirements of one bound port.
uint16_t name_max_bytes
Component bytes excluding NUL.
uint8_t directory_workspace_align
Required directory-state alignment.
uint32_t directory_workspace_bytes
State bytes required by dir open.
Caller-owned open directory cursor; fields are private to the facade.
void * state
Caller workspace.
void * ctx
Adapter context.
fw_fs_caps_t caps
Immutable port caps.
bool is_open
Facade lifecycle guard.
const fw_fs_namespace_iface_t * iface
Bound namespace vtable.
Stable caller-owned value returned by fw_fs_dir_next.
uint64_t size_bytes
File length; zero for dirs.
uint16_t name_bytes
Bytes excluding the NUL.
fw_fs_node_type_t type
Entry kind.
char name[k_fw_fs_path_cap]
Copied NUL-terminated leaf.
ra8_err_t(* dir_open)(void *ctx, const char *path, void *directory_state, uint32_t state_bytes)
Open a directory cursor in caller-supplied workspace.
ra8_err_t(* dir_next)(void *ctx, void *directory_state, fw_fs_dirent_value_t *out, bool *out_entry)
Copy the next visible entry or report clean end-of-directory.
ra8_err_t(* dir_close)(void *ctx, void *directory_state)
Close a directory cursor and consume its backend state.
Independently injectable path/namespace facade.
fw_fs_caps_t caps
Immutable capabilities.
void * ctx
Backend context.
const fw_fs_namespace_iface_t * iface
Bound private vtable.