/* kc3
* Copyright from 2022 to 2025 kmx.io <contact@kmx.io>
*
* Permission is hereby granted to use this software granted the above
* copyright notice and this permission paragraph are included in all
* copies and substantial portions of this software.
*
* THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
* PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
#include "../libkc3/alloc.h"
#include "../libkc3/io.h"
#include "assert.h"
#include "libkc3/buf.h"
#include "libkc3/buf_save.h"
#include "types.h"
#include <string.h>
#include <tls.h>
#include <unistd.h>
#include "tls_buf.h"
void tls_buf_close (s_buf *buf)
{
s_tls_buf *tls_buf;
assert(buf);
assert(buf->user_ptr);
tls_buf = buf->user_ptr;
buf_flush(buf);
tls_close(tls_buf->ctx);
buf->flush = NULL;
buf->refill = NULL;
free(buf->user_ptr);
buf->user_ptr = NULL;
}
sw tls_buf_open_r_refill (s_buf *buf)
{
s32 avail;
p_tls ctx;
sw r;
uw size;
assert(buf);
assert(buf->user_ptr);
if (buf->rpos > buf->wpos) {
err_puts("tls_buf_open_r_refill: buf->rpos > buf->wpos");
assert(! "tls_buf_open_r_refill: buf->rpos > buf->wpos");
return -1;
}
if (buf->wpos > buf->size) {
err_puts("tls_buf_open_r_refill: buf->wpos > buf->size");
assert(! "tls_buf_open_r_refill: buf->wpos > buf->size");
return -1;
}
size = buf->size - buf->wpos;
ctx = ((s_tls_buf *) (buf->user_ptr))->ctx;
if ((r = tls_read(ctx, buf->ptr.pchar + buf->wpos, size)) < 0)
return r;
if (buf->wpos + r > buf->size) {
err_puts("tls_buf_open_r_refill: buffer overflow");
assert(! "tls_buf_open_r_refill: buffer overflow");
return -1;
}
buf->wpos += r;
return r;
}
sw tls_buf_open_w_flush (s_buf *buf)
{
sw bytes;
s_tls_buf *tls_buf;
sw e;
uw min_wpos;
s_buf_save *save;
sw size;
sw w;
assert(buf);
assert(buf->user_ptr);
if (buf->rpos)
return -1;
if (buf->rpos > buf->wpos)
return -1;
if (buf->wpos > buf->size)
return -1;
min_wpos = buf_save_min_wpos(buf);
size = min_wpos;
if (size == 0)
return buf->size - buf->wpos;
tls_buf = buf->user_ptr;
bytes = 0;
while (bytes < size) {
// XXX TODO: #ifdef WIN32 || WIN64
if ((w = tls_write(tls_buf->ctx, buf->ptr.pchar + bytes,
size - bytes)) < 0) {
err_write_1("buf_fd_open_w_flush: tls_write: ");
err_puts(tls_error(tls_buf->ctx));
return -1;
}
bytes += w;
}
buf->wpos -= size;
save = buf->save;
while (save) {
save->wpos -= size;
save = save->next;
}
return size;
}
s_buf * tls_buf_open_r (s_buf *buf, p_tls ctx)
{
s_tls_buf * tls_buf = NULL;
assert(buf);
assert(ctx);
if (buf == NULL || ctx == NULL) {
err_puts("buf_tls_open_r: invalid input");
assert(! "buf_tls_open_r: invalid input");
return NULL;
}
if (! (tls_buf = alloc(sizeof(s_tls_buf))))
return NULL;
tls_buf->ctx = ctx;
buf->refill = tls_buf_open_r_refill;
buf->user_ptr = tls_buf;
return buf;
}
s_buf * tls_buf_open_w (s_buf *buf, struct tls *ctx)
{
s_tls_buf * tls_buf = NULL;
assert(buf);
assert(ctx);
if (buf == NULL || ctx == NULL) {
err_puts("buf_tls_open_w: invalid input");
assert(! "buf_tls_open_w: invalid input");
return NULL;
}
if (! (tls_buf = alloc(sizeof(s_tls_buf))))
return NULL;
tls_buf->ctx = ctx;
buf->flush = tls_buf_open_w_flush;
buf->user_ptr = tls_buf;
return buf;
}