mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 18:06:50 +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 {
|
namespace Genode {
|
||||||
|
|
||||||
class Number_of_bytes;
|
class Number_of_bytes;
|
||||||
|
class Byte_range_ptr;
|
||||||
class Cstring;
|
class Cstring;
|
||||||
template <Genode::size_t> class String;
|
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 **
|
** Utility functions **
|
||||||
***********************/
|
***********************/
|
||||||
|
@ -31,6 +31,12 @@ namespace Genode {
|
|||||||
class Watcher;
|
class Watcher;
|
||||||
template <typename>
|
template <typename>
|
||||||
class Watch_handler;
|
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
|
class Genode::File_content
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@ -533,22 +593,10 @@ class Genode::File_content
|
|||||||
:
|
:
|
||||||
_buffer(alloc, min((size_t)dir.file_size(rel_path), limit.value))
|
_buffer(alloc, min((size_t)dir.file_size(rel_path), limit.value))
|
||||||
{
|
{
|
||||||
Readonly_file file {dir, rel_path};
|
/* read the file content into the buffer */
|
||||||
|
with_raw_file_content(Readonly_file(dir, rel_path),
|
||||||
size_t total_read = 0;
|
Byte_range_ptr(_buffer.ptr, _buffer.size),
|
||||||
while (total_read < _buffer.size) {
|
[] (char const*, size_t) { });
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user