ucx/buffer.c

Fri, 12 Dec 2025 10:42:53 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 12 Dec 2025 10:42:53 +0100
changeset 30
d33eaaec15da
parent 23
b26390e77237
permissions
-rw-r--r--

update ucx

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

mercurial