src/ucx/buffer.c

Wed, 05 Jun 2024 19:50:44 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 05 Jun 2024 19:50:44 +0200
changeset 537
ad44e72fbf50
parent 490
d218607f5a7e
permissions
-rw-r--r--

add extra nullptr check in the event loop to handle the case when the finish ptr is set to NULL after it was already scheduled

91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
29 #include "cx/buffer.h"
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
30 #include "cx/utils.h"
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
31
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
32 #include <stdio.h>
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33 #include <string.h>
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
34
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
35 int cxBufferInit(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
36 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
37 void *space,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
38 size_t capacity,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
39 CxAllocator const *allocator,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
40 int flags
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
41 ) {
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
42 if (allocator == NULL) allocator = cxDefaultAllocator;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
43 buffer->allocator = allocator;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
44 buffer->flags = flags;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
45 if (!space) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
46 buffer->bytes = cxMalloc(allocator, capacity);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
47 if (buffer->bytes == NULL) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
48 return 1;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
50 buffer->flags |= CX_BUFFER_FREE_CONTENTS;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
51 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
52 buffer->bytes = space;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
54 buffer->capacity = capacity;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
55 buffer->size = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
56 buffer->pos = 0;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
58 buffer->flush_func = NULL;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
59 buffer->flush_target = NULL;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
60 buffer->flush_blkmax = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
61 buffer->flush_blksize = 4096;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
62 buffer->flush_threshold = SIZE_MAX;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
64 return 0;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
67 void cxBufferDestroy(CxBuffer *buffer) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
68 if ((buffer->flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
69 cxFree(buffer->allocator, buffer->bytes);
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72
490
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
73 CxBuffer *cxBufferCreate(
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
74 void *space,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
75 size_t capacity,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
76 CxAllocator const *allocator,
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
77 int flags
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
78 ) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
79 CxBuffer *buf = cxMalloc(allocator, sizeof(CxBuffer));
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
80 if (buf == NULL) return NULL;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
81 if (0 == cxBufferInit(buf, space, capacity, allocator, flags)) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
82 return buf;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
83 } else {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
84 cxFree(allocator, buf);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
85 return NULL;
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
86 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
87 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
88
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
89 void cxBufferFree(CxBuffer *buffer) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
90 if ((buffer->flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS) {
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
91 cxFree(buffer->allocator, buffer->bytes);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
92 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
93 cxFree(buffer->allocator, buffer);
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
94 }
d218607f5a7e update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 415
diff changeset
95
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
96 int cxBufferSeek(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
97 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
98 off_t offset,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
99 int whence
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
100 ) {
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 size_t npos;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 switch (whence) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
103 case SEEK_CUR:
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
104 npos = buffer->pos;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
105 break;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
106 case SEEK_END:
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
107 npos = buffer->size;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
108 break;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
109 case SEEK_SET:
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
110 npos = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
111 break;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
112 default:
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
113 return -1;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
116 size_t opos = npos;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 npos += offset;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
118
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
119 if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) {
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
120 return -1;
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
121 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
122
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
123 if (npos >= buffer->size) {
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 return -1;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 } else {
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 buffer->pos = npos;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 return 0;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
132 void cxBufferClear(CxBuffer *buffer) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
133 memset(buffer->bytes, 0, buffer->size);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
134 buffer->size = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
135 buffer->pos = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
136 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
137
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
138 int cxBufferEof(CxBuffer const *buffer) {
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 return buffer->pos >= buffer->size;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
142 int cxBufferMinimumCapacity(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
143 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
144 size_t newcap
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
145 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
146 if (newcap <= buffer->capacity) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
147 return 0;
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
148 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
149
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
150 if (cxReallocate(buffer->allocator,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
151 (void **) &buffer->bytes, newcap) == 0) {
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 buffer->capacity = newcap;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
153 return 0;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 } else {
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 return -1;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
159 /**
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
160 * Helps flushing data to the flush target of a buffer.
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
161 *
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
162 * @param buffer the buffer containing the config
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
163 * @param space the data to flush
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
164 * @param size the element size
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
165 * @param nitems the number of items
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
166 * @return the number of items flushed
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
167 */
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
168 static size_t cx_buffer_write_flush_helper(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
169 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
170 unsigned char const *space,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
171 size_t size,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
172 size_t nitems
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
173 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
174 size_t pos = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
175 size_t remaining = nitems;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
176 size_t max_items = buffer->flush_blksize / size;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
177 while (remaining > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
178 size_t items = remaining > max_items ? max_items : remaining;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
179 size_t flushed = buffer->flush_func(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
180 space + pos,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
181 size, items,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
182 buffer->flush_target);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
183 if (flushed > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
184 pos += (flushed * size);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
185 remaining -= flushed;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
186 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
187 // if no bytes can be flushed out anymore, we give up
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
188 break;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
189 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
190 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
191 return nitems - remaining;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
192 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
193
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
194 size_t cxBufferWrite(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
195 void const *ptr,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
196 size_t size,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
197 size_t nitems,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
198 CxBuffer *buffer
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
199 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
200 // optimize for easy case
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
201 if (size == 1 && (buffer->capacity - buffer->pos) >= nitems) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
202 memcpy(buffer->bytes + buffer->pos, ptr, nitems);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
203 buffer->pos += nitems;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
204 if (buffer->pos > buffer->size) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
205 buffer->size = buffer->pos;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
206 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
207 return nitems;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
208 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
209
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
210 size_t len;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
211 size_t nitems_out = nitems;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
212 if (cx_szmul(size, nitems, &len)) {
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
213 return 0;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
214 }
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
215 size_t required = buffer->pos + len;
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
216 if (buffer->pos > required) {
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
217 return 0;
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
218 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
219
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
220 bool perform_flush = false;
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
221 if (required > buffer->capacity) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
222 if ((buffer->flags & CX_BUFFER_AUTO_EXTEND) == CX_BUFFER_AUTO_EXTEND && required) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
223 if (buffer->flush_blkmax > 0 && required > buffer->flush_threshold) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
224 perform_flush = true;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
225 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
226 if (cxBufferMinimumCapacity(buffer, required)) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
227 return 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
228 }
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 } else {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
231 if (buffer->flush_blkmax > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
232 perform_flush = true;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
233 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
234 // truncate data to be written, if we can neither extend nor flush
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
235 len = buffer->capacity - buffer->pos;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
236 if (size > 1) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
237 len -= len % size;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
238 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
239 nitems_out = len / size;
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
240 }
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
243
99
b9a6af0ae41a ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 91
diff changeset
244 if (len == 0) {
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 return len;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
247
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
248 if (perform_flush) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
249 size_t flush_max;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
250 if (cx_szmul(buffer->flush_blkmax, buffer->flush_blksize, &flush_max)) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
251 return 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
252 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
253 size_t flush_pos = buffer->flush_func == NULL || buffer->flush_target == NULL
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
254 ? buffer->pos
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
255 : cx_buffer_write_flush_helper(buffer, buffer->bytes, 1, buffer->pos);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
256 if (flush_pos == buffer->pos) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
257 // entire buffer has been flushed, we can reset
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
258 buffer->size = buffer->pos = 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
259
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
260 size_t items_flush; // how many items can also be directly flushed
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
261 size_t items_keep; // how many items have to be written to the buffer
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
262
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
263 items_flush = flush_max >= required ? nitems : (flush_max - flush_pos) / size;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
264 if (items_flush > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
265 items_flush = cx_buffer_write_flush_helper(buffer, ptr, size, items_flush / size);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
266 // in case we could not flush everything, keep the rest
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
267 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
268 items_keep = nitems - items_flush;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
269 if (items_keep > 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
270 // try again with the remaining stuff
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
271 unsigned char const *new_ptr = ptr;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
272 new_ptr += items_flush * size;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
273 // report the directly flushed items as written plus the remaining stuff
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
274 return items_flush + cxBufferWrite(new_ptr, size, items_keep, buffer);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
275 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
276 // all items have been flushed - report them as written
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
277 return nitems;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
278 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
279 } else if (flush_pos == 0) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
280 // nothing could be flushed at all, we immediately give up without writing any data
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
281 return 0;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
282 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
283 // we were partially successful, we shift left and try again
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
284 cxBufferShiftLeft(buffer, flush_pos);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
285 return cxBufferWrite(ptr, size, nitems, buffer);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
286 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
287 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
288 memcpy(buffer->bytes + buffer->pos, ptr, len);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
289 buffer->pos += len;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
290 if (buffer->pos > buffer->size) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
291 buffer->size = buffer->pos;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
292 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
293 return nitems_out;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
295
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
298 int cxBufferPut(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
299 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
300 int c
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
301 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
302 c &= 0xFF;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
303 unsigned char const ch = c;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
304 if (cxBufferWrite(&ch, 1, 1, buffer) == 1) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
305 return c;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
306 } else {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
307 return EOF;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
308 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
309 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
310
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
311 size_t cxBufferPutString(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
312 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
313 const char *str
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
314 ) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
315 return cxBufferWrite(str, 1, strlen(str), buffer);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
316 }
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
317
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
318 size_t cxBufferRead(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
319 void *ptr,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
320 size_t size,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
321 size_t nitems,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
322 CxBuffer *buffer
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
323 ) {
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
324 size_t len;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
325 if (cx_szmul(size, nitems, &len)) {
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
326 return 0;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
327 }
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
328 if (buffer->pos + len > buffer->size) {
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329 len = buffer->size - buffer->pos;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
330 if (size > 1) len -= len % size;
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
332
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 if (len <= 0) {
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
334 return len;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
336
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
337 memcpy(ptr, buffer->bytes + buffer->pos, len);
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
338 buffer->pos += len;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
339
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
340 return len / size;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
341 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
342
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
343 int cxBufferGet(CxBuffer *buffer) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
344 if (cxBufferEof(buffer)) {
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
345 return EOF;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
346 } else {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
347 int c = buffer->bytes[buffer->pos];
91
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
348 buffer->pos++;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
349 return c;
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
350 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
351 }
fac51f87def0 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
352
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
353 int cxBufferShiftLeft(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
354 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
355 size_t shift
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
356 ) {
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
357 if (shift >= buffer->size) {
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
358 buffer->pos = buffer->size = 0;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
359 } else {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
360 memmove(buffer->bytes, buffer->bytes + shift, buffer->size - shift);
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
361 buffer->size -= shift;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
362
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
363 if (buffer->pos >= shift) {
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
364 buffer->pos -= shift;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
365 } else {
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
366 buffer->pos = 0;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
367 }
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
368 }
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
369 return 0;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
370 }
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
371
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
372 int cxBufferShiftRight(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
373 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
374 size_t shift
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
375 ) {
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
376 size_t req_capacity = buffer->size + shift;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
377 size_t movebytes;
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
378
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
379 // auto extend buffer, if required and enabled
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
380 if (buffer->capacity < req_capacity) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
381 if ((buffer->flags & CX_BUFFER_AUTO_EXTEND) == CX_BUFFER_AUTO_EXTEND) {
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
382 if (cxBufferMinimumCapacity(buffer, req_capacity)) {
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
383 return 1;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
384 }
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
385 movebytes = buffer->size;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
386 } else {
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
387 movebytes = buffer->capacity - shift;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
388 }
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
389 } else {
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
390 movebytes = buffer->size;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
391 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
392
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
393 memmove(buffer->bytes + shift, buffer->bytes, movebytes);
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
394 buffer->size = shift + movebytes;
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
395
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
396 buffer->pos += shift;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
397 if (buffer->pos > buffer->size) {
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
398 buffer->pos = buffer->size;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
399 }
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
400
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
401 return 0;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
402 }
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
403
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
404 int cxBufferShift(
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
405 CxBuffer *buffer,
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
406 off_t shift
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
407 ) {
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
408 if (shift < 0) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
409 return cxBufferShiftLeft(buffer, (size_t) (-shift));
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
410 } else if (shift > 0) {
415
d938228c382e switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 254
diff changeset
411 return cxBufferShiftRight(buffer, (size_t) shift);
254
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
412 } else {
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
413 return 0;
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
414 }
4784c14aa639 ucx update
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 135
diff changeset
415 }

mercurial