Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework iio_context_get_xml() #1133

Merged
merged 6 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion bindings/cpp/iiopp.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class cstr
public:
cstr(std::string const & s) : s(s.c_str()){}
cstr(char const * s) : s(s){assert(s);}
cstr(void const * s) : s(static_cast<char const *>(s)){assert(s);}

char const * c_str() const {return s;}
operator char const * () const {return s;}
Expand Down Expand Up @@ -580,6 +581,8 @@ class Device : public impl::IndexedSequence<Device, Channel>
uint32_t reg_read(uint32_t address) {uint32_t value; impl::check(iio_device_reg_read(p, address, &value), "iio_device_reg_read"); return value;}
};

typedef Ptr<cstr, void, free> CstrPtr;

/** @brief C++ wrapper for the @ref Context C-API
*/
class Context : public impl::IndexedSequence<Context, Device>
Expand Down Expand Up @@ -617,7 +620,7 @@ class Context : public impl::IndexedSequence<Context, Device>
unsigned int version_major() const { return iio_context_get_version_major(p); }
unsigned int version_minor() const { return iio_context_get_version_minor(p); }
cstr version_tag() const { return iio_context_get_version_tag(p); }
cstr xml() const { return iio_context_get_xml(p); }
CstrPtr xml() const { return CstrPtr{impl::check(iio_context_get_xml(p), "iio_context_get_xml")};}
cstr name() const { return iio_context_get_name(p); }
cstr description() const { return iio_context_get_description(p); }
unsigned int attrs_count() const {return iio_context_get_attrs_count(p);}
Expand Down
11 changes: 9 additions & 2 deletions bindings/python/iio.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
c_double,
cast,
sizeof,
string_at,
POINTER as _POINTER,
CDLL as _cdll,
memmove as _memmove,
Expand Down Expand Up @@ -300,6 +301,7 @@ class ChannelType(Enum):
_iiolib = "iio"

_lib = _cdll("libiio.so.1", use_errno=True, use_last_error=True)
_libc = _cdll(find_library("c"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will fail in Windows. Need to use something like ctypes.util.find_msvcrt

Probably need to fix the _cdll call above as well since that breaks Windows too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Python bindings were broken on Windows before, and they are still broken on Windows after, then I'd argue it's not a problem of this commit and it can be fixed later in a subsequent PR. I'm kind of running against time here :)


_get_backends_count = _lib.iio_get_builtin_backends_count
_get_backends_count.restype = c_uint
Expand Down Expand Up @@ -357,7 +359,7 @@ class ChannelType(Enum):
_get_description.argtypes = (_ContextPtr,)

_get_xml = _lib.iio_context_get_xml
_get_xml.restype = c_char_p
_get_xml.restype = c_void_p
_get_xml.argtypes = (_ContextPtr,)

_get_version_major = _lib.iio_context_get_version_major
Expand Down Expand Up @@ -697,6 +699,9 @@ class ChannelType(Enum):
_ev_get_channel.argtypes = (_EventPtr, _DevicePtr, c_bool)
_ev_get_channel.errcheck = _check_null

_libc_free = _libc.free
_libc_free.argtypes = (c_void_p,)

# pylint: enable=invalid-name


Expand Down Expand Up @@ -1419,13 +1424,15 @@ def __init__(self, _context=None):

self._name = _get_name(self._context).decode("ascii")
self._description = _get_description(self._context).decode("ascii")
self._xml = _get_xml(self._context).decode("ascii")
self._xml_hdl = _get_xml(self._context)
self._xml = bytes(string_at(self._xml_hdl)).decode("ascii")
self._version = _get_lib_version(self._context)

def __del__(self):
"""Destroy this context."""
if self._context is not None:
_destroy(self._context)
_libc_free(cast(self._xml_hdl, c_void_p))

def set_timeout(self, timeout):
"""
Expand Down
15 changes: 13 additions & 2 deletions compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct compat {

const char * (*iio_context_get_name)(const struct iio_context *);
const char * (*iio_context_get_description)(const struct iio_context *);
const char * (*iio_context_get_xml)(const struct iio_context *);
char * (*iio_context_get_xml)(const struct iio_context *);
const struct iio_context_params *
(*iio_context_get_params)(const struct iio_context *);

Expand Down Expand Up @@ -260,6 +260,7 @@ struct iio_context_compat {
void *userdata;

unsigned int nb_devices;
char *xml;
};

struct iio_buffer_compat {
Expand Down Expand Up @@ -322,6 +323,11 @@ static int iio_init_context_compat(struct iio_context *ctx)
if (!compat)
return -ENOMEM;

compat->xml = IIO_CALL(iio_context_get_xml)(ctx);
err = iio_err(compat->xml);
if (err)
goto err_free_compat;

compat->nb_devices = nb_devices;

for (i = 0; i < nb_devices; i++) {
Expand Down Expand Up @@ -368,6 +374,8 @@ static int iio_init_context_compat(struct iio_context *ctx)
if (dev_compat->mask)
IIO_CALL(iio_channels_mask_destroy)(dev_compat->mask);
}
free(compat->xml);
err_free_compat:
free(compat);
return err;
}
Expand Down Expand Up @@ -442,6 +450,7 @@ void iio_context_destroy(struct iio_context *ctx)

compat = IIO_CALL(iio_context_get_data)(ctx);
IIO_CALL(iio_context_destroy)(ctx);
free(compat->xml);
free(compat);
}

Expand Down Expand Up @@ -694,7 +703,9 @@ const char * iio_context_get_description(const struct iio_context *ctx)

const char * iio_context_get_xml(const struct iio_context *ctx)
{
return IIO_CALL(iio_context_get_xml)(ctx);
struct iio_context_compat *compat = IIO_CALL(iio_context_get_data)(ctx);

return compat->xml;
}

unsigned int iio_context_get_devices_count(const struct iio_context *ctx)
Expand Down
15 changes: 2 additions & 13 deletions context.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static ssize_t iio_snprintf_context_xml(char *ptr, ssize_t len,
}

/* Returns a string containing the XML representation of this context */
static char * iio_context_create_xml(const struct iio_context *ctx)
char * iio_context_get_xml(const struct iio_context *ctx)
{
ssize_t len;
char *str;
Expand Down Expand Up @@ -251,11 +251,6 @@ void iio_context_set_pdata(struct iio_context *ctx, struct iio_context_pdata *d)
ctx->pdata = d;
}

const char * iio_context_get_xml(const struct iio_context *ctx)
{
return ctx->xml;
}

const char * iio_context_get_name(const struct iio_context *ctx)
{
return ctx->name;
Expand Down Expand Up @@ -284,7 +279,6 @@ void iio_context_destroy(struct iio_context *ctx)
for (i = 0; i < ctx->nb_devices; i++)
free_device(ctx->devices[i]);
free(ctx->devices);
free(ctx->xml);
free(ctx->description);
free(ctx->git_tag);
free(ctx->pdata);
Expand Down Expand Up @@ -340,12 +334,7 @@ int iio_context_init(struct iio_context *ctx)
for (i = 0; i < ctx->nb_devices; i++)
reorder_channels(ctx->devices[i]);

if (ctx->xml)
return 0;

ctx->xml = iio_context_create_xml(ctx);

return iio_err(ctx->xml);
return 0;
}

unsigned int iio_context_get_version_major(const struct iio_context *ctx)
Expand Down
2 changes: 0 additions & 2 deletions iio-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ struct iio_context {
struct iio_device **devices;
unsigned int nb_devices;

char *xml;

char **values;
struct iio_attr_list attrlist;

Expand Down
16 changes: 8 additions & 8 deletions iiod/iiod.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,22 @@ static void sig_handler_usr1(int sig)

static void *get_xml_zstd_data(const struct iio_context *ctx, size_t *out_len)
{
const char *xml = iio_context_get_xml(ctx);
size_t xml_len = strlen(xml);
char *xml = iio_context_get_xml(ctx);
size_t len, xml_len = strlen(xml);
void *buf;
#if WITH_ZSTD
size_t len;
size_t ret;

len = ZSTD_compressBound(xml_len);
buf = malloc(len);
if (!buf)
if (!buf) {
free(xml);
return NULL;
}

ret = ZSTD_compress(buf, len, xml, xml_len, 3);
free(xml);

if (ZSTD_isError(ret)) {
IIO_WARNING("Unable to compress XML string: %s\n",
ZSTD_getErrorName(xml_len));
Expand All @@ -123,10 +126,7 @@ static void *get_xml_zstd_data(const struct iio_context *ctx, size_t *out_len)

*out_len = ret;
#else
buf = iio_strdup(xml);
if (!buf)
return NULL;

buf = xml;
*out_len = xml_len;
#endif

Expand Down
5 changes: 3 additions & 2 deletions include/iio/iio.h
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,9 @@ __api __pure const char * iio_context_get_version_tag(const struct iio_context *

/** @brief Obtain a XML representation of the given context
* @param ctx A pointer to an iio_context structure
* @return A pointer to a static NULL-terminated string */
__api __check_ret __pure const char * iio_context_get_xml(const struct iio_context *ctx);
* @return On success, an allocated string. Must be deallocated with free().
* @return On failure, a pointer-encoded error is returned */
__api __check_ret char * iio_context_get_xml(const struct iio_context *ctx);


/** @brief Get the name of the given context
Expand Down
5 changes: 3 additions & 2 deletions utils/iio_genxml.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ static const char *options_descriptions[] = {

int main(int argc, char **argv)
{
char **argw, *uri;
const char *xml;
char **argw, *uri, *xml;
struct iio_context *ctx;
struct option *opts;
size_t buf_len;
Expand Down Expand Up @@ -84,12 +83,14 @@ int main(int argc, char **argv)
uri = malloc(buf_len);
if (!uri) {
iio_context_destroy(ctx);
free(xml);
return EXIT_FAILURE;
}

snprintf(uri, buf_len, "xml:%s", xml);

iio_context_destroy(ctx);
free(xml);

ctx = iio_create_context(NULL, uri);
if (!ctx) {
Expand Down
Loading