forked from enlightenment/efl
eina: introduce Eina_Slice and Eina_Rw_Slice.
A plain simple pointer + length describing a linear memory region.
This commit is contained in:
parent
8906461b48
commit
9062bbd8e0
|
@ -99,7 +99,9 @@ lib/eina/eina_inline_vector.x \
|
||||||
lib/eina/eina_promise.h \
|
lib/eina/eina_promise.h \
|
||||||
lib/eina/eina_bezier.h \
|
lib/eina/eina_bezier.h \
|
||||||
lib/eina/eina_safepointer.h \
|
lib/eina/eina_safepointer.h \
|
||||||
lib/eina/eina_inline_safepointer.x
|
lib/eina/eina_inline_safepointer.x \
|
||||||
|
lib/eina/eina_slice.h \
|
||||||
|
lib/eina/eina_inline_slice.x
|
||||||
|
|
||||||
lib_eina_libeina_la_SOURCES = \
|
lib_eina_libeina_la_SOURCES = \
|
||||||
lib/eina/eina_abi.c \
|
lib/eina/eina_abi.c \
|
||||||
|
@ -330,7 +332,8 @@ tests/eina/eina_test_quaternion.c \
|
||||||
tests/eina/eina_test_vector.c \
|
tests/eina/eina_test_vector.c \
|
||||||
tests/eina/eina_test_promise.c \
|
tests/eina/eina_test_promise.c \
|
||||||
tests/eina/eina_test_bezier.c \
|
tests/eina/eina_test_bezier.c \
|
||||||
tests/eina/eina_test_safepointer.c
|
tests/eina/eina_test_safepointer.c \
|
||||||
|
tests/eina/eina_test_slice.c
|
||||||
|
|
||||||
tests_eina_eina_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
tests_eina_eina_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
|
||||||
-DTESTS_WD=\"`pwd`\" \
|
-DTESTS_WD=\"`pwd`\" \
|
||||||
|
|
|
@ -271,6 +271,7 @@ extern "C" {
|
||||||
#include <eina_promise.h>
|
#include <eina_promise.h>
|
||||||
#include <eina_bezier.h>
|
#include <eina_bezier.h>
|
||||||
#include <eina_safepointer.h>
|
#include <eina_safepointer.h>
|
||||||
|
#include <eina_slice.h>
|
||||||
|
|
||||||
#undef EAPI
|
#undef EAPI
|
||||||
#define EAPI
|
#define EAPI
|
||||||
|
|
|
@ -0,0 +1,232 @@
|
||||||
|
/* EINA - EFL data type library
|
||||||
|
* Copyright (C) 2016 ProFUSION embedded systems
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library;
|
||||||
|
* if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EINA_INLINE_SLICE_H
|
||||||
|
#define _EINA_INLINE_SLICE_H
|
||||||
|
|
||||||
|
static inline Eina_Slice
|
||||||
|
eina_rw_slice_slice_get(const Eina_Rw_Slice rw_slice)
|
||||||
|
{
|
||||||
|
Eina_Slice ret;
|
||||||
|
ret.len = rw_slice.len;
|
||||||
|
ret.mem = rw_slice.mem;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Rw_Slice
|
||||||
|
eina_slice_dup(const Eina_Slice slice)
|
||||||
|
{
|
||||||
|
Eina_Rw_Slice ret;
|
||||||
|
|
||||||
|
ret.len = slice.len;
|
||||||
|
ret.mem = NULL;
|
||||||
|
if (ret.len == 0) return ret;
|
||||||
|
|
||||||
|
ret.mem = malloc(ret.len);
|
||||||
|
if (!ret.mem)
|
||||||
|
ret.len = 0;
|
||||||
|
else
|
||||||
|
memcpy(ret.mem, slice.mem, ret.len);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Rw_Slice
|
||||||
|
eina_rw_slice_dup(const Eina_Rw_Slice rw_slice)
|
||||||
|
{
|
||||||
|
return eina_slice_dup(eina_rw_slice_slice_get(rw_slice));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
eina_slice_compare(const Eina_Slice a, const Eina_Slice b)
|
||||||
|
{
|
||||||
|
const size_t len = a.len <= b.len ? a.len : b.len;
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
int r = memcmp(a.mem, b.mem, len);
|
||||||
|
if (r != 0) return r;
|
||||||
|
}
|
||||||
|
if (a.len < b.len) return -1;
|
||||||
|
else if (a.len > b.len) return 1;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
eina_rw_slice_compare(const Eina_Rw_Slice a, const Eina_Rw_Slice b)
|
||||||
|
{
|
||||||
|
return eina_slice_compare(eina_rw_slice_slice_get(a),
|
||||||
|
eina_rw_slice_slice_get(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Rw_Slice
|
||||||
|
eina_rw_slice_copy(const Eina_Rw_Slice dst, const Eina_Slice src)
|
||||||
|
{
|
||||||
|
const size_t len = src.len <= dst.len ? src.len : dst.len;
|
||||||
|
Eina_Rw_Slice ret;
|
||||||
|
|
||||||
|
ret.len = len;
|
||||||
|
ret.mem = dst.mem;
|
||||||
|
if (len > 0) memcpy(ret.mem, src.mem, len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Slice
|
||||||
|
eina_slice_seek(const Eina_Slice slice, ssize_t offset, int whence)
|
||||||
|
{
|
||||||
|
Eina_Slice ret;
|
||||||
|
|
||||||
|
ret.len = 0;
|
||||||
|
ret.mem = slice.mem;
|
||||||
|
|
||||||
|
if (whence == SEEK_END)
|
||||||
|
{
|
||||||
|
whence = SEEK_SET;
|
||||||
|
offset += slice.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whence != SEEK_SET)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
offset = 0;
|
||||||
|
else if ((size_t)offset > slice.len)
|
||||||
|
offset = slice.len;
|
||||||
|
|
||||||
|
ret.len = slice.len - offset;
|
||||||
|
ret.mem = (const void *)(slice.bytes + offset);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Eina_Rw_Slice
|
||||||
|
eina_rw_slice_seek(const Eina_Rw_Slice rw_slice, ssize_t offset, int whence)
|
||||||
|
{
|
||||||
|
Eina_Rw_Slice ret;
|
||||||
|
|
||||||
|
ret.len = 0;
|
||||||
|
ret.mem = rw_slice.mem;
|
||||||
|
|
||||||
|
if (whence == SEEK_END)
|
||||||
|
{
|
||||||
|
whence = SEEK_SET;
|
||||||
|
offset += rw_slice.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whence != SEEK_SET)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (offset < 0)
|
||||||
|
offset = 0;
|
||||||
|
else if ((size_t)offset > rw_slice.len)
|
||||||
|
offset = rw_slice.len;
|
||||||
|
|
||||||
|
ret.len = rw_slice.len - offset;
|
||||||
|
ret.mem = (void *)(rw_slice.bytes + offset);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const void *
|
||||||
|
eina_slice_strchr(const Eina_Slice slice, int c)
|
||||||
|
{
|
||||||
|
if (slice.len == 0) return NULL;
|
||||||
|
return memchr(slice.mem, c, slice.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const void *
|
||||||
|
eina_slice_find(const Eina_Slice slice, const Eina_Slice needle)
|
||||||
|
{
|
||||||
|
Eina_Slice s, n;
|
||||||
|
uint8_t c;
|
||||||
|
|
||||||
|
if (slice.len == 0) return NULL;
|
||||||
|
if (needle.len == 0) return NULL;
|
||||||
|
if (slice.len < needle.len) return NULL;
|
||||||
|
if (slice.len == 1) return eina_slice_strchr(slice, needle.bytes[0]);
|
||||||
|
if ((slice.len == needle.len) &&
|
||||||
|
(memcmp(slice.mem, needle.mem, needle.len) == 0))
|
||||||
|
return slice.mem;
|
||||||
|
|
||||||
|
s.mem = slice.mem;
|
||||||
|
s.len = slice.len - needle.len;
|
||||||
|
|
||||||
|
c = needle.bytes[0];
|
||||||
|
n.mem = (const void *)(needle.bytes + 1);
|
||||||
|
n.len = needle.len - 1;
|
||||||
|
|
||||||
|
while (s.len > 0)
|
||||||
|
{
|
||||||
|
const uint8_t *p = (const uint8_t *)eina_slice_strchr(s, c);
|
||||||
|
size_t offset;
|
||||||
|
|
||||||
|
if (!p) return NULL;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
if (memcmp(p, n.mem, n.len) == 0)
|
||||||
|
return (const void *)(p - 1);
|
||||||
|
|
||||||
|
offset = p - s.bytes;
|
||||||
|
s.bytes += offset;
|
||||||
|
s.len -= offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
eina_rw_slice_strchr(const Eina_Rw_Slice rw_slice, int c)
|
||||||
|
{
|
||||||
|
if (rw_slice.len == 0) return NULL;
|
||||||
|
return memchr(rw_slice.mem, c, rw_slice.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
eina_rw_slice_find(const Eina_Rw_Slice rw_slice, const Eina_Slice needle)
|
||||||
|
{
|
||||||
|
return (void *)eina_slice_find(eina_rw_slice_slice_get(rw_slice), needle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const void *
|
||||||
|
eina_slice_end_get(const Eina_Slice slice)
|
||||||
|
{
|
||||||
|
return (const void *)(slice.bytes + slice.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *
|
||||||
|
eina_rw_slice_end_get(const Eina_Rw_Slice rw_slice)
|
||||||
|
{
|
||||||
|
return (void *)(rw_slice.bytes + rw_slice.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
eina_slice_strdup(const Eina_Slice slice)
|
||||||
|
{
|
||||||
|
if (slice.len == 0)
|
||||||
|
return strdup("");
|
||||||
|
else
|
||||||
|
return strndup((const char *)slice.mem, slice.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *
|
||||||
|
eina_rw_slice_strdup(const Eina_Rw_Slice rw_slice)
|
||||||
|
{
|
||||||
|
if (rw_slice.len == 0)
|
||||||
|
return strdup("");
|
||||||
|
else
|
||||||
|
return strndup((const char *)rw_slice.mem, rw_slice.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _EINA_INLINE_SLICE_H */
|
|
@ -0,0 +1,530 @@
|
||||||
|
/* EINA - EFL data type library
|
||||||
|
* Copyright (C) 2016 ProFUSION embedded systems
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library;
|
||||||
|
* if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EINA_SLICE_H
|
||||||
|
#define _EINA_SLICE_H
|
||||||
|
|
||||||
|
#include "eina_types.h"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Eina_Slice_Group Memory Slices
|
||||||
|
*
|
||||||
|
* @brief These functions provide memory slices in read-only and
|
||||||
|
* read-write forms.
|
||||||
|
*
|
||||||
|
* Memory slices define a contiguous linear memory starting at a given
|
||||||
|
* pointer (@c mem) and spanning for a given length (@c len).
|
||||||
|
*
|
||||||
|
* They may be read-only (Eina_Slice) or read-write (Eina_Rw_Slice).
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup Eina_Data_Types_Group Data Types
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup Eina_Slice_Group Memory Slices
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Eina_Slice
|
||||||
|
* Defines a read-only memory region.
|
||||||
|
*
|
||||||
|
* The slice is a memory starting at @c mem and accessible up to @c
|
||||||
|
* len bytes.
|
||||||
|
*
|
||||||
|
* @see Eina_Rw_Slice for read-write memory regions.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
typedef struct _Eina_Slice Eina_Slice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef Eina_Rw_Slice
|
||||||
|
* Defines a read-and-write able memory region.
|
||||||
|
*
|
||||||
|
* The slice is a memory starting at @c mem and accessible up to @c
|
||||||
|
* len bytes.
|
||||||
|
*
|
||||||
|
* @see Eina_Slice for read-only memory regions.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
typedef struct _Eina_Rw_Slice Eina_Rw_Slice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct _Eina_Slice
|
||||||
|
* Defines a read-only memory region.
|
||||||
|
*
|
||||||
|
* The slice is a memory starting at @c mem and accessible up to @c
|
||||||
|
* len bytes.
|
||||||
|
*
|
||||||
|
* @see Eina_Rw_Slice for read-write memory regions.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
struct _Eina_Slice
|
||||||
|
{
|
||||||
|
size_t len; /**< size of memory pointed by @c mem */
|
||||||
|
union {
|
||||||
|
const void *mem; /**< memory pointed by this slice. Just read, never modify it. */
|
||||||
|
const uint8_t *bytes; /**< memory as uint8_t pointer */
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @struct _Eina_Rw_Slice
|
||||||
|
* Defines a read-and-write able memory region.
|
||||||
|
*
|
||||||
|
* The slice is a memory starting at @c mem and accessible up to @c
|
||||||
|
* len bytes.
|
||||||
|
*
|
||||||
|
* @see Eina_Slice for read-only memory regions.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
struct _Eina_Rw_Slice
|
||||||
|
{
|
||||||
|
size_t len; /**< size of memory pointed by @c mem */
|
||||||
|
union {
|
||||||
|
void *mem; /**< memory pointed by this slice. It's write able. */
|
||||||
|
uint8_t *bytes; /**< memory as uint8_t pointer */
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert the Read-write slice to read-only.
|
||||||
|
*
|
||||||
|
* @param rw_slice the read-write slice to convert.
|
||||||
|
* @return the red-only slice matching the slice.
|
||||||
|
*/
|
||||||
|
static inline Eina_Slice eina_rw_slice_slice_get(const Eina_Rw_Slice rw_slice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a duplicate of slice's memory.
|
||||||
|
*
|
||||||
|
* @param slice the input to duplicate
|
||||||
|
* @return a new read-write slice with new @c mem that matches @a slice
|
||||||
|
* contents. The new @c mem is allocated with malloc() and must
|
||||||
|
* be released with free().
|
||||||
|
*
|
||||||
|
* @see eina_rw_slice_copy()
|
||||||
|
* @see eina_rw_slice_dup()
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline Eina_Rw_Slice eina_slice_dup(const Eina_Slice slice) EINA_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a duplicate of slice's memory.
|
||||||
|
*
|
||||||
|
* @param rw_slice the input to duplicate
|
||||||
|
* @return a new read-write slice with new @c mem that matches @a slice
|
||||||
|
* contents. The new @c mem is allocated with malloc() and must
|
||||||
|
* be released with free().
|
||||||
|
*
|
||||||
|
* @see eina_rw_slice_copy()
|
||||||
|
* @see eina_slice_dup()
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline Eina_Rw_Slice eina_rw_slice_dup(const Eina_Rw_Slice rw_slice) EINA_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compare two slices, similar to memcmp()
|
||||||
|
*
|
||||||
|
* @param a the first slice to compare.
|
||||||
|
* @param b the second slice to compare.
|
||||||
|
* @return 0 if equal, < 0 if a < b, > 0 if a > b
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline int eina_slice_compare(const Eina_Slice a, const Eina_Slice b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compare two slices, similar to memcmp()
|
||||||
|
*
|
||||||
|
* @param a the first slice to compare.
|
||||||
|
* @param b the second slice to compare.
|
||||||
|
* @return 0 if equal, < 0 if a < b, > 0 if a > b
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline int eina_rw_slice_compare(const Eina_Rw_Slice a, const Eina_Rw_Slice b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Copy a read-only slice to a read-write one, similar to memcpy().
|
||||||
|
*
|
||||||
|
* @param dest where to write the memory.
|
||||||
|
* @param src where to load memory.
|
||||||
|
*
|
||||||
|
* @return a new slice with the resulting write. Note that the length
|
||||||
|
* (@c len) will be the smallest of @a dest and @a src.
|
||||||
|
*
|
||||||
|
* @see eina_rw_slice_dup()
|
||||||
|
* @see eina_slice_dup()
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline Eina_Rw_Slice eina_rw_slice_copy(const Eina_Rw_Slice dest, const Eina_Slice src);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Seek within a slice, similar to fseek().
|
||||||
|
*
|
||||||
|
* @param slice the containing slice to seek inside.
|
||||||
|
* @param offset how to get to the new position.
|
||||||
|
* @param whence SEEK_SET, SEEK_END as fseek().
|
||||||
|
* @return a new slice contained inside, it will start at the given
|
||||||
|
* offset and have a length that goes until the end of the @a
|
||||||
|
* slice. If an invalid @a whence, a zero-sized slice starting
|
||||||
|
* at @a slice mem will be returned. The slice is guaranteed
|
||||||
|
* to be contained within @a slice, even if offset causes it
|
||||||
|
* to go out of bounds, then it will be clamped to 0 and
|
||||||
|
* slice.len.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline Eina_Slice eina_slice_seek(const Eina_Slice slice, ssize_t offset, int whence);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Seek within a read-write slice, similar to fseek().
|
||||||
|
*
|
||||||
|
* @param rw_slice the containing slice to seek inside.
|
||||||
|
* @param offset how to get to the new position.
|
||||||
|
* @param whence SEEK_SET, SEEK_END as fseek().
|
||||||
|
* @return a new slice contained inside, it will start at the given
|
||||||
|
* offset and have a length that goes until the end of the @a
|
||||||
|
* rw_slice. If an invalid @a whence, a zero-sized slice
|
||||||
|
* starting at @a rw_slice mem will be returned. The slice is
|
||||||
|
* guaranteed to be contained within @a rw_slice, even if
|
||||||
|
* offset causes it to go out of bounds, then it will be
|
||||||
|
* clamped to 0 and slice.len.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline Eina_Rw_Slice eina_rw_slice_seek(const Eina_Rw_Slice rw_slice, ssize_t offset, int whence);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find a character inside the slice, similar to memchr().
|
||||||
|
*
|
||||||
|
* @param slice the reference memory.
|
||||||
|
* @param c the byte (character) to find.
|
||||||
|
* @return the memory within slice or @c NULL if not found.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline const void *eina_slice_strchr(const Eina_Slice slice, int c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find a needle inside the slice, similar to memmem().
|
||||||
|
*
|
||||||
|
* @param slice the reference memory.
|
||||||
|
* @param needle what to find.
|
||||||
|
* @return the memory within slice or @c NULL if not found.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline const void *eina_slice_find(const Eina_Slice slice, const Eina_Slice needle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find a character inside the slice, similar to memchr().
|
||||||
|
*
|
||||||
|
* @param rw_slice the reference memory.
|
||||||
|
* @param c the byte (character) to find.
|
||||||
|
* @return the memory within slice or @c NULL if not found.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline void *eina_rw_slice_strchr(const Eina_Rw_Slice rw_slice, int c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find a needle inside the slice, similar to memmem().
|
||||||
|
*
|
||||||
|
* @param rw_slice the reference memory.
|
||||||
|
* @param needle what to find.
|
||||||
|
* @return the memory within slice or @c NULL if not found.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline void *eina_rw_slice_find(const Eina_Rw_Slice rw_slice, const Eina_Slice needle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The memory position where the slice ends.
|
||||||
|
*
|
||||||
|
* @note this is out-of the slice, the first byte after it ends and
|
||||||
|
* must not be accessed.
|
||||||
|
*
|
||||||
|
* @param slice the reference memory.
|
||||||
|
* @return the first byte after the slice ends.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline const void *eina_slice_end_get(const Eina_Slice slice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The memory position where the slice ends.
|
||||||
|
*
|
||||||
|
* @note this is out-of the slice, the first byte after it ends and
|
||||||
|
* must not be accessed.
|
||||||
|
*
|
||||||
|
* @param rw_slice the reference memory.
|
||||||
|
* @return the first byte after the slice ends.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline void *eina_rw_slice_end_get(const Eina_Rw_Slice rw_slice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A null-terminated string for this slice.
|
||||||
|
*
|
||||||
|
* @param slice the reference memory.
|
||||||
|
* @return newly allocated memory or @c NULL on error
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline char *eina_slice_strdup(const Eina_Slice slice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A null-terminated string for this slice.
|
||||||
|
*
|
||||||
|
* @param slice the reference memory.
|
||||||
|
* @return newly allocated memory or @c NULL on error
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
static inline char *eina_rw_slice_strdup(const Eina_Rw_Slice rw_slice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_ARRAY(buf)
|
||||||
|
*
|
||||||
|
* Initializer for arrays of any kind.
|
||||||
|
*
|
||||||
|
* It is often useful for globals.
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* static uint8_t buf[1024];
|
||||||
|
* static Eina_Slice rw_slice = EINA_SLICE_ARRAY(buf);
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @see EINA_SLICE_STR_LITERAL() for specific version that checks for string literals.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EINA_SLICE_ARRAY(buf) {((sizeof(buf) / sizeof((buf)[0])) * sizeof((buf)[0])), (buf)}
|
||||||
|
#else
|
||||||
|
#define EINA_SLICE_ARRAY(buf) {.len = ((sizeof(buf) / sizeof((buf)[0])) * sizeof((buf)[0])), .mem = (buf)}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_RW_SLICE_DECLARE(name, length)
|
||||||
|
*
|
||||||
|
* Declare a local (stack) array for storage at given @a length and
|
||||||
|
* initialize an Eina_Rw_Slice called @a name.
|
||||||
|
*
|
||||||
|
* @param name the name of the variable to be the Eina_Rw_Slice
|
||||||
|
* @param length the size in bytes of the storage.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#define EINA_RW_SLICE_DECLARE(name, length) \
|
||||||
|
uint8_t _eina_slice_storage_ ## name [(length)] = { 0 }; \
|
||||||
|
Eina_Rw_Slice name = EINA_SLICE_ARRAY(_eina_slice_storage_ ## name)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_STR_LITERAL(buf)
|
||||||
|
*
|
||||||
|
* Initializer for string literals (those declared as
|
||||||
|
* double-quoted). The size will @b NOT include the trainling
|
||||||
|
* null-terminator.
|
||||||
|
*
|
||||||
|
* It is often useful for globals.
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* static const Eina_Slice ro_slice = EINA_SLICE_STR_LITERAL("hello world");
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @see EINA_SLICE_STR() for more generic version.
|
||||||
|
* @see EINA_SLICE_ARRAY() for version that uses a general array.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EINA_SLICE_STR_LITERAL(buf) {(sizeof("" buf) - 1), (buf)}
|
||||||
|
#else
|
||||||
|
#define EINA_SLICE_STR_LITERAL(buf) {.len = (sizeof("" buf) - 1), .mem = (buf)}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_STR(str)
|
||||||
|
*
|
||||||
|
* Initializer for strings (uses strlen()).
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Eina_Slice ro_slice = EINA_SLICE_STR("hello world");
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @see EINA_SLICE_STR() for specific version using literals.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EINA_SLICE_STR(str) {strlen((str)), (str)}
|
||||||
|
#else
|
||||||
|
#define EINA_SLICE_STR(str) {.len = strlen((str)), .mem = (str)}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_STR_FMT
|
||||||
|
*
|
||||||
|
* To be used in printf()-like statements, prints the slice as a
|
||||||
|
* string, its @c len is to be used, then it doesn need the null
|
||||||
|
* terminator.
|
||||||
|
*
|
||||||
|
* Use with EINA_SLICE_STR_PRINT()
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Eina_Slice s = EINA_SLICE_STR_LITERAL("hello");
|
||||||
|
* printf("s=" EINA_SLICE_STR_FMT "\n", EINA_SLICE_STR_PRINT(s));
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#define EINA_SLICE_STR_FMT "%.*s"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_STR_PRINT(s)
|
||||||
|
*
|
||||||
|
* To be used in printf()-like statements when EINA_SLICE_STR_FMT was
|
||||||
|
* used, it will print the slice as a string up to @c len.
|
||||||
|
*
|
||||||
|
* Use with EINA_SLICE_STR_FMT.
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Eina_Slice s = EINA_SLICE_STR_LITERAL("hello");
|
||||||
|
* printf("s=" EINA_SLICE_STR_FMT "\n", EINA_SLICE_STR_PRINT(s));
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#define EINA_SLICE_STR_PRINT(s) (int)(s).len, (const char *)(s).mem
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_FMT
|
||||||
|
*
|
||||||
|
* To be used in printf()-like statements, prints the slice as
|
||||||
|
* @c 0x1234+12 (@c mem + @c len).
|
||||||
|
*
|
||||||
|
* Use with EINA_SLICE_PRINT()
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Eina_Slice s = EINA_SLICE_STR_LITERAL("hello");
|
||||||
|
* printf("s=" EINA_SLICE_FMT "\n", EINA_SLICE_PRINT(s));
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#define EINA_SLICE_FMT "%p+%zu"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_PRINT(s)
|
||||||
|
*
|
||||||
|
* To be used in printf()-like statements when EINA_SLICE_FMT was
|
||||||
|
* used, it will print the slice @c mem and @c len.
|
||||||
|
*
|
||||||
|
* Use with EINA_SLICE_FMT.
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @param s the slice
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* Eina_Slice s = EINA_SLICE_STR_LITERAL("hello");
|
||||||
|
* printf("s=" EINA_SLICE_FMT "\n", EINA_SLICE_PRINT(s));
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#define EINA_SLICE_PRINT(s) (s).mem, (s).len
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def EINA_SLICE_FOREACH(s, itr)
|
||||||
|
*
|
||||||
|
* Iterate over the slice memory, using @c itr. Each increment will be
|
||||||
|
* using the size of @c itr pointer (int32_t* will do in increments of
|
||||||
|
* 4 bytes).
|
||||||
|
*
|
||||||
|
* @note This macro is usable with both Eina_Slice or Eina_Rw_Slice.
|
||||||
|
*
|
||||||
|
* @note Be aware of memory alignment! Accessing unaligned memory may
|
||||||
|
* not be supported in some architectures.
|
||||||
|
*
|
||||||
|
* @param s the slice
|
||||||
|
* @param itr the iterator to hold each byte. Use a proper type, not
|
||||||
|
* "void*" or "const void*" as it doesn't have an intrinsic
|
||||||
|
* size.
|
||||||
|
*
|
||||||
|
* @since 1.19
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EINA_SLICE_FOREACH(s, itr) \
|
||||||
|
for ((itr) = static_cast<__typeof__(itr)>((s).mem); \
|
||||||
|
(itr) < static_cast<__typeof__(itr)>(static_cast<void *>((s).bytes + (s).len)); \
|
||||||
|
(itr)++)
|
||||||
|
#else
|
||||||
|
#define EINA_SLICE_FOREACH(s, itr) \
|
||||||
|
for ((itr) = (s).mem; \
|
||||||
|
(void *)(itr) < (void *)((s).bytes + (s).len); \
|
||||||
|
(itr)++)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "eina_inline_slice.x"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* _EINA_SLICE_H */
|
|
@ -43,3 +43,15 @@ enum @extern Eina.Xattr.Flags {
|
||||||
type @extern Eina.Error: int;
|
type @extern Eina.Error: int;
|
||||||
|
|
||||||
struct @extern @free(eina_binbuf_free) Eina.Binbuf;
|
struct @extern @free(eina_binbuf_free) Eina.Binbuf;
|
||||||
|
|
||||||
|
struct @extern Eina.Slice {
|
||||||
|
[[A linear, read-only, memory segment]]
|
||||||
|
len: size;
|
||||||
|
mem: const(void_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct @extern Eina.Rw_Slice {
|
||||||
|
[[A linear, read-write, memory segment]]
|
||||||
|
len: size;
|
||||||
|
mem: void_ptr;
|
||||||
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ static const Efl_Test_Case etc[] = {
|
||||||
{ "Promise", eina_test_promise },
|
{ "Promise", eina_test_promise },
|
||||||
{ "Bezier", eina_test_bezier },
|
{ "Bezier", eina_test_bezier },
|
||||||
{ "SafePointer", eina_test_safepointer },
|
{ "SafePointer", eina_test_safepointer },
|
||||||
|
{ "Slice", eina_test_slice },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -72,5 +72,6 @@ void eina_test_vector(TCase *tc);
|
||||||
void eina_test_promise(TCase *tc);
|
void eina_test_promise(TCase *tc);
|
||||||
void eina_test_bezier(TCase *tc);
|
void eina_test_bezier(TCase *tc);
|
||||||
void eina_test_safepointer(TCase *tc);
|
void eina_test_safepointer(TCase *tc);
|
||||||
|
void eina_test_slice(TCase *tc);
|
||||||
|
|
||||||
#endif /* EINA_SUITE_H_ */
|
#endif /* EINA_SUITE_H_ */
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
/* EINA - EFL data type library
|
||||||
|
* Copyright (C) 2016 ProFUSION embedded systems
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library;
|
||||||
|
* if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <Eina.h>
|
||||||
|
|
||||||
|
#include "eina_suite.h"
|
||||||
|
|
||||||
|
START_TEST(eina_test_slice_init)
|
||||||
|
{
|
||||||
|
Eina_Rw_Slice a = EINA_SLICE_STR_LITERAL("hello world");
|
||||||
|
char buf[1024] = "";
|
||||||
|
Eina_Rw_Slice b = EINA_SLICE_ARRAY(buf);
|
||||||
|
Eina_Rw_Slice c = EINA_SLICE_STR("hi there");
|
||||||
|
EINA_RW_SLICE_DECLARE(d, 512);
|
||||||
|
|
||||||
|
eina_init();
|
||||||
|
|
||||||
|
fail_unless(a.len == sizeof("hello world") - 1);
|
||||||
|
fail_unless(strcmp(a.mem, "hello world") == 0);
|
||||||
|
|
||||||
|
fail_unless(b.len == sizeof(buf));
|
||||||
|
|
||||||
|
fail_unless(c.len == strlen("hi there"));
|
||||||
|
fail_unless(strcmp(c.mem, "hi there") == 0);
|
||||||
|
|
||||||
|
fail_unless(d.len == 512);
|
||||||
|
|
||||||
|
eina_shutdown();
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(eina_test_slice_ro)
|
||||||
|
{
|
||||||
|
Eina_Slice slice = EINA_SLICE_STR_LITERAL("hi there");
|
||||||
|
Eina_Slice a, needle;
|
||||||
|
Eina_Rw_Slice dup;
|
||||||
|
const void *p;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
dup = eina_slice_dup(slice);
|
||||||
|
fail_unless(dup.len == slice.len);
|
||||||
|
fail_unless(dup.mem != slice.mem);
|
||||||
|
fail_unless(eina_slice_compare(eina_rw_slice_slice_get(dup), slice) == 0);
|
||||||
|
free(dup.mem);
|
||||||
|
|
||||||
|
str = eina_slice_strdup(slice);
|
||||||
|
fail_unless(str != NULL);
|
||||||
|
fail_unless(strcmp(str, "hi there") == 0);
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
a = eina_slice_seek(slice, strlen("hi "), SEEK_SET);
|
||||||
|
fail_unless(a.mem == slice.bytes + strlen("hi "));
|
||||||
|
fail_unless(a.len == slice.len - strlen("hi "));
|
||||||
|
|
||||||
|
a = eina_slice_seek(slice, 0, SEEK_SET);
|
||||||
|
fail_unless(a.mem == slice.bytes + 0);
|
||||||
|
fail_unless(a.len == slice.len);
|
||||||
|
|
||||||
|
a = eina_slice_seek(slice, -1, SEEK_END);
|
||||||
|
fail_unless(a.mem == slice.bytes + slice.len - 1);
|
||||||
|
fail_unless(a.len == 1);
|
||||||
|
|
||||||
|
a = eina_slice_seek(slice, 0, SEEK_END);
|
||||||
|
fail_unless(a.mem == eina_slice_end_get(slice));
|
||||||
|
fail_unless(a.len == 0);
|
||||||
|
|
||||||
|
p = eina_slice_end_get(slice);
|
||||||
|
fail_unless(p == slice.bytes + slice.len);
|
||||||
|
|
||||||
|
slice = (Eina_Slice)EINA_SLICE_STR_LITERAL("HELLO WORLD");
|
||||||
|
slice.len = strlen("hi there"); /* crop... */
|
||||||
|
|
||||||
|
p = eina_slice_strchr(slice, ' ');
|
||||||
|
fail_unless(p == slice.bytes + 5); /* 5 = index of ' ' in HELLO WORLD.. */
|
||||||
|
|
||||||
|
p = eina_slice_strchr(slice, '!');
|
||||||
|
fail_unless(p == NULL);
|
||||||
|
|
||||||
|
needle = (Eina_Slice)EINA_SLICE_STR_LITERAL(" W");
|
||||||
|
p = eina_slice_find(slice, needle);
|
||||||
|
fail_unless(p == slice.bytes + 5); /* 5 = index of ' W' in HELLO WORLD..*/
|
||||||
|
|
||||||
|
needle = (Eina_Slice)EINA_SLICE_STR_LITERAL("LO");
|
||||||
|
p = eina_slice_find(slice, needle);
|
||||||
|
fail_unless(p == slice.bytes + 3); /* 3 = index of 'LO' in HELLO WORLD..*/
|
||||||
|
|
||||||
|
needle = (Eina_Slice)EINA_SLICE_STR_LITERAL("HELLO");
|
||||||
|
p = eina_slice_find(slice, needle);
|
||||||
|
fail_unless(p == slice.mem);
|
||||||
|
|
||||||
|
needle = (Eina_Slice)EINA_SLICE_STR_LITERAL("WORLD"); /* would go out of boundaries */
|
||||||
|
p = eina_slice_find(slice, needle);
|
||||||
|
fail_unless(p == NULL);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(eina_test_slice_rw)
|
||||||
|
{
|
||||||
|
uint8_t buf[] = "hi there";
|
||||||
|
Eina_Rw_Slice rw_slice = EINA_SLICE_ARRAY(buf);
|
||||||
|
Eina_Slice ro_slice;
|
||||||
|
Eina_Rw_Slice a;
|
||||||
|
const void *p;
|
||||||
|
char *str;
|
||||||
|
|
||||||
|
buf[sizeof(buf) - 1] = 0xff;
|
||||||
|
rw_slice.len--; /* do not account \0 (now 0xff) */
|
||||||
|
ro_slice = eina_rw_slice_slice_get(rw_slice);
|
||||||
|
|
||||||
|
fail_unless(rw_slice.len == ro_slice.len);
|
||||||
|
fail_unless(rw_slice.mem == ro_slice.mem);
|
||||||
|
|
||||||
|
a = eina_slice_dup(ro_slice);
|
||||||
|
fail_unless(a.len == ro_slice.len);
|
||||||
|
fail_unless(a.mem != ro_slice.mem);
|
||||||
|
fail_unless(eina_rw_slice_compare(a, rw_slice) == 0);
|
||||||
|
free(a.mem);
|
||||||
|
|
||||||
|
str = eina_rw_slice_strdup(rw_slice);
|
||||||
|
fail_unless(str != NULL);
|
||||||
|
fail_unless(strcmp(str, "hi there") == 0);
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
a = eina_rw_slice_seek(rw_slice, strlen("hi "), SEEK_SET);
|
||||||
|
fail_unless(a.mem == rw_slice.bytes + strlen("hi "));
|
||||||
|
fail_unless(a.len == rw_slice.len - strlen("hi "));
|
||||||
|
|
||||||
|
a = eina_rw_slice_seek(rw_slice, 0, SEEK_SET);
|
||||||
|
fail_unless(a.mem == rw_slice.bytes + 0);
|
||||||
|
fail_unless(a.len == rw_slice.len);
|
||||||
|
|
||||||
|
a = eina_rw_slice_seek(rw_slice, -1, SEEK_END);
|
||||||
|
fail_unless(a.mem == rw_slice.bytes + rw_slice.len - 1);
|
||||||
|
fail_unless(a.len == 1);
|
||||||
|
|
||||||
|
a = eina_rw_slice_seek(rw_slice, 0, SEEK_END);
|
||||||
|
fail_unless(a.mem == eina_rw_slice_end_get(rw_slice));
|
||||||
|
fail_unless(a.len == 0);
|
||||||
|
|
||||||
|
p = eina_rw_slice_end_get(rw_slice);
|
||||||
|
fail_unless(p == rw_slice.bytes + rw_slice.len);
|
||||||
|
|
||||||
|
ro_slice = (Eina_Slice)EINA_SLICE_STR_LITERAL("HELLO WORLD, big string to be cropped");
|
||||||
|
a = eina_rw_slice_copy(rw_slice, ro_slice);
|
||||||
|
|
||||||
|
fail_unless(a.mem == rw_slice.mem);
|
||||||
|
fail_unless(a.len == rw_slice.len);
|
||||||
|
fail_unless(strncmp(a.mem, "HELLO WO", a.len) == 0);
|
||||||
|
|
||||||
|
p = eina_rw_slice_strchr(rw_slice, ' ');
|
||||||
|
fail_unless(p == rw_slice.bytes + 5); /* 5 = index of ' ' in HELLO WORLD.. */
|
||||||
|
|
||||||
|
p = eina_rw_slice_strchr(rw_slice, '!');
|
||||||
|
fail_unless(p == NULL);
|
||||||
|
|
||||||
|
ro_slice = (Eina_Slice)EINA_SLICE_STR_LITERAL(" W");
|
||||||
|
p = eina_rw_slice_find(rw_slice, ro_slice);
|
||||||
|
fail_unless(p == rw_slice.bytes + 5); /* 5 = index of ' W' in HELLO WORLD..*/
|
||||||
|
|
||||||
|
ro_slice = (Eina_Slice)EINA_SLICE_STR_LITERAL("LO");
|
||||||
|
p = eina_rw_slice_find(rw_slice, ro_slice);
|
||||||
|
fail_unless(p == rw_slice.bytes + 3); /* 3 = index of 'LO' in HELLO WORLD..*/
|
||||||
|
|
||||||
|
ro_slice = (Eina_Slice)EINA_SLICE_STR_LITERAL("HELLO");
|
||||||
|
p = eina_rw_slice_find(rw_slice, ro_slice);
|
||||||
|
fail_unless(p == rw_slice.mem);
|
||||||
|
|
||||||
|
ro_slice = (Eina_Slice)EINA_SLICE_STR_LITERAL("WORLD"); /* would go out of boundaries */
|
||||||
|
p = eina_rw_slice_find(rw_slice, ro_slice);
|
||||||
|
fail_unless(p == NULL);
|
||||||
|
|
||||||
|
fail_unless(buf[sizeof(buf) - 1] == 0xff);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(eina_test_slice_print)
|
||||||
|
{
|
||||||
|
char buf[] = "Hello World";
|
||||||
|
Eina_Slice slice = {.len = strlen("Hello"), .mem = buf};
|
||||||
|
char a[128], b[128];
|
||||||
|
|
||||||
|
snprintf(a, sizeof(a), EINA_SLICE_FMT, EINA_SLICE_PRINT(slice));
|
||||||
|
snprintf(b, sizeof(b), "%p+%zu", slice.mem, slice.len);
|
||||||
|
fail_unless(strcmp(a, b) == 0);
|
||||||
|
|
||||||
|
snprintf(a, sizeof(a), EINA_SLICE_STR_FMT, EINA_SLICE_STR_PRINT(slice));
|
||||||
|
fail_unless(strcmp(a, "Hello") == 0);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
void
|
||||||
|
eina_test_slice(TCase *tc)
|
||||||
|
{
|
||||||
|
tcase_add_test(tc, eina_test_slice_init);
|
||||||
|
tcase_add_test(tc, eina_test_slice_ro);
|
||||||
|
tcase_add_test(tc, eina_test_slice_rw);
|
||||||
|
tcase_add_test(tc, eina_test_slice_print);
|
||||||
|
}
|
Loading…
Reference in New Issue