summaryrefslogtreecommitdiff
path: root/src/codevect.c
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2020-03-14 15:29:52 +0200
committerAdrian Thurston <thurston@colm.net>2020-03-14 15:29:52 +0200
commitf653735830d537715f2885bd832cf04851d35401 (patch)
tree95e6551e39407543366d4f49aedf7b78c6e8bbe1 /src/codevect.c
parentbcc54d5df10cf425e7134b06f70d7ffe1abee4e4 (diff)
downloadcolm-f653735830d537715f2885bd832cf04851d35401.tar.gz
moved source files into commit repository
Diffstat (limited to 'src/codevect.c')
-rw-r--r--src/codevect.c183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/codevect.c b/src/codevect.c
new file mode 100644
index 00000000..50b86336
--- /dev/null
+++ b/src/codevect.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2010-2018 Adrian Thurston <thurston@colm.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <colm/rtvector.h>
+#include <colm/pdarun.h>
+
+void init_rt_code_vect( struct rt_code_vect *vect )
+{
+ vect->data = 0;
+ vect->tab_len = 0;
+ vect->alloc_len = 0;
+}
+
+static long new_size_up( long existing, long needed )
+{
+ return needed > existing ? (needed<<1) : existing;
+}
+
+static long new_size_down( long existing, long needed )
+{
+ return needed < (existing>>2) ? (needed<<1) : existing;
+}
+
+/* Up resize the data for len elements using Resize::upResize to tell us the
+ * new tabLen. Reads and writes allocLen. Does not read or write tabLen. */
+static void up_resize( struct rt_code_vect *vect, long len )
+{
+ /* Ask the resizer what the new tabLen will be. */
+ long new_len = new_size_up(vect->alloc_len, len);
+
+ /* Did the data grow? */
+ if ( new_len > vect->alloc_len ) {
+ vect->alloc_len = new_len;
+ if ( vect->data != 0 ) {
+ /* Table exists already, resize it up. */
+ vect->data = (code_t*) realloc( vect->data, sizeof(code_t) * new_len );
+ //if ( vect->data == 0 )
+ // throw std::bad_alloc();
+ }
+ else {
+ /* Create the data. */
+ vect->data = (code_t*) malloc( sizeof(code_t) * new_len );
+ //if ( vect->data == 0 )
+ // throw std::bad_alloc();
+ }
+ }
+}
+
+/* Down resize the data for len elements using Resize::downResize to determine
+ * the new tabLen. Reads and writes allocLen. Does not read or write tabLen. */
+static void down_resize( struct rt_code_vect *vect, long len)
+{
+ /* Ask the resizer what the new tabLen will be. */
+ long new_len = new_size_down( vect->alloc_len, len );
+
+ /* Did the data shrink? */
+ if ( new_len < vect->alloc_len ) {
+ vect->alloc_len = new_len;
+ if ( new_len == 0 ) {
+ /* Simply free the data. */
+ free( vect->data );
+ vect->data = 0;
+ }
+ else {
+ /* Not shrinking to size zero, realloc it to the smaller size. */
+ vect->data = (code_t*) realloc( vect->data, sizeof(code_t) * new_len );
+ //if ( vect->data == 0 )
+ // throw std::bad_alloc();
+ }
+ }
+}
+
+
+void colm_rt_code_vect_empty( struct rt_code_vect *vect )
+{
+ if ( vect->data != 0 ) {
+ /* Free the data space. */
+ free( vect->data );
+ vect->data = 0;
+ vect->tab_len = vect->alloc_len = 0;
+ }
+}
+
+void colm_rt_code_vect_replace( struct rt_code_vect *vect, long pos,
+ const code_t *val, long len )
+{
+ long end_pos, i;
+ //code_t *item;
+
+ /* If we are given a negative position to replace at then
+ * treat it as a position relative to the length. */
+ if ( pos < 0 )
+ pos = vect->tab_len + pos;
+
+ /* The end is the one past the last item that we want
+ * to write to. */
+ end_pos = pos + len;
+
+ /* Make sure we have enough space. */
+ if ( end_pos > vect->tab_len ) {
+ up_resize( vect, end_pos );
+
+ /* Delete any objects we need to delete. */
+ //item = vect->data + pos;
+ //for ( i = pos; i < vect->tabLen; i++, item++ )
+ // item->~code_t();
+
+ /* We are extending the vector, set the new data length. */
+ vect->tab_len = end_pos;
+ }
+ else {
+ /* Delete any objects we need to delete. */
+ //item = vect->data + pos;
+ //for ( i = pos; i < endPos; i++, item++ )
+ // item->~code_t();
+ }
+
+ /* Copy data in using copy constructor. */
+ code_t *dst = vect->data + pos;
+ const code_t *src = val;
+ for ( i = 0; i < len; i++, dst++, src++ )
+ *dst = *src;
+}
+
+void colm_rt_code_vect_remove( struct rt_code_vect *vect, long pos, long len )
+{
+ long new_len, len_to_slide_over, end_pos;
+ code_t *dst;//, *item;
+
+ /* If we are given a negative position to remove at then
+ * treat it as a position relative to the length. */
+ if ( pos < 0 )
+ pos = vect->tab_len + pos;
+
+ /* The first position after the last item deleted. */
+ end_pos = pos + len;
+
+ /* The new data length. */
+ new_len = vect->tab_len - len;
+
+ /* The place in the data we are deleting at. */
+ dst = vect->data + pos;
+
+ /* Call Destructors. */
+ //item = dst;
+ //for ( long i = 0; i < len; i += 1, item += 1 )
+ // item->~code_t();
+
+ /* Shift data over if necessary. */
+ len_to_slide_over = vect->tab_len - end_pos;
+ if ( len > 0 && len_to_slide_over > 0 )
+ memmove(dst, dst + len, sizeof(code_t)*len_to_slide_over);
+
+ /* Shrink the data if necessary. */
+ down_resize( vect, new_len );
+
+ /* Set the new data length. */
+ vect->tab_len = new_len;
+}
+
+