gnunet-developers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Let BIO also handle already allocated buffers


From: Alessio Vanni
Subject: Re: Let BIO also handle already allocated buffers
Date: Sun, 19 Apr 2020 14:01:09 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)

Christian Grothoff <address@hidden> writes:

> However, there are two issues. First, your patch introduces a new type
> 'struct GNUNET_BIO_MemoryHandle'. I think to avoid having to duplicate
> all of the individual BIO-read/write functions

Yes, I made a new struct to avoid touching already-existing code.
Mostly, it was because I didn't want to "break" the API.  Anyway, it's
not really an important thing, so if the concept of having BIO work on
memory buffers is ok, a future patch can simply use the existing types.

> more similar to the gnunet{pq,sq,my,json} APIs we have that use similar
> 'spec' arrays to serialize from/to database and or JSON.

About this, I think it's very verbose compared to the current syntax.
Consider the following (without error checking):

struct GNUNET_BIO_ReadSpec rs[] = {
    GNUNET_BIO_read_spec_int32 (&num),
    GNUNET_BIO_read_spec_end (),
};

GNUNET_BIO_read (handle, rs);

if (0 < num) {
    struct GNUNET_BIO_ReadSpec rs2[] = {
        GNUNET_BIO_read_spec_string (&string),
        GNUNET_BIO_read_spec_end (),
    }

    GNUNET_BIO_read (handle, rs2);
} else {
    struct GNUNET_BIO_ReadSpec rs2[] = {
        GNUNET_BIO_read_spec_int32 (&num2),
        GNUNET_BIO_read_spec_int32 (&num3),
        GNUNET_BIO_read_spec_int32 (&num4),
        GNUNET_BIO_read_spec_end (),
    }

    GNUNET_BIO_read (handle, rs2);
}

This can happen e.g. when dealing with messages between client and
services.  Of course, with enough cleverness it can probably be
optimized to make it less verbose, but I think the I/O itself is too
"dynamic" for this kind of "declarative" syntax, unlike database access
which is often based on well-known queries.

In my opinion, a nicer approach could be something based on Java's
Buffer object from the NIO package.  For example (again no error
checking; also the names could use some more work):

struct GNUNET_BIO_Buffer *b1 = GNUNET_BIO_create_from_file ("myfile");
struct GNUNET_BIO_Buffer *b2 = GNUNET_BIO_create_from_buffer (some_data, 
data_length);

GNUNET_BIO_write_string (b1, "mystring");
GNUNET_BIO_write_int32 (b2, 32);

GNUNET_BIO_flip (b1);
GNUNET_BIO_flip (b2);

GNUNET_BIO_read_string (b1, &str);
GNUNET_BIO_read_int32 (b2, &num);

Another solution could simply be to keep BIO to handle I/O on files and
move the various de/serialization functions to a separate library, so we
would get something like:

struct GNUNET_BIO_WriteHandle *wh = GNUNET_BIO_write_open ("myfile");
struct GNUNET_DISK_FileHandle *fh = GNUNET_DISK_file_open ("myfile", 
GNUNET_DISK_OPEN_WRITE, perms);
struct GNUNET_FIO_Serialized *s = GNUNET_FIO_serialize_string (str);

GNUNET_BIO_write (wh, s);
GNUNET_DISK_file_write (fh, s->data, s->size);
GNUNET_memcpy (mybuffer, s->data, s->size);

What do you think?

Thanks,
A.V.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]