forked from enlightenment/efl
628 lines
17 KiB
C
628 lines
17 KiB
C
#define EFL_IO_READER_PROTECTED 1
|
|
#define EFL_IO_WRITER_PROTECTED 1
|
|
|
|
#include "config.h"
|
|
#include "Efl.h"
|
|
|
|
#define MY_CLASS EFL_IO_BUFFER_CLASS
|
|
|
|
typedef struct _Efl_Io_Buffer_Data
|
|
{
|
|
uint8_t *bytes;
|
|
size_t allocated;
|
|
size_t used;
|
|
size_t limit;
|
|
size_t position_read;
|
|
size_t position_write;
|
|
Eina_Bool closed;
|
|
Eina_Bool can_read;
|
|
Eina_Bool can_write;
|
|
Eina_Bool readonly;
|
|
} Efl_Io_Buffer_Data;
|
|
|
|
static Eina_Bool
|
|
_efl_io_buffer_realloc(Eo *o, Efl_Io_Buffer_Data *pd, size_t size)
|
|
{
|
|
void *tmp;
|
|
size_t limit = efl_io_buffer_limit_get(o);
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(pd->readonly, EINA_FALSE);
|
|
|
|
if ((limit > 0) && (size > limit))
|
|
size = limit;
|
|
|
|
if (pd->allocated == size) return EINA_FALSE;
|
|
|
|
if (efl_io_sizer_size_get(o) > size)
|
|
{
|
|
if (efl_io_buffer_position_read_get(o) > size)
|
|
efl_io_buffer_position_read_set(o, size);
|
|
if (efl_io_buffer_position_write_get(o) > size)
|
|
efl_io_buffer_position_write_set(o, size);
|
|
|
|
/* no efl_io_sizer_size_set() since it could recurse! */
|
|
pd->used = size;
|
|
efl_event_callback_call(o, EFL_IO_SIZER_EVENT_SIZE_CHANGED, NULL);
|
|
}
|
|
|
|
if (size == 0)
|
|
{
|
|
free(pd->bytes);
|
|
tmp = NULL;
|
|
}
|
|
else
|
|
{
|
|
tmp = realloc(pd->bytes, size);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, EINA_FALSE);
|
|
}
|
|
|
|
pd->bytes = tmp;
|
|
pd->allocated = size;
|
|
efl_event_callback_call(o, EFL_IO_BUFFER_EVENT_REALLOCATED, NULL);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static Eina_Bool
|
|
_efl_io_buffer_realloc_rounded(Eo *o, Efl_Io_Buffer_Data *pd, size_t size)
|
|
{
|
|
if ((size > 0) && (size < 128))
|
|
size = ((size / 32) + 1) * 32;
|
|
else if (size < 1024)
|
|
size = ((size / 128) + 1) * 128;
|
|
else if (size < 8192)
|
|
size = ((size / 1024) + 1) * 1024;
|
|
else
|
|
size = ((size / 4096) + 1) * 4096;
|
|
|
|
return _efl_io_buffer_realloc(o, pd, size);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_preallocate(Eo *o, Efl_Io_Buffer_Data *pd, size_t size)
|
|
{
|
|
EINA_SAFETY_ON_TRUE_RETURN(pd->readonly);
|
|
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
|
|
if (pd->allocated < size)
|
|
_efl_io_buffer_realloc_rounded(o, pd, size);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_limit_set(Eo *o, Efl_Io_Buffer_Data *pd, size_t limit)
|
|
{
|
|
EINA_SAFETY_ON_TRUE_RETURN(pd->readonly);
|
|
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
|
|
|
|
if (pd->limit == limit) return;
|
|
pd->limit = limit;
|
|
|
|
if ((limit > 0) && (pd->allocated > limit))
|
|
_efl_io_buffer_realloc(o, pd, limit);
|
|
|
|
if (pd->closed) return;
|
|
|
|
efl_io_reader_can_read_set(o, efl_io_buffer_position_read_get(o) < efl_io_sizer_size_get(o));
|
|
if (pd->closed) return;
|
|
efl_io_writer_can_write_set(o, (limit == 0) ||
|
|
(efl_io_buffer_position_write_get(o) < limit));
|
|
}
|
|
|
|
EOLIAN static size_t
|
|
_efl_io_buffer_limit_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
return pd->limit;
|
|
}
|
|
|
|
EOLIAN static Eina_Slice
|
|
_efl_io_buffer_slice_get(const Eo *o, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
Eina_Slice slice = { };
|
|
|
|
if (!efl_io_closer_closed_get(o))
|
|
{
|
|
slice.mem = pd->bytes;
|
|
slice.len = efl_io_sizer_size_get(o);
|
|
}
|
|
|
|
return slice;
|
|
}
|
|
|
|
EOLIAN static Eina_Binbuf *
|
|
_efl_io_buffer_binbuf_steal(Eo *o, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
Eina_Binbuf *ret;
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(pd->readonly, NULL);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), NULL);
|
|
|
|
ret = eina_binbuf_manage_new(pd->bytes, efl_io_sizer_size_get(o), EINA_FALSE);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(ret, NULL);
|
|
|
|
pd->bytes = NULL;
|
|
pd->allocated = 0;
|
|
efl_event_callback_call(o, EFL_IO_BUFFER_EVENT_REALLOCATED, NULL);
|
|
efl_io_sizer_resize(o, 0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
EOLIAN static Efl_Object *
|
|
_efl_io_buffer_efl_object_finalize(Eo *o, Efl_Io_Buffer_Data *pd EINA_UNUSED)
|
|
{
|
|
size_t limit;
|
|
|
|
o = efl_finalize(efl_super(o, MY_CLASS));
|
|
if (!o) return NULL;
|
|
|
|
efl_io_reader_can_read_set(o, efl_io_buffer_position_read_get(o) < efl_io_sizer_size_get(o));
|
|
if (pd->closed) return o;
|
|
|
|
limit = efl_io_buffer_limit_get(o);
|
|
efl_io_writer_can_write_set(o, (limit == 0) ||
|
|
(efl_io_buffer_position_write_get(o) < limit));
|
|
|
|
return o;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_efl_object_destructor(Eo *o, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
if (!efl_io_closer_closed_get(o))
|
|
{
|
|
efl_event_freeze(o);
|
|
efl_io_closer_close(o);
|
|
efl_event_thaw(o);
|
|
}
|
|
|
|
efl_destructor(efl_super(o, MY_CLASS));
|
|
|
|
if (pd->bytes)
|
|
{
|
|
if (!pd->readonly) free(pd->bytes);
|
|
pd->bytes = NULL;
|
|
pd->allocated = 0;
|
|
pd->used = 0;
|
|
pd->position_read = 0;
|
|
pd->position_write = 0;
|
|
}
|
|
}
|
|
|
|
EOLIAN static Eina_Error
|
|
_efl_io_buffer_efl_io_reader_read(Eo *o, Efl_Io_Buffer_Data *pd, Eina_Rw_Slice *rw_slice)
|
|
{
|
|
Eina_Slice ro_slice;
|
|
size_t used, read_pos, available;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(rw_slice, EINVAL);
|
|
EINA_SAFETY_ON_TRUE_GOTO(efl_io_closer_closed_get(o), error);
|
|
|
|
used = efl_io_sizer_size_get(o);
|
|
read_pos = efl_io_buffer_position_read_get(o);
|
|
available = used - read_pos;
|
|
|
|
if (rw_slice->len > available)
|
|
{
|
|
rw_slice->len = available;
|
|
if (rw_slice->len == 0)
|
|
return EAGAIN;
|
|
}
|
|
|
|
ro_slice.len = rw_slice->len;
|
|
ro_slice.mem = pd->bytes + read_pos;
|
|
|
|
*rw_slice = eina_rw_slice_copy(*rw_slice, ro_slice);
|
|
efl_io_buffer_position_read_set(o, read_pos + ro_slice.len);
|
|
|
|
return 0;
|
|
|
|
error:
|
|
rw_slice->len = 0;
|
|
rw_slice->mem = NULL;
|
|
efl_io_reader_can_read_set(o, EINA_FALSE);
|
|
return EINVAL;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_efl_io_reader_can_read_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
return pd->can_read;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_efl_io_reader_can_read_set(Eo *o, Efl_Io_Buffer_Data *pd, Eina_Bool can_read)
|
|
{
|
|
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
|
|
if (pd->can_read == can_read) return;
|
|
pd->can_read = can_read;
|
|
efl_event_callback_call(o, EFL_IO_READER_EVENT_CAN_READ_CHANGED, &can_read);
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_efl_io_reader_eos_get(const Eo *o, Efl_Io_Buffer_Data *pd EINA_UNUSED)
|
|
{
|
|
return efl_io_closer_closed_get(o) ||
|
|
efl_io_buffer_position_read_get(o) >= efl_io_sizer_size_get(o);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_efl_io_reader_eos_set(Eo *o, Efl_Io_Buffer_Data *pd EINA_UNUSED, Eina_Bool is_eos)
|
|
{
|
|
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
|
|
if (is_eos)
|
|
efl_event_callback_call(o, EFL_IO_READER_EVENT_EOS, NULL);
|
|
}
|
|
|
|
EOLIAN static Eina_Error
|
|
_efl_io_buffer_efl_io_writer_write(Eo *o, Efl_Io_Buffer_Data *pd, Eina_Slice *slice, Eina_Slice *remaining)
|
|
{
|
|
size_t available, todo, write_pos, limit;
|
|
int err = EINVAL;
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(pd->readonly, EPERM);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(slice, EINVAL);
|
|
EINA_SAFETY_ON_TRUE_GOTO(efl_io_closer_closed_get(o), error);
|
|
|
|
write_pos = efl_io_buffer_position_write_get(o);
|
|
available = pd->allocated - write_pos;
|
|
limit = efl_io_buffer_limit_get(o);
|
|
|
|
err = ENOSPC;
|
|
if (available >= slice->len)
|
|
todo = slice->len;
|
|
else if ((limit > 0) && (pd->allocated == limit)) goto error;
|
|
else
|
|
{
|
|
_efl_io_buffer_realloc_rounded(o, pd, write_pos + slice->len);
|
|
if (pd->allocated >= write_pos + slice->len)
|
|
todo = slice->len;
|
|
else
|
|
todo = pd->allocated - write_pos;
|
|
|
|
if (todo == 0) goto error;
|
|
}
|
|
|
|
memcpy(pd->bytes + write_pos, slice->mem, todo);
|
|
if (remaining)
|
|
{
|
|
remaining->len = slice->len - todo;
|
|
if (remaining->len)
|
|
remaining->mem = slice->bytes + todo;
|
|
else
|
|
remaining->mem = NULL;
|
|
}
|
|
slice->len = todo;
|
|
|
|
if (pd->used < write_pos + todo)
|
|
{
|
|
pd->used = write_pos + todo;
|
|
efl_event_callback_call(o, EFL_IO_SIZER_EVENT_SIZE_CHANGED, NULL);
|
|
if (pd->closed) return 0;
|
|
efl_io_reader_can_read_set(o, pd->position_read < pd->used);
|
|
if (pd->closed) return 0;
|
|
}
|
|
efl_io_buffer_position_write_set(o, write_pos + todo);
|
|
|
|
return 0;
|
|
|
|
error:
|
|
if (remaining) *remaining = *slice;
|
|
slice->len = 0;
|
|
slice->mem = NULL;
|
|
efl_io_writer_can_write_set(o, EINA_FALSE);
|
|
return err;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_efl_io_writer_can_write_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
return pd->can_write;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_efl_io_writer_can_write_set(Eo *o, Efl_Io_Buffer_Data *pd, Eina_Bool can_write)
|
|
{
|
|
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
|
|
if (pd->can_write == can_write) return;
|
|
pd->can_write = can_write;
|
|
efl_event_callback_call(o, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, &can_write);
|
|
}
|
|
|
|
EOLIAN static Eina_Error
|
|
_efl_io_buffer_efl_io_closer_close(Eo *o, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), EINVAL);
|
|
efl_io_sizer_resize(o, 0);
|
|
pd->closed = EINA_TRUE;
|
|
efl_event_callback_call(o, EFL_IO_CLOSER_EVENT_CLOSED, NULL);
|
|
return 0;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_efl_io_closer_closed_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
return pd->closed;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_efl_io_closer_close_on_exec_set(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED, Eina_Bool close_on_exec)
|
|
{
|
|
if (!close_on_exec) return EINA_FALSE;
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_efl_io_closer_close_on_exec_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED)
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_efl_io_closer_close_on_invalidate_set(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED, Eina_Bool close_on_invalidate EINA_UNUSED)
|
|
{
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_efl_io_closer_close_on_invalidate_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd EINA_UNUSED)
|
|
{
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Error
|
|
_efl_io_buffer_efl_io_sizer_resize(Eo *o, Efl_Io_Buffer_Data *pd, uint64_t size)
|
|
{
|
|
Eina_Error ret = 0;
|
|
Eina_Bool reallocated = EINA_FALSE;
|
|
size_t old_size, pos_read, pos_write;
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), EINVAL);
|
|
|
|
if (efl_io_sizer_size_get(o) == size) return 0;
|
|
|
|
if (pd->readonly)
|
|
{
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(size > pd->used, EPERM);
|
|
pd->used = size;
|
|
goto end;
|
|
}
|
|
|
|
old_size = pd->used;
|
|
pd->used = size;
|
|
|
|
efl_event_freeze(o);
|
|
reallocated = _efl_io_buffer_realloc_rounded(o, pd, size);
|
|
efl_event_thaw(o);
|
|
|
|
if (size > pd->allocated)
|
|
{
|
|
pd->used = size = pd->allocated;
|
|
ret = ENOSPC;
|
|
}
|
|
|
|
if (old_size < size)
|
|
memset(pd->bytes + old_size, 0, size - old_size);
|
|
|
|
end:
|
|
pos_read = efl_io_buffer_position_read_get(o);
|
|
if (pos_read > size)
|
|
efl_io_buffer_position_read_set(o, size);
|
|
else
|
|
efl_io_reader_can_read_set(o, pos_read < size);
|
|
|
|
if (pd->closed) return 0;
|
|
|
|
pos_write = efl_io_buffer_position_write_get(o);
|
|
if (pos_write > size)
|
|
efl_io_buffer_position_write_set(o, size);
|
|
else
|
|
{
|
|
size_t limit = efl_io_buffer_limit_get(o);
|
|
efl_io_writer_can_write_set(o, (limit == 0) || (pos_write < limit));
|
|
if (pd->closed) return 0;
|
|
}
|
|
|
|
efl_event_callback_call(o, EFL_IO_SIZER_EVENT_SIZE_CHANGED, NULL);
|
|
if (reallocated)
|
|
efl_event_callback_call(o, EFL_IO_BUFFER_EVENT_REALLOCATED, NULL);
|
|
|
|
return ret;
|
|
}
|
|
|
|
EOLIAN static uint64_t
|
|
_efl_io_buffer_efl_io_sizer_size_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
return pd->used;
|
|
}
|
|
|
|
EOLIAN static Eina_Error
|
|
_efl_io_buffer_efl_io_positioner_seek(Eo *o, Efl_Io_Buffer_Data *pd EINA_UNUSED, int64_t offset, Efl_Io_Positioner_Whence whence)
|
|
{
|
|
size_t size;
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), EINVAL);
|
|
|
|
size = efl_io_sizer_size_get(o);
|
|
|
|
if (whence == EFL_IO_POSITIONER_WHENCE_CURRENT)
|
|
{
|
|
whence = EFL_IO_POSITIONER_WHENCE_START;
|
|
offset += efl_io_positioner_position_get(o);
|
|
}
|
|
else if (whence == EFL_IO_POSITIONER_WHENCE_END)
|
|
{
|
|
whence = EFL_IO_POSITIONER_WHENCE_START;
|
|
offset += size;
|
|
}
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(whence != EFL_IO_POSITIONER_WHENCE_START, EINVAL);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(offset < 0, EINVAL);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL((size_t)offset > size, EINVAL);
|
|
|
|
efl_io_buffer_position_read_set(o, offset);
|
|
efl_io_buffer_position_write_set(o, offset);
|
|
|
|
return 0;
|
|
}
|
|
|
|
EOLIAN static uint64_t
|
|
_efl_io_buffer_efl_io_positioner_position_get(const Eo *o, Efl_Io_Buffer_Data *pd EINA_UNUSED)
|
|
{
|
|
uint64_t r = efl_io_buffer_position_read_get(o);
|
|
uint64_t w = efl_io_buffer_position_write_get(o);
|
|
/* if using Efl.Io.Positioner.position, on set it will do both
|
|
* read/write to the same offset, however on Efl.Io.Reader.read it
|
|
* will only update position_read (and similarly for
|
|
* Efl.Io.Writer), thus on the next position.get we want the
|
|
* greatest position.
|
|
*
|
|
* This allows the buffer to be used solely as reader or writer
|
|
* without the need to know it have two internal offsets.
|
|
*/
|
|
if (r >= w)
|
|
return r;
|
|
return w;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_position_read_set(Eo *o, Efl_Io_Buffer_Data *pd, uint64_t position)
|
|
{
|
|
size_t size;
|
|
Eina_Bool changed;
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), EINA_FALSE);
|
|
|
|
size = efl_io_sizer_size_get(o);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(position > size, EINA_FALSE);
|
|
|
|
if (pd->position_read == position) return EINA_TRUE;
|
|
|
|
changed = efl_io_positioner_position_get(o) != position;
|
|
|
|
pd->position_read = position;
|
|
efl_event_callback_call(o, EFL_IO_BUFFER_EVENT_POSITION_READ_CHANGED, NULL);
|
|
if (changed)
|
|
efl_event_callback_call(o, EFL_IO_POSITIONER_EVENT_POSITION_CHANGED, NULL);
|
|
|
|
efl_io_reader_can_read_set(o, position < size);
|
|
if (pd->closed) return EINA_TRUE;
|
|
efl_io_reader_eos_set(o, position >= size);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static uint64_t
|
|
_efl_io_buffer_position_read_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
return pd->position_read;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_io_buffer_position_write_set(Eo *o, Efl_Io_Buffer_Data *pd, uint64_t position)
|
|
{
|
|
size_t size;
|
|
size_t limit;
|
|
Eina_Bool changed;
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), EINA_FALSE);
|
|
|
|
size = efl_io_sizer_size_get(o);
|
|
if (position < size)
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(pd->readonly, EINA_FALSE);
|
|
EINA_SAFETY_ON_TRUE_RETURN_VAL(position > size, EINA_FALSE);
|
|
|
|
if (pd->position_write == position) return EINA_TRUE;
|
|
|
|
changed = efl_io_positioner_position_get(o) != position;
|
|
|
|
pd->position_write = position;
|
|
efl_event_callback_call(o, EFL_IO_BUFFER_EVENT_POSITION_WRITE_CHANGED, NULL);
|
|
if (changed)
|
|
efl_event_callback_call(o, EFL_IO_POSITIONER_EVENT_POSITION_CHANGED, NULL);
|
|
|
|
if (pd->closed) return 0;
|
|
|
|
limit = efl_io_buffer_limit_get(o);
|
|
efl_io_writer_can_write_set(o, (limit == 0) || (position < limit));
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static uint64_t
|
|
_efl_io_buffer_position_write_get(const Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
|
|
{
|
|
return pd->position_write;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_adopt_readonly(Eo *o, Efl_Io_Buffer_Data *pd, const Eina_Slice slice)
|
|
{
|
|
Eina_Bool changed_size;
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
|
|
|
|
if (!pd->readonly) free(pd->bytes);
|
|
pd->readonly = EINA_TRUE;
|
|
pd->bytes = (uint8_t *)slice.bytes;
|
|
pd->allocated = slice.len;
|
|
|
|
changed_size = (pd->used != slice.len);
|
|
pd->used = slice.len;
|
|
efl_io_writer_can_write_set(o, EINA_FALSE);
|
|
if (pd->closed) return;
|
|
|
|
if (efl_io_buffer_position_read_get(o) > slice.len)
|
|
{
|
|
efl_io_buffer_position_read_set(o, slice.len);
|
|
if (pd->closed) return;
|
|
}
|
|
|
|
efl_io_buffer_position_write_set(o, slice.len);
|
|
if (pd->closed) return;
|
|
|
|
if (changed_size)
|
|
{
|
|
efl_event_callback_call(o, EFL_IO_SIZER_EVENT_SIZE_CHANGED, NULL);
|
|
if (pd->closed) return;
|
|
}
|
|
|
|
efl_event_callback_call(o, EFL_IO_BUFFER_EVENT_REALLOCATED, NULL);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_io_buffer_adopt_readwrite(Eo *o, Efl_Io_Buffer_Data *pd, Eina_Rw_Slice slice)
|
|
{
|
|
Eina_Bool changed_size;
|
|
|
|
EINA_SAFETY_ON_TRUE_RETURN(efl_io_closer_closed_get(o));
|
|
|
|
if (!pd->readonly) free(pd->bytes);
|
|
pd->readonly = EINA_FALSE;
|
|
pd->bytes = slice.bytes;
|
|
pd->allocated = slice.len;
|
|
|
|
changed_size = (pd->used != slice.len);
|
|
pd->used = slice.len;
|
|
|
|
efl_io_writer_can_write_set(o, (pd->limit == 0) ||
|
|
(efl_io_buffer_position_write_get(o) < pd->limit));
|
|
if (pd->closed) return;
|
|
|
|
if (efl_io_buffer_position_read_get(o) > slice.len)
|
|
{
|
|
efl_io_buffer_position_read_set(o, slice.len);
|
|
if (pd->closed) return;
|
|
}
|
|
|
|
if (efl_io_buffer_position_write_get(o) > slice.len)
|
|
{
|
|
efl_io_buffer_position_write_set(o, slice.len);
|
|
if (pd->closed) return;
|
|
}
|
|
|
|
if (changed_size)
|
|
{
|
|
efl_event_callback_call(o, EFL_IO_SIZER_EVENT_SIZE_CHANGED, NULL);
|
|
if (pd->closed) return;
|
|
}
|
|
|
|
efl_event_callback_call(o, EFL_IO_BUFFER_EVENT_REALLOCATED, NULL);
|
|
}
|
|
|
|
#include "interfaces/efl_io_buffer.eo.c"
|