📄 circ.c
字号:
/*
* "Copyright (c) 2008, 2009 The Regents of the University of California.
* All rights reserved."
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "tcplib.h"
struct circ_buf {
uint8_t *data_start;
uint8_t *data_head;
uint16_t data_len;
uint32_t head_seqno;
};
int circ_buf_init(void *data, int len, uint32_t seqno) {
struct circ_buf *b = (struct circ_buf *)data;
if (len < sizeof(struct circ_buf))
return -1;
b->data_head = b->data_start = (uint8_t *)(b + 1);
b->data_len = len - sizeof(struct circ_buf);
b->head_seqno = seqno;
return 0;
}
uint32_t circ_get_seqno(void *buf) {
struct circ_buf *b = (struct circ_buf *)buf;
return b->head_seqno;
}
static void get_ptr_off_1(struct circ_buf *b, uint32_t sseqno, int len,
uint8_t **writeptr, int *w_len) {
uint8_t *endptr = b->data_start + b->data_len;
int offset;
*writeptr = NULL;
*w_len = len;
/* write up to either the end of the buffer */
offset = sseqno - b->head_seqno;
if (b->data_head + offset < endptr) {
*writeptr = b->data_head + offset;
} else {
offset -= (endptr - b->data_head);
*writeptr = b->data_start + offset;
}
if (*writeptr + *w_len > endptr) {
*w_len = endptr - *writeptr;
}
}
int circ_shorten_head(void *buf, uint32_t seqno) {
struct circ_buf *b = (struct circ_buf *)buf;
int offset = seqno - b->head_seqno;
b->head_seqno = seqno;
b->data_head += offset;
while (b->data_head > b->data_start + b->data_len)
b->data_head -= b->data_len;
return 0;
}
int circ_buf_read(void *buf, uint32_t sseqno,
uint8_t *data, int len) {
struct circ_buf *b = (struct circ_buf *)buf;
uint8_t *readptr;
int r_len, rc = 0;
get_ptr_off_1(b, sseqno, len, &readptr, &r_len);
memcpy(data, readptr, r_len);
data += r_len;
rc += r_len;
if (r_len != len) {
readptr = b->data_start;
r_len = min(len - r_len, b->data_head - b->data_start);
memcpy(data, readptr, r_len);
rc += r_len;
}
return rc;
}
int circ_buf_write(char *buf, uint32_t sseqno,
uint8_t *data, int len) {
struct circ_buf *b = (struct circ_buf *)buf;
uint8_t *writeptr;
int w_len;
/* we can't write any bytes since we're trying to write too far
ahead */
if (sseqno > b->head_seqno + b->data_len)
return -1;
if (len == 0) return 0;
get_ptr_off_1(b, sseqno, len, &writeptr, &w_len);
memcpy(writeptr, data, w_len);
data += w_len;
if (w_len != len) {
writeptr = b->data_start;
w_len = min(len - w_len, b->data_head - b->data_start);
memcpy(writeptr, data, w_len);
}
return 0;
}
#ifdef PC
void circ_buf_dump(void *buf) {
struct circ_buf *b = (struct circ_buf *)buf;
uint8_t *d;
int i;
/* printf("circ buf: %p\n\tmap: %p\n\tmap_len: %i\n\tdata_start: %p\n\t" */
/* "data_head: %p\n\tdata_len: %i\n\thead_seqno: %i\n", */
/* b, b->map, */
/* b->map_len, b->data_start, b->data_head, b->data_len, b->head_seqno); */
for (d = b->data_start; d < b->data_start + b->data_len; d++) {
if (d == b->data_head) putc('|', stdout);
printf("%2.x ", *d);
}
putc('\n', stdout);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -