Eina_Bool closed;
Eina_Bool can_read;
Eina_Bool can_write;
+ Eina_Bool readonly;
} Efl_Io_Buffer_Data;
static Eina_Bool
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;
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;
_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);
if (pd->bytes)
{
- free(pd->bytes);
+ if (!pd->readonly) free(pd->bytes);
pd->bytes = NULL;
pd->allocated = 0;
pd->used = 0;
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);
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;
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);
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;
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"
}
}
+ adopt_readonly {
+ [[Adopt a read-only slice as buffer's backing store.
+
+ The slice memory will not be copied and must remain
+ alive during buffer's lifetime. Usually this is
+ guaranteed by some global static-const memory or some
+ parent object and this buffer being a view of that -- be
+ aware of parent memory remaining alive, such as
+ "slice,changed" events.
+ ]]
+ params {
+ @in slice: const(Eina.Slice); [[Slice to adopt as read-only]]
+ }
+ }
+
+ adopt_readwrite {
+ [[Adopt a read-write slice as buffer's backing store.
+
+ The slice memory will not be copied and must remain
+ alive during buffer's lifetime. Usually this is
+ guaranteed by some global static memory or some
+ parent object and this buffer being a view of that -- be
+ aware of parent memory remaining alive, such as
+ "slice,changed" events.
+
+ The memory will be disposed using free() and reallocated
+ using realloc().
+ ]]
+ params {
+ @in slice: Eina.Rw_Slice; [[Slice to adopt as read-write]]
+ }
+ }
+
@property limit {
[[Limit how big the buffer can grow.
[[Steals the internal buffer memory and returns it as a binbuf.
The returned memory must be freed with eina_binbuf_free().
+
+ On failure, for example a read-only backing store was
+ adopted with @.adopt_readonly, NULL is returned.
]]
return: free(own(ptr(Eina.Binbuf)), eina_binbuf_free) @warn_unused; [[Binbuf]]
}