[ADD/WIP] Basic XEP-0393 support.

Still needs lots of work. Did I fail to mention I _hate_ HTML?
This commit is contained in:
LDA 2024-06-24 18:26:08 +02:00
commit 771c3271ad
10 changed files with 473 additions and 9 deletions

131
src/Streams/Reader.c Normal file
View file

@ -0,0 +1,131 @@
#include <StringStream.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Stream.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Io.h>
#include <string.h>
typedef struct ReaderCookie {
size_t length;
size_t offset;
char *buffer;
} ReaderCookie;
#define Remaining() (cook->length - cook->offset)
static ssize_t
ReadStreamReader(void *coop, void *to, size_t n)
{
ReaderCookie *cook = coop;
size_t remaining;
if (!cook)
{
return 0;
}
remaining = Remaining();
if (n > remaining)
{
memcpy(to, cook->buffer + cook->offset, remaining);
cook->offset = cook->length;
return remaining;
}
memcpy(to, cook->buffer + cook->offset, n);
cook->offset += n;
return n;
}
static ssize_t
WriteStreamReader(void *coop, void *from, size_t n)
{
/* Writing to a stream reader is silly. */
return 0;
}
static off_t
SeekStreamReader(void *coop, off_t mag, int sgn)
{
ReaderCookie *cook = coop;
if (!cook)
{
return 0;
}
switch (sgn)
{
case SEEK_SET:
if (mag > cook->length)
{
cook->offset = cook->length;
return 0;
}
else if (mag < 0)
{
cook->offset = 0;
return 0;
}
cook->offset = mag;
return 0;
case SEEK_CUR:
cook->offset += mag;
if (cook->offset > cook->length)
{
cook->offset = cook->length;
}
else if (cook->offset < 0)
{
cook->offset = 0;
}
return 0;
case SEEK_END:
cook->offset += cook->length + mag;
if (cook->offset > cook->length)
{
cook->offset = cook->length;
}
else if (cook->offset < 0)
{
cook->offset = 0;
}
return 0;
}
return 0;
}
static int
CloseStreamReader(void *coop)
{
/* Nothing to free as of now. */
if (coop)
{
Free(coop);
}
return 0;
}
const static IoFunctions Functions = {
.read = ReadStreamReader,
.seek = SeekStreamReader,
.write = WriteStreamReader,
.close = CloseStreamReader,
};
Stream *
StrStreamReader(char *buffer)
{
Io *raw_io;
ReaderCookie *cookie;
if (!buffer)
{
return NULL;
}
cookie = Malloc(sizeof(*cookie));
cookie->buffer = buffer;
cookie->length = strlen(buffer);
cookie->offset = 0;
raw_io = IoCreate(cookie, Functions);
return StreamIo(raw_io);
}