1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 25392f7a3SLiteSpeed Tech/* 35392f7a3SLiteSpeed Tech * lsquic_frab_list.c -- List of buffer for simple reading and writing 45392f7a3SLiteSpeed Tech */ 55392f7a3SLiteSpeed Tech 65392f7a3SLiteSpeed Tech#include <stddef.h> 75392f7a3SLiteSpeed Tech#include <stdlib.h> 85392f7a3SLiteSpeed Tech#include <string.h> 95392f7a3SLiteSpeed Tech#include <sys/queue.h> 105392f7a3SLiteSpeed Tech 115392f7a3SLiteSpeed Tech#include "lsquic_frab_list.h" 125392f7a3SLiteSpeed Tech 135392f7a3SLiteSpeed Tech 145392f7a3SLiteSpeed Techstatic void * 155392f7a3SLiteSpeed Techfral_alloc (void *ctx, size_t size) 165392f7a3SLiteSpeed Tech{ 175392f7a3SLiteSpeed Tech return malloc(size); 185392f7a3SLiteSpeed Tech} 195392f7a3SLiteSpeed Tech 205392f7a3SLiteSpeed Tech 215392f7a3SLiteSpeed Techstatic void 225392f7a3SLiteSpeed Techfral_free (void *ctx, void *obj) 235392f7a3SLiteSpeed Tech{ 245392f7a3SLiteSpeed Tech free(obj); 255392f7a3SLiteSpeed Tech} 265392f7a3SLiteSpeed Tech 275392f7a3SLiteSpeed Tech 285392f7a3SLiteSpeed Techvoid 295392f7a3SLiteSpeed Techlsquic_frab_list_init (struct frab_list *fral, unsigned short buf_size, 305392f7a3SLiteSpeed Tech void * (*alloc)(void *alloc_ctx, size_t size), 315392f7a3SLiteSpeed Tech void (*free)(void *alloc_ctx, void *obj), void *alloc_ctx) 325392f7a3SLiteSpeed Tech{ 335392f7a3SLiteSpeed Tech TAILQ_INIT(&fral->fl_frabs); 345392f7a3SLiteSpeed Tech fral->fl_alloc_ctx = alloc_ctx; 355392f7a3SLiteSpeed Tech fral->fl_alloc = alloc ? alloc : fral_alloc; 365392f7a3SLiteSpeed Tech fral->fl_free = free ? free : fral_free; 375392f7a3SLiteSpeed Tech fral->fl_buf_size = buf_size; 385392f7a3SLiteSpeed Tech fral->fl_size = 0; 395392f7a3SLiteSpeed Tech} 405392f7a3SLiteSpeed Tech 415392f7a3SLiteSpeed Tech 425392f7a3SLiteSpeed Techvoid 435392f7a3SLiteSpeed Techlsquic_frab_list_cleanup (struct frab_list *fral) 445392f7a3SLiteSpeed Tech{ 455392f7a3SLiteSpeed Tech struct frame_buf *frab, *next; 465392f7a3SLiteSpeed Tech 475392f7a3SLiteSpeed Tech for (frab = TAILQ_FIRST(&fral->fl_frabs); frab; frab = next) 485392f7a3SLiteSpeed Tech { 495392f7a3SLiteSpeed Tech next = TAILQ_NEXT(frab, frab_next); 505392f7a3SLiteSpeed Tech fral->fl_free(fral->fl_alloc_ctx, frab); 515392f7a3SLiteSpeed Tech } 525392f7a3SLiteSpeed Tech} 535392f7a3SLiteSpeed Tech 545392f7a3SLiteSpeed Tech 555392f7a3SLiteSpeed Techstatic struct frame_buf * 565392f7a3SLiteSpeed Techfral_get_frab (struct frab_list *fral) 575392f7a3SLiteSpeed Tech{ 585392f7a3SLiteSpeed Tech struct frame_buf *frab; 595392f7a3SLiteSpeed Tech frab = fral->fl_alloc(fral->fl_alloc_ctx, fral->fl_buf_size); 605392f7a3SLiteSpeed Tech if (frab) 615392f7a3SLiteSpeed Tech { 625392f7a3SLiteSpeed Tech memset(frab, 0, sizeof(*frab)); 635392f7a3SLiteSpeed Tech frab->frab_buf_size = fral->fl_buf_size; 645392f7a3SLiteSpeed Tech } 655392f7a3SLiteSpeed Tech return frab; 665392f7a3SLiteSpeed Tech} 675392f7a3SLiteSpeed Tech 685392f7a3SLiteSpeed Tech 695392f7a3SLiteSpeed Techint 705392f7a3SLiteSpeed Techlsquic_frab_list_write (struct frab_list *fral, const void *buf, size_t bufsz) 715392f7a3SLiteSpeed Tech{ 725392f7a3SLiteSpeed Tech const unsigned char *p = buf; 735392f7a3SLiteSpeed Tech const unsigned char *const end = p + bufsz; 745392f7a3SLiteSpeed Tech struct frame_buf *frab; 755392f7a3SLiteSpeed Tech unsigned ntowrite; 765392f7a3SLiteSpeed Tech 775392f7a3SLiteSpeed Tech while (p < end) 785392f7a3SLiteSpeed Tech { 795392f7a3SLiteSpeed Tech frab = TAILQ_LAST(&fral->fl_frabs, frame_buf_head); 805392f7a3SLiteSpeed Tech if (!(frab && (ntowrite = frab_left_to_write(frab)) > 0)) 815392f7a3SLiteSpeed Tech { 825392f7a3SLiteSpeed Tech frab = fral_get_frab(fral); 835392f7a3SLiteSpeed Tech if (!frab) 845392f7a3SLiteSpeed Tech return -1; 855392f7a3SLiteSpeed Tech TAILQ_INSERT_TAIL(&fral->fl_frabs, frab, frab_next); 865392f7a3SLiteSpeed Tech ntowrite = frab_left_to_write(frab); 875392f7a3SLiteSpeed Tech } 885392f7a3SLiteSpeed Tech if ((ptrdiff_t) ntowrite > end - p) 895392f7a3SLiteSpeed Tech ntowrite = end - p; 905392f7a3SLiteSpeed Tech memcpy(frab_write_to(frab), p, ntowrite); 915392f7a3SLiteSpeed Tech p += ntowrite; 925392f7a3SLiteSpeed Tech frab->frab_size += ntowrite; 935392f7a3SLiteSpeed Tech } 945392f7a3SLiteSpeed Tech 955392f7a3SLiteSpeed Tech fral->fl_size += bufsz; 965392f7a3SLiteSpeed Tech return 0; 975392f7a3SLiteSpeed Tech} 985392f7a3SLiteSpeed Tech 995392f7a3SLiteSpeed Tech 1005392f7a3SLiteSpeed Techsize_t 1015392f7a3SLiteSpeed Techlsquic_frab_list_size (void *ctx) 1025392f7a3SLiteSpeed Tech{ 1035392f7a3SLiteSpeed Tech struct frab_list *fral = ctx; 1045392f7a3SLiteSpeed Tech return fral->fl_size; 1055392f7a3SLiteSpeed Tech} 1065392f7a3SLiteSpeed Tech 1075392f7a3SLiteSpeed Tech 1085392f7a3SLiteSpeed Techsize_t 1095392f7a3SLiteSpeed Techlsquic_frab_list_read (void *ctx, void *buf, size_t bufsz) 1105392f7a3SLiteSpeed Tech{ 1115392f7a3SLiteSpeed Tech struct frab_list *const fral = ctx; 1125392f7a3SLiteSpeed Tech unsigned char *p = buf; 1135392f7a3SLiteSpeed Tech unsigned char *const end = p + bufsz; 1145392f7a3SLiteSpeed Tech struct frame_buf *frab; 1155392f7a3SLiteSpeed Tech size_t ntocopy; 1165392f7a3SLiteSpeed Tech 1175392f7a3SLiteSpeed Tech while (p < end && (frab = TAILQ_FIRST(&fral->fl_frabs))) 1185392f7a3SLiteSpeed Tech { 1195392f7a3SLiteSpeed Tech ntocopy = end - p; 1205392f7a3SLiteSpeed Tech if (ntocopy > (size_t) frab_left_to_read(frab)) 1215392f7a3SLiteSpeed Tech ntocopy = frab_left_to_read(frab); 1225392f7a3SLiteSpeed Tech memcpy(p, frab->frab_buf + frab->frab_off, ntocopy); 1235392f7a3SLiteSpeed Tech fral->fl_size -= ntocopy; 1245392f7a3SLiteSpeed Tech frab->frab_off += ntocopy; 1255392f7a3SLiteSpeed Tech p += ntocopy; 1265392f7a3SLiteSpeed Tech if (frab->frab_off == frab->frab_size) 1275392f7a3SLiteSpeed Tech { 1285392f7a3SLiteSpeed Tech TAILQ_REMOVE(&fral->fl_frabs, frab, frab_next); 1295392f7a3SLiteSpeed Tech fral->fl_free(fral->fl_alloc_ctx, frab); 1305392f7a3SLiteSpeed Tech } 1315392f7a3SLiteSpeed Tech } 1325392f7a3SLiteSpeed Tech 1335392f7a3SLiteSpeed Tech return p - (unsigned char *) buf; 1345392f7a3SLiteSpeed Tech} 1355392f7a3SLiteSpeed Tech 1365392f7a3SLiteSpeed Tech 1375392f7a3SLiteSpeed Techsize_t 1385392f7a3SLiteSpeed Techlsquic_frab_list_mem_used (const struct frab_list *fral) 1395392f7a3SLiteSpeed Tech{ 1405392f7a3SLiteSpeed Tech struct frame_buf *frab; 1415392f7a3SLiteSpeed Tech size_t size; 1425392f7a3SLiteSpeed Tech 1435392f7a3SLiteSpeed Tech size = sizeof(*fral); 1445392f7a3SLiteSpeed Tech TAILQ_FOREACH(frab, &fral->fl_frabs, frab_next) 1455392f7a3SLiteSpeed Tech size += fral->fl_buf_size; 1465392f7a3SLiteSpeed Tech 1475392f7a3SLiteSpeed Tech return size; 1485392f7a3SLiteSpeed Tech} 149