add byte-wise i/o to tags open in sequential write-only mode
This commit is contained in:
99
src/tag.c
99
src/tag.c
@@ -8,6 +8,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static enum ec3_status flush_seq_buffer(struct ec3_tag_ioctx *tag);
|
||||
|
||||
static enum ec3_status init_seq_write_temp_files(struct ec3_tag_ioctx *tag)
|
||||
{
|
||||
b_status status = b_file_open_temp(
|
||||
@@ -78,6 +80,17 @@ enum ec3_status ec3_tag_ioctx_create(
|
||||
|
||||
enum ec3_status ec3_tag_ioctx_close(struct ec3_tag_ioctx *tag)
|
||||
{
|
||||
enum ec3_status status = EC3_SUCCESS;
|
||||
|
||||
if ((tag->io_mode & (EC3_TAG_IO_SEQUENTIAL))
|
||||
&& tag->io_seq_data_ptr > 0) {
|
||||
status = flush_seq_buffer(tag);
|
||||
}
|
||||
|
||||
if (status != EC3_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
enum ec3_tag_ioctx_mode mode = tag->io_mode;
|
||||
tag->io_mode |= EC3_TAG_IO_CLOSED;
|
||||
|
||||
@@ -146,6 +159,12 @@ enum ec3_status ec3_tag_ioctx_read_cluster(
|
||||
cluster_id,
|
||||
&physical_cluster_id);
|
||||
|
||||
if (status == EC3_ERR_OUT_OF_BOUNDS) {
|
||||
/* reached the end of the tag data */
|
||||
*nr_read = 0;
|
||||
return EC3_SUCCESS;
|
||||
}
|
||||
|
||||
if (status != EC3_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
@@ -166,7 +185,8 @@ enum ec3_status ec3_tag_ioctx_read_cluster(
|
||||
return EC3_ERR_BAD_FORMAT;
|
||||
}
|
||||
|
||||
size_t offset = tag->io_cluster_data_offset + cluster_info.c_base;
|
||||
size_t offset = tag->io_parent->io_header.img_cluster_data_offset
|
||||
+ cluster_info.c_base;
|
||||
size_t r;
|
||||
enum b_status status2 = b_file_read(
|
||||
tag->io_f_image,
|
||||
@@ -198,7 +218,7 @@ enum ec3_status ec3_tag_ioctx_read_cluster(
|
||||
enum ec3_status ec3_tag_ioctx_write_cluster(
|
||||
struct ec3_tag_ioctx *tag,
|
||||
size_t cluster_id,
|
||||
void *buf,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
size_t *nr_written)
|
||||
{
|
||||
@@ -210,7 +230,7 @@ enum ec3_status ec3_tag_ioctx_write_cluster(
|
||||
|
||||
if (!(tag->io_mode & EC3_TAG_IO_SEQUENTIAL)) {
|
||||
status = cluster_cache_put(
|
||||
tag->io_cluster_buf,
|
||||
&tag->io_cache,
|
||||
cluster_id,
|
||||
buf,
|
||||
len);
|
||||
@@ -264,6 +284,79 @@ enum ec3_status ec3_tag_ioctx_write_cluster(
|
||||
return EC3_SUCCESS;
|
||||
}
|
||||
|
||||
static enum ec3_status flush_seq_buffer(struct ec3_tag_ioctx *tag)
|
||||
{
|
||||
size_t nr_written = 0;
|
||||
enum ec3_status status = ec3_tag_ioctx_write_cluster(
|
||||
tag,
|
||||
tag->io_seq_cluster_id,
|
||||
tag->io_cluster_buf,
|
||||
tag->io_seq_data_ptr,
|
||||
&nr_written);
|
||||
|
||||
if (status != EC3_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
tag->io_seq_data_ptr = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
enum ec3_status ec3_tag_ioctx_write(
|
||||
struct ec3_tag_ioctx *tag,
|
||||
const void *p,
|
||||
size_t len,
|
||||
size_t *nr_written)
|
||||
{
|
||||
if (!(tag->io_mode & EC3_TAG_IO_WRITE)) {
|
||||
return EC3_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!(tag->io_mode & EC3_TAG_IO_SEQUENTIAL)) {
|
||||
return EC3_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
enum ec3_status status = EC3_SUCCESS;
|
||||
size_t cluster_size = tag->io_parent->io_header.img_cluster_size;
|
||||
|
||||
const unsigned char *buf = p;
|
||||
size_t written = 0;
|
||||
|
||||
while (len > 0) {
|
||||
size_t space_remaining = cluster_size - tag->io_seq_data_ptr;
|
||||
|
||||
size_t to_copy = len;
|
||||
if (to_copy > space_remaining) {
|
||||
to_copy = space_remaining;
|
||||
}
|
||||
|
||||
const unsigned char *src = buf + written;
|
||||
unsigned char *dest
|
||||
= tag->io_cluster_buf + tag->io_seq_data_ptr;
|
||||
|
||||
memcpy(dest, src, to_copy);
|
||||
|
||||
tag->io_seq_data_ptr += to_copy;
|
||||
written += to_copy;
|
||||
|
||||
len -= to_copy;
|
||||
space_remaining -= to_copy;
|
||||
|
||||
if (space_remaining == 0) {
|
||||
status = flush_seq_buffer(tag);
|
||||
}
|
||||
|
||||
if (status != EC3_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
*nr_written = written;
|
||||
|
||||
return EC3_SUCCESS;
|
||||
}
|
||||
|
||||
enum ec3_status ec3_tag_ioctx_get_nr_clusters(
|
||||
struct ec3_tag_ioctx *tag,
|
||||
size_t *out_nr_clusters)
|
||||
|
||||
14
src/tag.h
14
src/tag.h
@@ -36,8 +36,6 @@ struct ec3_tag_ioctx {
|
||||
|
||||
/* temp buffer of cluster size, used for pipeline operations */
|
||||
void *io_cluster_buf;
|
||||
/* the offset to the start of the cluster table in io_f_rotag */
|
||||
size_t io_cluster_data_offset;
|
||||
|
||||
/* this points to memory belonging to ec3_image_ioctx */
|
||||
struct ec3_tag_info io_tag_info;
|
||||
@@ -82,6 +80,10 @@ struct ec3_tag_ioctx {
|
||||
struct cluster_table io_cluster_table;
|
||||
/* how many clusters have been written sequentially to this tag */
|
||||
size_t io_seq_cluster_id;
|
||||
/* how many bytes have been written to io_cluster_buf using
|
||||
* ec3_tag_ioctx_write. when this reaches the cluster size (or
|
||||
* ec3_tag_ioctx_close is called) this is reset to 0. */
|
||||
size_t io_seq_data_ptr;
|
||||
};
|
||||
|
||||
extern enum ec3_status ec3_tag_ioctx_create(
|
||||
@@ -98,7 +100,13 @@ extern enum ec3_status ec3_tag_ioctx_read_cluster(
|
||||
extern enum ec3_status ec3_tag_ioctx_write_cluster(
|
||||
struct ec3_tag_ioctx *tag,
|
||||
size_t cluster_id,
|
||||
void *buf,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
size_t *nr_written);
|
||||
|
||||
extern enum ec3_status ec3_tag_ioctx_write(
|
||||
struct ec3_tag_ioctx *tag,
|
||||
const void *buf,
|
||||
size_t len,
|
||||
size_t *nr_written);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user