mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
vfs: add 'with_xml_file_content()' and 'with_raw_file_content()'
Fixes #4372
This commit is contained in:
parent
8fd2847a48
commit
8ced0f184e
@ -23,6 +23,7 @@
|
||||
namespace Genode {
|
||||
|
||||
class Number_of_bytes;
|
||||
class Byte_range_ptr;
|
||||
class Cstring;
|
||||
template <Genode::size_t> class String;
|
||||
}
|
||||
@ -67,6 +68,22 @@ class Genode::Number_of_bytes
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Data structure for describing a byte buffer
|
||||
*
|
||||
* The type is intended to be used as 'Byte_range_ptr const &' argument.
|
||||
* It is deliberately non-copyable.
|
||||
*/
|
||||
struct Genode::Byte_range_ptr
|
||||
{
|
||||
char * const start;
|
||||
size_t const num_bytes;
|
||||
|
||||
Byte_range_ptr(char *start, size_t num_bytes)
|
||||
: start(start), num_bytes(num_bytes) { }
|
||||
};
|
||||
|
||||
|
||||
/***********************
|
||||
** Utility functions **
|
||||
***********************/
|
||||
|
@ -31,6 +31,12 @@ namespace Genode {
|
||||
class Watcher;
|
||||
template <typename>
|
||||
class Watch_handler;
|
||||
template <typename FN>
|
||||
void with_raw_file_content(Readonly_file const &,
|
||||
Byte_range_ptr const &, FN const &);
|
||||
template <typename FN>
|
||||
void with_xml_file_content(Readonly_file const &,
|
||||
Byte_range_ptr const &, FN const &);
|
||||
}
|
||||
|
||||
|
||||
@ -487,6 +493,60 @@ class Genode::Readonly_file : public File
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Call functor 'fn' with the data pointer and size in bytes
|
||||
*
|
||||
* If the buffer has a size of zero, 'fn' is not called.
|
||||
*/
|
||||
template <typename FN>
|
||||
void Genode::with_raw_file_content(Readonly_file const &file,
|
||||
Byte_range_ptr const &range, FN const &fn)
|
||||
{
|
||||
if (range.num_bytes == 0)
|
||||
return;
|
||||
|
||||
size_t total_read = 0;
|
||||
while (total_read < range.num_bytes) {
|
||||
size_t read_bytes = file.read(Readonly_file::At{total_read},
|
||||
range.start + total_read,
|
||||
range.num_bytes - total_read);
|
||||
|
||||
if (read_bytes == 0)
|
||||
break;
|
||||
|
||||
total_read += read_bytes;
|
||||
}
|
||||
|
||||
if (total_read != range.num_bytes)
|
||||
throw File::Truncated_during_read();
|
||||
|
||||
fn(range.start, range.num_bytes);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call functor 'fn' with content as 'Xml_node' argument
|
||||
*
|
||||
* If the file does not contain valid XML, 'fn' is called with an
|
||||
* '<empty/>' node as argument.
|
||||
*/
|
||||
template <typename FN>
|
||||
void Genode::with_xml_file_content(Readonly_file const &file,
|
||||
Byte_range_ptr const &range, FN const &fn)
|
||||
{
|
||||
with_raw_file_content(file, range,
|
||||
[&] (char const *ptr, size_t num_bytes) {
|
||||
try {
|
||||
fn(Xml_node(ptr, num_bytes));
|
||||
return;
|
||||
}
|
||||
catch (Xml_node::Invalid_syntax) { }
|
||||
|
||||
fn(Xml_node("<empty/>"));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
class Genode::File_content
|
||||
{
|
||||
private:
|
||||
@ -533,22 +593,10 @@ class Genode::File_content
|
||||
:
|
||||
_buffer(alloc, min((size_t)dir.file_size(rel_path), limit.value))
|
||||
{
|
||||
Readonly_file file {dir, rel_path};
|
||||
|
||||
size_t total_read = 0;
|
||||
while (total_read < _buffer.size) {
|
||||
size_t read_bytes = file.read(Readonly_file::At{total_read},
|
||||
_buffer.ptr + total_read,
|
||||
_buffer.size - total_read);
|
||||
|
||||
if (read_bytes == 0)
|
||||
break;
|
||||
|
||||
total_read += read_bytes;
|
||||
}
|
||||
|
||||
if (total_read != _buffer.size)
|
||||
throw Truncated_during_read();
|
||||
/* read the file content into the buffer */
|
||||
with_raw_file_content(Readonly_file(dir, rel_path),
|
||||
Byte_range_ptr(_buffer.ptr, _buffer.size),
|
||||
[] (char const*, size_t) { });
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user