[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);
}

64
src/Streams/Writer.c Normal file
View file

@ -0,0 +1,64 @@
#include <StringStream.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Stream.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Io.h>
#include <string.h>
static ssize_t
ReadStreamWriter(void *coop, void *to, size_t n)
{
/* Reading from a stream writer is silly. */
return 0;
}
static ssize_t
WriteStreamWriter(void *coop, void *from, size_t n)
{
char **cook = coop;
char *tmp = NULL;
char *str = Malloc(n + 1);
memcpy(str, from, n);
str[n] = '\0';
tmp = *cook;
*cook = StrConcat(2, *cook, str);
Free(tmp);
Free(str);
return 0;
}
static off_t
SeekStreamWriter(void *coop, off_t mag, int sgn)
{
/* TODO: Seeking would be useful, though not supported yet. */
return 0;
}
static int
CloseStreamWriter(void *coop)
{
/* Nothing to free as of now. */
return 0;
}
const static IoFunctions Functions = {
.read = ReadStreamWriter,
.seek = SeekStreamWriter,
.write = WriteStreamWriter,
.close = CloseStreamWriter,
};
Stream *
StrStreamWriter(char **buffer)
{
Io *raw_io;
if (!buffer)
{
return NULL;
}
raw_io = IoCreate(buffer, Functions);
return StreamIo(raw_io);
}