ucx/buffer.c

changeset 157
0b33b9396851
parent 152
62921b370c60
--- a/ucx/buffer.c	Mon Feb 04 14:46:11 2019 +0100
+++ b/ucx/buffer.c	Mon Feb 04 17:49:50 2019 +0100
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2016 Olaf Wintermann. All rights reserved.
+ * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -26,7 +26,8 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "buffer.h"
+#include "ucx/buffer.h"
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
@@ -64,8 +65,9 @@
 
 UcxBuffer* ucx_buffer_extract(
         UcxBuffer *src, size_t start, size_t length, int flags) {
-    
-    if (src->size == 0 || length == 0 || start+length > src->capacity) {
+    if (src->size == 0 || length == 0 ||
+        ((size_t)-1) - start < length || start+length > src->capacity)
+    {
         return NULL;
     }
 
@@ -149,8 +151,10 @@
 
 size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
         UcxBuffer *buffer) {
-    size_t len = size * nitems;
-    const char *string = ptr;
+    size_t len;
+    if(ucx_szmul(size, nitems, &len)) {
+        return 0;
+    }
     size_t required = buffer->pos + len;
     if (buffer->pos > required) {
         return 0;
@@ -184,7 +188,10 @@
 
 size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
         UcxBuffer *buffer) {
-    size_t len = size * nitems;
+    size_t len;
+    if(ucx_szmul(size, nitems, &len)) {
+        return 0;
+    }
     if (buffer->pos + len > buffer->size) {
         len = buffer->size - buffer->pos;
         if (size > 1) len -= len%size;
@@ -224,12 +231,67 @@
     if (ucx_buffer_eof(buffer)) {
         return EOF;
     } else {
-        int c = buffer->space[buffer->pos];
+        int c = ((unsigned char*)buffer->space)[buffer->pos];
         buffer->pos++;
         return c;
     }
 }
 
-size_t ucx_buffer_puts(UcxBuffer *buffer, char *str) {
+size_t ucx_buffer_puts(UcxBuffer *buffer, const char *str) {
     return ucx_buffer_write((const void*)str, 1, strlen(str), buffer);
 }
+
+int ucx_buffer_shift_left(UcxBuffer* buffer, size_t shift) {
+    if (shift >= buffer->size) {
+        buffer->pos = buffer->size = 0;
+    } else {
+        memmove(buffer->space, buffer->space + shift, buffer->size - shift);
+        buffer->size -= shift;
+        
+        if (buffer->pos >= shift) {
+            buffer->pos -= shift;
+        } else {
+            buffer->pos = 0;
+        }
+    }
+    return 0;
+}
+
+int ucx_buffer_shift_right(UcxBuffer* buffer, size_t shift) {
+    size_t req_capacity = buffer->size + shift;
+    size_t movebytes;
+    
+    // auto extend buffer, if required and enabled
+    if (buffer->capacity < req_capacity) {
+        if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
+            if (ucx_buffer_extend(buffer, req_capacity - buffer->capacity)) {
+                return 1;
+            }
+            movebytes = buffer->size;
+        } else {
+            movebytes = buffer->capacity - shift;
+        }
+    } else {
+        movebytes = buffer->size;
+    }
+    
+    memmove(buffer->space + shift, buffer->space, movebytes);
+    buffer->size = shift+movebytes;
+    
+    buffer->pos += shift;
+    if (buffer->pos > buffer->size) {
+        buffer->pos = buffer->size;
+    }
+    
+    return 0;
+}
+
+int ucx_buffer_shift(UcxBuffer* buffer, off_t shift) {
+    if (shift < 0) {
+        return ucx_buffer_shift_left(buffer, (size_t) (-shift));
+    } else if (shift > 0) {
+        return ucx_buffer_shift_right(buffer, (size_t) shift);
+    } else {
+        return 0;
+    }
+}

mercurial