/work/svt-av1/Source/Lib/Codec/vector.c
Line | Count | Source |
1 | | /* |
2 | | The MIT License(MIT) |
3 | | Copyright(c) 2016 Peter Goldsborough |
4 | | |
5 | | Permission is hereby granted, free of charge, to any person obtaining a copy of |
6 | | this software and associated documentation files(the "Software"), to deal in |
7 | | the Software without restriction, including without limitation the rights to |
8 | | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of |
9 | | the Software, and to permit persons to whom the Software is furnished to do so, |
10 | | subject to the following conditions : |
11 | | |
12 | | The above copyright notice and this permission notice shall be included in all |
13 | | copies or substantial portions of the Software. |
14 | | |
15 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS |
17 | | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR |
18 | | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER |
19 | | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
20 | | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
21 | | */ |
22 | | |
23 | | #include <assert.h> |
24 | | #include <stdlib.h> |
25 | | #include <string.h> |
26 | | |
27 | | #include "svt_malloc.h" |
28 | | |
29 | | #include "vector.h" |
30 | 0 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
31 | | |
32 | 0 | int svt_aom_vector_setup(Vector* vector, uint32_t capacity, uint32_t element_size) { |
33 | 0 | assert(vector != NULL); |
34 | |
|
35 | 0 | if (vector == NULL) { |
36 | 0 | return VECTOR_ERROR; |
37 | 0 | } |
38 | | |
39 | 0 | vector->size = 0; |
40 | 0 | vector->capacity = MAX(VECTOR_MINIMUM_CAPACITY, capacity); |
41 | 0 | vector->element_size = element_size; |
42 | 0 | EB_MALLOC_NO_CHECK(vector->data, vector->capacity * element_size); |
43 | |
|
44 | 0 | return vector->data == NULL ? VECTOR_ERROR : VECTOR_SUCCESS; |
45 | 0 | } |
46 | | |
47 | 0 | int svt_aom_vector_destroy(Vector* vector) { |
48 | 0 | assert(vector != NULL); |
49 | |
|
50 | 0 | if (vector == NULL) { |
51 | 0 | return VECTOR_ERROR; |
52 | 0 | } |
53 | | |
54 | 0 | EB_FREE(vector->data); |
55 | 0 | vector->data = NULL; |
56 | |
|
57 | 0 | return VECTOR_SUCCESS; |
58 | 0 | } |
59 | | |
60 | | /* Insertion */ |
61 | 0 | int svt_aom_vector_push_back(Vector* vector, void* element) { |
62 | 0 | assert(vector != NULL); |
63 | 0 | assert(element != NULL); |
64 | |
|
65 | 0 | if (_vector_should_grow(vector)) { |
66 | 0 | if (_vector_adjust_capacity(vector) == VECTOR_ERROR) { |
67 | 0 | return VECTOR_ERROR; |
68 | 0 | } |
69 | 0 | } |
70 | | |
71 | 0 | _vector_assign(vector, vector->size, element); |
72 | |
|
73 | 0 | ++vector->size; |
74 | |
|
75 | 0 | return VECTOR_SUCCESS; |
76 | 0 | } |
77 | | |
78 | | /* Information */ |
79 | | |
80 | 0 | size_t svt_aom_vector_byte_size(const Vector* vector) { |
81 | 0 | return (size_t)vector->size * vector->element_size; |
82 | 0 | } |
83 | | |
84 | | /* Iterators */ |
85 | 0 | Iterator svt_aom_vector_begin(Vector* vector) { |
86 | 0 | return svt_aom_vector_iterator(vector, 0); |
87 | 0 | } |
88 | | |
89 | 0 | Iterator svt_aom_vector_iterator(Vector* vector, size_t index) { |
90 | 0 | Iterator iterator = {NULL, 0}; |
91 | |
|
92 | 0 | assert(vector != NULL && index <= vector->size); |
93 | |
|
94 | 0 | if (vector == NULL) { |
95 | 0 | return iterator; |
96 | 0 | } |
97 | 0 | if (index > vector->size) { |
98 | 0 | return iterator; |
99 | 0 | } |
100 | 0 | if (vector->element_size == 0) { |
101 | 0 | return iterator; |
102 | 0 | } |
103 | | |
104 | 0 | iterator.pointer = _vector_offset(vector, index); |
105 | 0 | iterator.element_size = vector->element_size; |
106 | |
|
107 | 0 | return iterator; |
108 | 0 | } |
109 | | |
110 | 0 | void* svt_aom_iterator_get(Iterator* iterator) { |
111 | 0 | return iterator->pointer; |
112 | 0 | } |
113 | | |
114 | 0 | void svt_aom_iterator_increment(Iterator* iterator) { |
115 | 0 | assert(iterator != NULL); |
116 | 0 | iterator->pointer = (unsigned char*)iterator->pointer + iterator->element_size; |
117 | 0 | } |
118 | | |
119 | | /***** PRIVATE *****/ |
120 | | |
121 | 0 | bool _vector_should_grow(Vector* vector) { |
122 | 0 | assert(vector->size <= vector->capacity); |
123 | 0 | return vector->size == vector->capacity; |
124 | 0 | } |
125 | | |
126 | 0 | void* _vector_offset(Vector* vector, size_t index) { |
127 | 0 | return (unsigned char*)vector->data + (index * vector->element_size); |
128 | 0 | } |
129 | | |
130 | 0 | void _vector_assign(Vector* vector, size_t index, void* element) { |
131 | | /* Insert the element */ |
132 | 0 | void* offset = _vector_offset(vector, index); |
133 | 0 | svt_memcpy(offset, element, vector->element_size); |
134 | 0 | } |
135 | | |
136 | 0 | int _vector_adjust_capacity(Vector* vector) { |
137 | 0 | return _vector_reallocate(vector, MAX(1, vector->size * VECTOR_GROWTH_FACTOR)); |
138 | 0 | } |
139 | | |
140 | 0 | int _vector_reallocate(Vector* vector, uint32_t new_capacity) { |
141 | 0 | size_t new_capacity_in_bytes; |
142 | 0 | void* old; |
143 | 0 | assert(vector != NULL); |
144 | |
|
145 | 0 | if (new_capacity < VECTOR_MINIMUM_CAPACITY) { |
146 | 0 | if (vector->capacity > VECTOR_MINIMUM_CAPACITY) { |
147 | 0 | new_capacity = VECTOR_MINIMUM_CAPACITY; |
148 | 0 | } else { |
149 | | /* NO-OP */ |
150 | 0 | return VECTOR_SUCCESS; |
151 | 0 | } |
152 | 0 | } |
153 | | |
154 | 0 | new_capacity_in_bytes = new_capacity * vector->element_size; |
155 | 0 | old = vector->data; |
156 | |
|
157 | 0 | EB_MALLOC_NO_CHECK(vector->data, new_capacity_in_bytes); |
158 | 0 | if (vector->data == NULL) { |
159 | 0 | return VECTOR_ERROR; |
160 | 0 | } |
161 | | #ifdef __STDC_LIB_EXT1__ |
162 | | if (memcpy_s(vector->data, new_capacity_in_bytes, old, svt_aom_vector_byte_size(vector)) != 0) { |
163 | | return VECTOR_ERROR; |
164 | | } |
165 | | #else |
166 | 0 | svt_memcpy(vector->data, old, svt_aom_vector_byte_size(vector)); |
167 | 0 | #endif |
168 | |
|
169 | 0 | vector->capacity = new_capacity; |
170 | |
|
171 | 0 | EB_FREE(old); |
172 | |
|
173 | 0 | return VECTOR_SUCCESS; |
174 | 0 | } |