jancity/src/transport/test/test.c

213 lines
4.0 KiB
C

#include <transport.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct client
{
bool connected, received;
const char *expected;
struct transport_handle h;
struct io
{
FILE *in, *out;
} io;
};
struct server
{
struct transport_handle h;
struct io io;
const char *expected;
bool received;
};
static int io_write(const void *const buf, const size_t n,
const struct io *const io)
{
FILE *const f = io->out;
const size_t w = fwrite(buf, 1, n, f);
return ferror(f) ? -1 : w;
}
static int io_read(void *const buf, const size_t n,
const struct io *const io)
{
FILE *const f = io->in;
const size_t w = fread(buf, 1, n, f);
return ferror(f) ? -1 : w;
}
static int client_write(const void *const buf, const size_t n, void *const arg)
{
struct client *const c = arg;
return io_write(buf, n, &c->io);
}
static int client_read(void *const buf, const size_t n, void *const arg)
{
struct client *const c = arg;
return io_read(buf, n, &c->io);
}
static void client_received(const struct transport_event *const ev,
void *const arg)
{
struct client *const c = arg;
if (ev->common.type == TRANSPORT_EVENT_TYPE_CONNECT)
c->connected = true;
else if (ev->common.type == TRANSPORT_EVENT_TYPE_DATA)
{
const struct transport_event_data *const d = &ev->u.data;
if (!strncmp(d->buf, c->expected, d->n))
c->received = true;
}
}
static int server_write(const void *const buf, const size_t n, void *const arg)
{
struct server *const s = arg;
return io_write(buf, n, &s->io);
}
static int server_read(void *const buf, const size_t n, void *const arg)
{
struct server *const s = arg;
return io_read(buf, n, &s->io);
}
static void server_received(const struct transport_event *const ev,
void *const arg)
{
struct server *const s = arg;
if (ev->common.type == TRANSPORT_EVENT_TYPE_DATA)
{
const struct transport_event_data *const d = &ev->u.data;
if (!strncmp(d->buf, s->expected, d->n))
s->received = true;
}
}
static int loop(struct server *const s, struct client *const c)
{
if (transport_update(&s->h)
|| !freopen("client", "w+b", s->io.in))
return -1;
rewind(s->io.out);
if (transport_update(&c->h)
|| !freopen("server", "w+b", c->io.in))
return -1;
rewind(c->io.out);
return 0;
}
int main(void)
{
int ret = EXIT_FAILURE;
FILE *const cf = fopen("client", "w+b"),
*const sf = fopen("server", "w+b");
if (!cf)
{
perror("fopen(3) client");
goto end;
}
else if (!sf)
{
perror("fopen(3) server");
goto end;
}
struct client c =
{
.h =
{
.cfg =
{
.arg = &c,
.read = client_read,
.write = client_write,
.received = client_received
}
},
.io =
{
.in = sf,
.out = cf
},
.expected = "hi there!"
};
struct server s =
{
.h =
{
.cfg =
{
.arg = &s,
.read = server_read,
.write = server_write,
.received = server_received,
}
},
.io =
{
.in = cf,
.out = sf
},
.expected = "hello"
};
if (transport_connect(&c.h))
goto end;
while (!c.connected)
if (loop(&s, &c))
goto end;
if (transport_send(&c.h, s.expected, strlen(s.expected)))
goto end;
while (!s.received)
if (loop(&s, &c))
goto end;
if (transport_send(&s.h, c.expected, strlen(c.expected)))
goto end;
while (!c.received)
if (loop(&s, &c))
goto end;
ret = EXIT_SUCCESS;
end:
if (cf)
fclose(cf);
if (sf)
fclose(sf);
return ret;
}