ucx/buffer.c

Fri, 12 Dec 2025 12:28:32 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 12 Dec 2025 12:28:32 +0100
changeset 992
f421aef8f865
parent 943
9b5948aa5b90
permissions
-rw-r--r--

remove old UCX2 properties

174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 *
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 *
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 *
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0358f1d9c506 upgrade ucx
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
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 */
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 #include "cx/buffer.h"
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 #include <stdio.h>
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 #include <string.h>
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
33 #include <errno.h>
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
34
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
35 static int buffer_copy_on_write(CxBuffer* buffer) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
36 if (0 == (buffer->flags & CX_BUFFER_COPY_ON_WRITE)) return 0;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
37 void *newspace = cxMalloc(buffer->allocator, buffer->capacity);
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
38 if (NULL == newspace) return -1; // LCOV_EXCL_LINE
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
39 memcpy(newspace, buffer->space, buffer->size);
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
40 buffer->space = newspace;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
41 buffer->flags &= ~CX_BUFFER_COPY_ON_WRITE;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
42 buffer->flags |= CX_BUFFER_FREE_CONTENTS;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
43 return 0;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
44 }
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 int cxBufferInit(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 CxBuffer *buffer,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48 void *space,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 size_t capacity,
324
ce13a778654a update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 253
diff changeset
50 const CxAllocator *allocator,
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 int flags
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 ) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
53 if (allocator == NULL) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
54 allocator = cxDefaultAllocator;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
55 }
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
56 if (flags & CX_BUFFER_COPY_ON_EXTEND) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
57 flags |= CX_BUFFER_AUTO_EXTEND;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
58 }
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 buffer->allocator = allocator;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 buffer->flags = flags;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 if (!space) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62 buffer->bytes = cxMalloc(allocator, capacity);
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
63 if (buffer->bytes == NULL) return -1; // LCOV_EXCL_LINE
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 buffer->flags |= CX_BUFFER_FREE_CONTENTS;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 buffer->bytes = space;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 buffer->capacity = capacity;
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
69 buffer->max_capacity = SIZE_MAX;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 buffer->size = 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 buffer->pos = 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
73 return 0;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
74 }
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
75
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 void cxBufferDestroy(CxBuffer *buffer) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
77 if (buffer->flags & CX_BUFFER_FREE_CONTENTS) {
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 cxFree(buffer->allocator, buffer->bytes);
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 }
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
80 memset(buffer, 0, sizeof(CxBuffer));
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 CxBuffer *cxBufferCreate(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 void *space,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 size_t capacity,
324
ce13a778654a update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 253
diff changeset
86 const CxAllocator *allocator,
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 int flags
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 ) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
89 if (allocator == NULL) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
90 allocator = cxDefaultAllocator;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
91 }
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 CxBuffer *buf = cxMalloc(allocator, sizeof(CxBuffer));
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
93 if (buf == NULL) return NULL; // LCOV_EXCL_LINE
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94 if (0 == cxBufferInit(buf, space, capacity, allocator, flags)) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 return buf;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 } else {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
97 // LCOV_EXCL_START
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98 cxFree(allocator, buf);
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 return NULL;
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
100 // LCOV_EXCL_STOP
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 void cxBufferFree(CxBuffer *buffer) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
105 if (buffer == NULL) return;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
106 const CxAllocator *allocator = buffer->allocator;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
107 cxBufferDestroy(buffer);
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
108 cxFree(allocator, buffer);
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111 int cxBufferSeek(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 CxBuffer *buffer,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 off_t offset,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 int whence
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 ) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 size_t npos;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 switch (whence) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118 case SEEK_CUR:
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 npos = buffer->pos;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 break;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 case SEEK_END:
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 npos = buffer->size;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 break;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 case SEEK_SET:
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 npos = 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 break;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 default:
629
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
128 errno = EINVAL;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 return -1;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 size_t opos = npos;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 npos += offset;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) {
629
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
136 // to be compliant with fseek() specification
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
137 // we return EINVAL on underflow
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
138 errno = EINVAL;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 return -1;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
142 if (npos > buffer->size) {
629
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
143 // not compliant with fseek() specification
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
144 // but this is the better behavior for CxBuffer
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
145 errno = EINVAL;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146 return -1;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 buffer->pos = npos;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 return 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
154 size_t cxBufferPop(CxBuffer *buffer, size_t size, size_t nitems) {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
155 size_t len;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
156 if (cx_szmul(size, nitems, &len)) {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
157 // LCOV_EXCL_START
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
158 errno = EOVERFLOW;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
159 return 0;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
160 // LCOV_EXCL_STOP
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
161 }
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
162 if (len == 0) return 0;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
163 if (len > buffer->size) {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
164 if (size == 1) {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
165 // simple case: everything can be discarded
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
166 len = buffer->size;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
167 } else {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
168 // complicated case: misaligned bytes must stay
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
169 size_t misalignment = buffer->size % size;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
170 len = buffer->size - misalignment;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
171 }
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
172 }
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
173 buffer->size -= len;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
174
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
175 // adjust position, if required
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
176 if (buffer->pos > buffer->size) {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
177 buffer->pos = buffer->size;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
178 }
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
179
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
180 return len / size;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
181 }
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
182
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 void cxBufferClear(CxBuffer *buffer) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
184 if (0 == (buffer->flags & CX_BUFFER_COPY_ON_WRITE)) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
185 memset(buffer->bytes, 0, buffer->size);
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
186 }
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 buffer->size = 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 buffer->pos = 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190
253
087cc9216f28 initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 174
diff changeset
191 void cxBufferReset(CxBuffer *buffer) {
087cc9216f28 initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 174
diff changeset
192 buffer->size = 0;
087cc9216f28 initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 174
diff changeset
193 buffer->pos = 0;
087cc9216f28 initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 174
diff changeset
194 }
087cc9216f28 initial newapi GTK port
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 174
diff changeset
195
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
196 bool cxBufferEof(const CxBuffer *buffer) {
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 return buffer->pos >= buffer->size;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
200 int cxBufferReserve(CxBuffer *buffer, size_t newcap) {
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
201 if (newcap == buffer->capacity) {
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 return 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203 }
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
204 if (newcap > buffer->max_capacity) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
205 return -1;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
206 }
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
207 const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
208 if (buffer->flags & force_copy_flags) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
209 void *newspace = cxMalloc(buffer->allocator, newcap);
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
210 if (NULL == newspace) return -1;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
211 memcpy(newspace, buffer->space, buffer->size);
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
212 buffer->space = newspace;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
213 buffer->capacity = newcap;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
214 buffer->flags &= ~force_copy_flags;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
215 buffer->flags |= CX_BUFFER_FREE_CONTENTS;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
216 return 0;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
217 } else if (cxReallocate(buffer->allocator,
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 (void **) &buffer->bytes, newcap) == 0) {
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
219 buffer->flags |= CX_BUFFER_FREE_CONTENTS;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 buffer->capacity = newcap;
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
221 if (buffer->size > newcap) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
222 buffer->size = newcap;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
223 }
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 return 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 } else {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
226 return -1; // LCOV_EXCL_LINE
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
230 int cxBufferMaximumCapacity(CxBuffer *buffer, size_t capacity) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
231 if (capacity < buffer->capacity) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
232 return -1;
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
233 }
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
234 buffer->max_capacity = capacity;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
235 return 0;
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
236 }
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
237
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
238 int cxBufferMinimumCapacity(CxBuffer *buffer, size_t newcap) {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
239 if (newcap <= buffer->capacity) {
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
240 return 0;
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
241 }
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
242 if (newcap > buffer->max_capacity) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
243 return -1;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
244 }
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
245 if (newcap < buffer->max_capacity) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
246 unsigned long pagesize = cx_system_page_size();
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
247 // if page size is larger than 64 KB - for some reason - truncate to 64 KB
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
248 if (pagesize > 65536) pagesize = 65536;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
249 if (newcap < pagesize) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
250 // when smaller as one page, map to the next power of two
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
251 newcap--;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
252 newcap |= newcap >> 1;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
253 newcap |= newcap >> 2;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
254 newcap |= newcap >> 4;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
255 // last operation only needed for pages larger 4096 bytes
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
256 // but if/else would be more expensive than just doing this
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
257 newcap |= newcap >> 8;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
258 newcap++;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
259 } else {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
260 // otherwise, map to a multiple of the page size
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
261 newcap -= newcap % pagesize;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
262 newcap += pagesize;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
263 // note: if newcap is already page aligned,
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
264 // this gives a full additional page (which is good)
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
265 }
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
266 if (newcap > buffer->max_capacity) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
267 newcap = buffer->max_capacity;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
268 }
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
269 }
943
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
270 return cxBufferReserve(buffer, newcap);
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
271 }
9b5948aa5b90 update ucx to version 3.2
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 629
diff changeset
272
629
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
273 void cxBufferShrink(
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
274 CxBuffer *buffer,
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
275 size_t reserve
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
276 ) {
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
277 // Ensure buffer is in a reallocatable state
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
278 const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND;
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
279 if (buffer->flags & force_copy_flags) {
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
280 // do nothing when we are not allowed to reallocate
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
281 return;
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
282 }
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
283
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
284 // calculate new capacity
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
285 size_t newCapacity = buffer->size + reserve;
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
286
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
287 // If new capacity is smaller than current capacity, resize the buffer
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
288 if (newCapacity < buffer->capacity) {
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
289 if (0 == cxReallocate(buffer->allocator, &buffer->bytes, newCapacity)) {
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
290 buffer->capacity = newCapacity;
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
291 }
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
292 }
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
293 }
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
294
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 size_t cxBufferWrite(
324
ce13a778654a update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 253
diff changeset
296 const void *ptr,
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 size_t size,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 size_t nitems,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 CxBuffer *buffer
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 ) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 // optimize for easy case
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 if (size == 1 && (buffer->capacity - buffer->pos) >= nitems) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
303 if (buffer_copy_on_write(buffer)) return 0;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304 memcpy(buffer->bytes + buffer->pos, ptr, nitems);
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 buffer->pos += nitems;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 if (buffer->pos > buffer->size) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307 buffer->size = buffer->pos;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 return nitems;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
312 size_t len;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 if (cx_szmul(size, nitems, &len)) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
314 errno = EOVERFLOW;
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
315 return 0;
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
316 }
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
317 if (buffer->pos > SIZE_MAX - len) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
318 errno = EOVERFLOW;
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
319 return 0;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 }
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
321 const size_t required = buffer->pos + len;
471
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
322
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
323 // check if we need to auto-extend
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324 if (required > buffer->capacity) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
325 if (buffer->flags & CX_BUFFER_AUTO_EXTEND) {
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
326 size_t newcap = required < buffer->max_capacity
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
327 ? required : buffer->max_capacity;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
328 if (cxBufferMinimumCapacity(buffer, newcap)) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
329 return 0; // LCOV_EXCL_LINE
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
334 // check again and truncate data if capacity is still not enough
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
335 if (required > buffer->capacity) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
336 len = buffer->capacity - buffer->pos;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
337 if (size > 1) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
338 len -= len % size;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
339 }
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
340 nitems = len / size;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
341 }
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
342
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
343 // check here and not above because of possible truncation
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
344 if (len == 0) {
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
345 return 0;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
346 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
347
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
348 // check if we need to copy
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
349 if (buffer_copy_on_write(buffer)) return 0;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
350
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
351 // perform the operation
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
352 memcpy(buffer->bytes + buffer->pos, ptr, len);
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
353 buffer->pos += len;
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
354 if (buffer->pos > buffer->size) {
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
355 buffer->size = buffer->pos;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
356 }
992
f421aef8f865 remove old UCX2 properties
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 943
diff changeset
357 return nitems;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
358 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
359
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
360 size_t cxBufferAppend(
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
361 const void *ptr,
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
362 size_t size,
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
363 size_t nitems,
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
364 CxBuffer *buffer
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
365 ) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
366 size_t pos = buffer->pos;
471
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
367 size_t append_pos = buffer->size;
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
368 buffer->pos = append_pos;
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
369 size_t written = cxBufferWrite(ptr, size, nitems, buffer);
471
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
370 // the buffer might have been flushed
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
371 // we must compute a possible delta for the position
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
372 // expected: pos = append_pos + written
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
373 // -> if this is not the case, there is a delta
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
374 size_t delta = append_pos + written*size - buffer->pos;
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
375 if (delta > pos) {
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
376 buffer->pos = 0;
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
377 } else {
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
378 buffer->pos = pos - delta;
063a9f29098c ucx update + fix doc attach/detach + fix ui_set with unbound values
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 440
diff changeset
379 }
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
380 return written;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
381 }
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
382
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
383 int cxBufferPut(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
384 CxBuffer *buffer,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
385 int c
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
386 ) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
387 c &= 0xFF;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
388 unsigned char const ch = c;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
389 if (cxBufferWrite(&ch, 1, 1, buffer) == 1) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
390 return c;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
391 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
392 return EOF;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
393 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
394 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
395
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
396 int cxBufferTerminate(CxBuffer *buffer) {
629
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
397 if (0 == cxBufferPut(buffer, 0)) {
0385a450c2a6 add list initializer
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 471
diff changeset
398 buffer->size = buffer->pos - 1;
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
399 return 0;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
400 } else {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
401 return -1;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
402 }
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
403 }
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
404
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
405 size_t cxBufferPutString(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
406 CxBuffer *buffer,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
407 const char *str
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
408 ) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
409 return cxBufferWrite(str, 1, strlen(str), buffer);
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
410 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
411
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
412 size_t cxBufferRead(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
413 void *ptr,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
414 size_t size,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
415 size_t nitems,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
416 CxBuffer *buffer
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
417 ) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
418 size_t len;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
419 if (cx_szmul(size, nitems, &len)) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
420 errno = EOVERFLOW;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
421 return 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
422 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
423 if (buffer->pos + len > buffer->size) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
424 len = buffer->size - buffer->pos;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
425 if (size > 1) len -= len % size;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
426 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
427
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
428 if (len <= 0) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
429 return len;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
430 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
431
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
432 memcpy(ptr, buffer->bytes + buffer->pos, len);
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
433 buffer->pos += len;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
434
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
435 return len / size;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
436 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
437
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
438 int cxBufferGet(CxBuffer *buffer) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
439 if (cxBufferEof(buffer)) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
440 return EOF;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
441 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
442 int c = buffer->bytes[buffer->pos];
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
443 buffer->pos++;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
444 return c;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
446 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
447
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
448 int cxBufferShiftLeft(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
449 CxBuffer *buffer,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
450 size_t shift
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
451 ) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
452 if (shift >= buffer->size) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
453 buffer->pos = buffer->size = 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
454 } else {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
455 if (buffer_copy_on_write(buffer)) return -1;
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
456 memmove(buffer->bytes, buffer->bytes + shift, buffer->size - shift);
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
457 buffer->size -= shift;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
458
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
459 if (buffer->pos >= shift) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
460 buffer->pos -= shift;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
461 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
462 buffer->pos = 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
463 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
464 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
465 return 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
466 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
467
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
468 int cxBufferShiftRight(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
469 CxBuffer *buffer,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
470 size_t shift
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
471 ) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
472 if (buffer->size > SIZE_MAX - shift) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
473 errno = EOVERFLOW;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
474 return -1;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
475 }
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
476 size_t req_capacity = buffer->size + shift;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
477 size_t movebytes;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
478
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
479 // auto extend buffer, if required and enabled
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
480 if (buffer->capacity < req_capacity) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
481 if (buffer->flags & CX_BUFFER_AUTO_EXTEND) {
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
482 if (cxBufferMinimumCapacity(buffer, req_capacity)) {
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
483 return -1; // LCOV_EXCL_LINE
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
484 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
485 movebytes = buffer->size;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
486 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
487 movebytes = buffer->capacity - shift;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
488 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
489 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
490 movebytes = buffer->size;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
491 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
492
440
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
493 if (movebytes > 0) {
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
494 if (buffer_copy_on_write(buffer)) return -1;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
495 memmove(buffer->bytes + shift, buffer->bytes, movebytes);
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
496 buffer->size = shift + movebytes;
7c4b9cba09ca update ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 324
diff changeset
497 }
174
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
498
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
499 buffer->pos += shift;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
500 if (buffer->pos > buffer->size) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
501 buffer->pos = buffer->size;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
502 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
503
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
504 return 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
505 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
506
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
507 int cxBufferShift(
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
508 CxBuffer *buffer,
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
509 off_t shift
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
510 ) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
511 if (shift < 0) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
512 return cxBufferShiftLeft(buffer, (size_t) (-shift));
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
513 } else if (shift > 0) {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
514 return cxBufferShiftRight(buffer, (size_t) shift);
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
515 } else {
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
516 return 0;
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
517 }
0358f1d9c506 upgrade ucx
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
518 }

mercurial