188 lines
4.7 KiB
C
188 lines
4.7 KiB
C
|
|
#include "aos_buf.h"
|
||
|
|
#include "aos_log.h"
|
||
|
|
#include <apr_file_io.h>
|
||
|
|
|
||
|
|
aos_buf_t *aos_create_buf(aos_pool_t *p, int size)
|
||
|
|
{
|
||
|
|
aos_buf_t* b;
|
||
|
|
|
||
|
|
b = aos_palloc(p, sizeof(aos_buf_t) + size);
|
||
|
|
if (b == NULL) {
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
b->pos = (uint8_t *)b + sizeof(aos_buf_t);
|
||
|
|
b->start = b->pos;
|
||
|
|
b->last = b->start;
|
||
|
|
b->end = b->last + size;
|
||
|
|
aos_list_init(&b->node);
|
||
|
|
|
||
|
|
return b;
|
||
|
|
}
|
||
|
|
|
||
|
|
aos_buf_t *aos_buf_pack(aos_pool_t *p, const void *data, int size)
|
||
|
|
{
|
||
|
|
aos_buf_t* b;
|
||
|
|
|
||
|
|
b = aos_palloc(p, sizeof(aos_buf_t));
|
||
|
|
if (b == NULL) {
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
b->pos = (uint8_t *)data;
|
||
|
|
b->start = b->pos;
|
||
|
|
b->last = b->start + size;
|
||
|
|
b->end = b->last;
|
||
|
|
aos_list_init(&b->node);
|
||
|
|
|
||
|
|
return b;
|
||
|
|
}
|
||
|
|
|
||
|
|
int64_t aos_buf_list_len(aos_list_t *list)
|
||
|
|
{
|
||
|
|
aos_buf_t *b;
|
||
|
|
int64_t len = 0;
|
||
|
|
|
||
|
|
aos_list_for_each_entry(aos_buf_t, b, list, node) {
|
||
|
|
len += aos_buf_size(b);
|
||
|
|
}
|
||
|
|
|
||
|
|
return len;
|
||
|
|
}
|
||
|
|
|
||
|
|
char *aos_buf_list_content(aos_pool_t *p, aos_list_t *list)
|
||
|
|
{
|
||
|
|
int64_t body_len;
|
||
|
|
char *buf;
|
||
|
|
int64_t pos = 0;
|
||
|
|
int64_t size = 0;
|
||
|
|
aos_buf_t *content;
|
||
|
|
|
||
|
|
body_len = aos_buf_list_len(list);
|
||
|
|
buf = aos_pcalloc(p, (size_t)(body_len + 1));
|
||
|
|
buf[body_len] = '\0';
|
||
|
|
aos_list_for_each_entry(aos_buf_t, content, list, node) {
|
||
|
|
size = aos_buf_size(content);
|
||
|
|
memcpy(buf + pos, content->pos, (size_t)(size));
|
||
|
|
pos += size;
|
||
|
|
}
|
||
|
|
return buf;
|
||
|
|
}
|
||
|
|
|
||
|
|
aos_file_buf_t *aos_create_file_buf(aos_pool_t *p)
|
||
|
|
{
|
||
|
|
return (aos_file_buf_t*)aos_pcalloc(p, sizeof(aos_file_buf_t));
|
||
|
|
}
|
||
|
|
|
||
|
|
int aos_open_file_for_read(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||
|
|
{
|
||
|
|
int s;
|
||
|
|
char buf[256];
|
||
|
|
apr_finfo_t finfo;
|
||
|
|
|
||
|
|
if ((s = apr_file_open(&fb->file, path, APR_READ, APR_UREAD | APR_GREAD, p)) != APR_SUCCESS) {
|
||
|
|
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||
|
|
assert(fb->file == NULL);
|
||
|
|
return AOSE_OPEN_FILE_ERROR;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((s = apr_file_info_get(&finfo, APR_FINFO_NORM, fb->file)) != APR_SUCCESS) {
|
||
|
|
apr_file_close(fb->file);
|
||
|
|
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||
|
|
return AOSE_FILE_INFO_ERROR;
|
||
|
|
}
|
||
|
|
fb->file_pos = 0;
|
||
|
|
fb->file_last = finfo.size;
|
||
|
|
fb->owner = 1;
|
||
|
|
|
||
|
|
return AOSE_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
int aos_open_file_for_all_read(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||
|
|
{
|
||
|
|
return aos_open_file_for_read(p, path, fb);
|
||
|
|
}
|
||
|
|
|
||
|
|
int aos_open_file_for_range_read(aos_pool_t *p, const char *path,
|
||
|
|
int64_t file_pos, int64_t file_last, aos_file_buf_t *fb)
|
||
|
|
{
|
||
|
|
int s;
|
||
|
|
|
||
|
|
s = aos_open_file_for_read(p, path, fb);
|
||
|
|
if (s == AOSE_OK) {
|
||
|
|
if (file_pos > fb->file_pos) {
|
||
|
|
if (file_pos > fb->file_last) {
|
||
|
|
aos_warn_log("read range beyond file size, read start:%" APR_INT64_T_FMT ", file size:%" APR_INT64_T_FMT "\n",
|
||
|
|
file_pos, fb->file_last);
|
||
|
|
file_pos = fb->file_last;
|
||
|
|
}
|
||
|
|
fb->file_pos = file_pos;
|
||
|
|
}
|
||
|
|
if (file_last < fb->file_last) {
|
||
|
|
fb->file_last = file_last;
|
||
|
|
}
|
||
|
|
apr_file_seek(fb->file, APR_SET, (apr_off_t *)&fb->file_pos);
|
||
|
|
}
|
||
|
|
|
||
|
|
return s;
|
||
|
|
}
|
||
|
|
|
||
|
|
int aos_open_file_for_write(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||
|
|
{
|
||
|
|
int s;
|
||
|
|
char buf[256];
|
||
|
|
|
||
|
|
if ((s = apr_file_open(&fb->file, path, APR_CREATE | APR_WRITE | APR_TRUNCATE,
|
||
|
|
APR_UREAD | APR_UWRITE | APR_GREAD, p)) != APR_SUCCESS) {
|
||
|
|
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||
|
|
assert(fb->file == NULL);
|
||
|
|
return AOSE_OPEN_FILE_ERROR;
|
||
|
|
}
|
||
|
|
fb->owner = 1;
|
||
|
|
|
||
|
|
return AOSE_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
int aos_open_file_for_write_notrunc(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||
|
|
{
|
||
|
|
int s;
|
||
|
|
char buf[256];
|
||
|
|
|
||
|
|
if ((s = apr_file_open(&fb->file, path, APR_CREATE | APR_WRITE,
|
||
|
|
APR_UREAD | APR_UWRITE | APR_GREAD, p)) != APR_SUCCESS) {
|
||
|
|
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||
|
|
assert(fb->file == NULL);
|
||
|
|
return AOSE_OPEN_FILE_ERROR;
|
||
|
|
}
|
||
|
|
fb->owner = 1;
|
||
|
|
|
||
|
|
return AOSE_OK;
|
||
|
|
}
|
||
|
|
|
||
|
|
void aos_buf_append_string(aos_pool_t *p, aos_buf_t *b, const char *str, int len)
|
||
|
|
{
|
||
|
|
int size;
|
||
|
|
int nsize;
|
||
|
|
int remain;
|
||
|
|
char *buf;
|
||
|
|
|
||
|
|
if (len <= 0) return;
|
||
|
|
|
||
|
|
remain = b->end - b->last;
|
||
|
|
|
||
|
|
if (remain > len + 128) {
|
||
|
|
memcpy(b->last, str, len);
|
||
|
|
b->last += len;
|
||
|
|
} else {
|
||
|
|
size = aos_buf_size(b);
|
||
|
|
nsize = (size + len) * 2;
|
||
|
|
buf = aos_palloc(p, nsize);
|
||
|
|
memcpy(buf, b->pos, size);
|
||
|
|
memcpy(buf+size, str, len);
|
||
|
|
b->start = (uint8_t *)buf;
|
||
|
|
b->end = (uint8_t *)buf + nsize;
|
||
|
|
b->pos = (uint8_t *)buf;
|
||
|
|
b->last = (uint8_t *)buf + size + len;
|
||
|
|
}
|
||
|
|
}
|