You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2011/04/27 08:57:42 UTC

svn commit: r1097014 - in /commons/sandbox/runtime/trunk/src/main/native: Makefile.msc.in Makefile.unx.in include/acr/sbuf.h shared/sbuf.c

Author: mturk
Date: Wed Apr 27 06:57:42 2011
New Revision: 1097014

URL: http://svn.apache.org/viewvc?rev=1097014&view=rev
Log:
Add string buffer helper

Added:
    commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h   (with props)
    commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
    commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=1097014&r1=1097013&r2=1097014&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Wed Apr 27 06:57:42 2011
@@ -112,6 +112,7 @@ LIBSOURCES=\
 	$(TOPDIR)\shared\object.c \
 	$(TOPDIR)\shared\observer.c \
 	$(TOPDIR)\shared\reflect.c \
+	$(TOPDIR)\shared\sbuf.c \
 	$(TOPDIR)\shared\sliceptr.c \
 	$(TOPDIR)\shared\string.c \
 	$(TOPDIR)\shared\system.c \

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in?rev=1097014&r1=1097013&r2=1097014&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.unx.in Wed Apr 27 06:57:42 2011
@@ -109,6 +109,7 @@ LIBSOURCES=\
 	$(TOPDIR)/shared/object.c \
 	$(TOPDIR)/shared/observer.c \
 	$(TOPDIR)/shared/reflect.c \
+	$(TOPDIR)/shared/sbuf.c \
 	$(TOPDIR)/shared/sliceptr.c \
 	$(TOPDIR)/shared/string.c \
 	$(TOPDIR)/shared/system.c \

Added: commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h?rev=1097014&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h (added)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h Wed Apr 27 06:57:42 2011
@@ -0,0 +1,99 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ACR_SBUF_H
+#define _ACR_SBUF_H
+
+#include "acr/stdtypes.h"
+/**
+ * sbuf flags
+ */
+#define ACR_SB_FIXEDLEN   0x00000000  /* fixed length buffer (default)      */
+#define ACR_SB_AUTOEXTEND 0x00000001  /* automatically extend buffer        */
+#define ACR_SB_USRFLAGMSK 0x0000ffff  /* mask of flags the user may specify */
+#define ACR_SB_DYNAMIC    0x00010000  /* s_buf must be freed                */
+#define ACR_SB_FINISHED   0x00020000  /* set by sbuf_finish()               */
+#define ACR_SB_OVERFLOWED 0x00040000  /* sbuf overflowed                    */
+#define ACR_SB_DYNSTRUCT  0x00080000  /* sbuf must be freed                 */
+
+#define ACR_SBUF_INIT_AUTO(Buf, Siz)   AcrSbInitAuto((Buf), (int)(Siz))
+
+typedef struct acr_sb_t acr_sb_t;
+
+struct acr_sb_t {
+    char            *s_buf;     /* storage buffer */
+    int              s_size;    /* size of storage buffer */
+    int              s_len;     /* current length of string */
+    unsigned int     s_max;     /* maximum storage size */
+    unsigned int     s_flags;   /* flags */
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Sbuf API functions
+ */
+ 
+acr_sb_t *AcrSbNew(char *, int, unsigned int);
+acr_sb_t *AcrSbDup(acr_sb_t *buf);
+int       AcrSbInit(acr_sb_t *, char *, int, unsigned int);
+void      AcrSbFree(acr_sb_t *);
+void      AcrSbClear(acr_sb_t *);
+int       AcrSbSetPos(acr_sb_t *, int);
+int       AcrSbSetMax(acr_sb_t *, int);
+int       AcrSbCatb(acr_sb_t *, const void *, int);
+int       AcrSbCpyb(acr_sb_t *, const void *, int);
+int       AcrSbCat(acr_sb_t *, const char *);
+int       AcrSbCpy(acr_sb_t *, const char *);
+int       AcrSbPutc(acr_sb_t *, int);
+int       AcrSbPutb(acr_sb_t *, int);
+int       AcrSbRightTrim(acr_sb_t *);
+char     *AcrSbLeftTrim(acr_sb_t *);
+char     *AcrSbTrim(acr_sb_t *);
+int       AcrSbOverflowed(acr_sb_t *);
+void      AcrSbFinish(acr_sb_t *);
+void      AcrSbFlush(acr_sb_t *);
+char     *AcrSbFetach(acr_sb_t *);
+int       AcrSbLen(acr_sb_t *);
+int       AcrSbCapacity(acr_sb_t *);
+int       AcrSbDone(acr_sb_t *);
+int       AcrSbCatl(acr_sb_t *s, va_list ap);
+int       AcrSbCatv(acr_sb_t *s, ...);
+
+/*
+ * Return a pointer to the sbuf data.
+ */
+ACR_INLINE(char *)     AcrSbData(acr_sb_t *s)
+{
+    return s->s_buf;
+}
+
+ACR_INLINE(acr_sb_t *) AcrSbNewAuto(void)
+{
+    return AcrSbNew(0, 0, ACR_SB_AUTOEXTEND);
+}
+
+ACR_INLINE(int) AcrSbInitAuto(acr_sb_t *b, int s)
+{
+    return AcrSbInit(b, 0, s, ACR_SB_AUTOEXTEND);
+}
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ACR_SBUF_H */

Propchange: commons/sandbox/runtime/trunk/src/main/native/include/acr/sbuf.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c?rev=1097014&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c Wed Apr 27 06:57:42 2011
@@ -0,0 +1,550 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr/sbuf.h"
+#include "acr/error.h"
+#include "acr/string.h"
+
+/*
+ * Predicates
+ */
+#define SBUF_ISDYNAMIC(s)       ((s)->s_flags & ACR_SB_DYNAMIC)
+#define SBUF_ISDYNSTRUCT(s)     ((s)->s_flags & ACR_SB_DYNSTRUCT)
+#define SBUF_ISFINISHED(s)      ((s)->s_flags & ACR_SB_FINISHED)
+#define SBUF_HASOVERFLOWED(s)   ((s)->s_flags & ACR_SB_OVERFLOWED || (s)->s_buf == 0)
+#define SBUF_HASROOM(s)         ((s)->s_len   < ((s)->s_size - 1))
+#define SBUF_FREESPACE(s)       ((s)->s_size  - ((s)->s_len  + 1))
+#define SBUF_CANEXTEND(s)       ((s)->s_flags & ACR_SB_AUTOEXTEND)
+
+/*
+ * Set / clear flags
+ */
+#define SBUF_SETFLAG(s, f)      do { (s)->s_flags |=  (f); } while (0)
+#define SBUF_CLRFLAG(s, f)      do { (s)->s_flags &= ~(f); } while (0)
+#define SBUF_MINEXTEND_SIZE     16 /* Should be power of 2. */
+
+static int sbuf_extend_size(int size)
+{
+    int newsize;
+    if (size > 65536)
+        newsize = 65536;
+    else
+        newsize = SBUF_MINEXTEND_SIZE;
+    while (newsize < size) {
+        if (newsize < 65536)
+            newsize *= 2;
+        else
+            newsize += 65536;
+    }
+    return newsize;
+}
+
+/*
+ * Extend an sbuf.
+ */
+static int
+sbuf_extend(acr_sb_t *s, int addlen)
+{
+    char *newbuf;
+    unsigned int newsize;
+
+    if (!SBUF_CANEXTEND(s))
+        return -1;
+
+    newsize = sbuf_extend_size(s->s_size + addlen);
+    if (newsize > s->s_max)
+        return -1;
+    newbuf = malloc(newsize);
+    if (newbuf == 0)
+        return -1;
+    memcpy(newbuf, s->s_buf, s->s_size);
+    if (SBUF_ISDYNAMIC(s))
+        AcrFree(s->s_buf);
+    else
+        SBUF_SETFLAG(s, ACR_SB_DYNAMIC);
+    s->s_buf  = newbuf;
+    s->s_size = newsize;
+
+    return 0;
+}
+
+/*
+ * Initialize an sbuf.
+ * If buf is non-NULL, it points to a static or already-allocated string
+ * big enough to hold at least length characters.
+ */
+acr_sb_t *
+AcrSbNew(char *buf, int length, unsigned int flags)
+{
+    acr_sb_t *s;
+    if ((flags & ~ACR_SB_USRFLAGMSK) || length < 0) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return 0;
+    }
+    flags &= ACR_SB_USRFLAGMSK;
+    s = calloc(1, sizeof(acr_sb_t));
+    if (s == 0)
+        return 0;
+    s->s_flags = flags;
+    SBUF_SETFLAG(s, ACR_SB_DYNSTRUCT);
+    s->s_size = length;
+    if (buf) {
+        s->s_max = length;
+        s->s_buf = buf;
+        return s;
+    }
+    if (flags & ACR_SB_AUTOEXTEND)
+        s->s_size = sbuf_extend_size(s->s_size);
+    s->s_buf = malloc(s->s_size);
+    if (s->s_buf == 0) {
+        AcrFree(s);
+        ACR_SET_OS_ERROR(ACR_ENOMEM);
+        return 0;
+    }
+    s->s_max = INT_MAX - 65536;
+    SBUF_SETFLAG(s, ACR_SB_DYNAMIC);
+    return s;
+}
+
+acr_sb_t *
+AcrSbDup(acr_sb_t *buf)
+{
+    acr_sb_t *s;
+
+    s = malloc(sizeof(acr_sb_t));
+    if (s == 0)
+        return 0;
+    s->s_flags  = buf->s_flags & ACR_SB_USRFLAGMSK;
+    s->s_flags |= ACR_SB_DYNSTRUCT | ACR_SB_AUTOEXTEND | ACR_SB_DYNAMIC;
+    s->s_len  = buf->s_len;
+    s->s_max  = INT_MAX - 65536;
+    s->s_size = sbuf_extend_size(s->s_len);
+    s->s_buf  = malloc(s->s_size);
+    if (s->s_buf == 0) {
+        AcrFree(s);
+        ACR_SET_OS_ERROR(ACR_ENOMEM);
+        return 0;
+    }
+    if (s->s_len)
+        memcpy(s->s_buf, buf->s_buf, s->s_len);
+    return s;
+}
+
+int
+AcrSbInit(acr_sb_t *s, char *buf, int length, unsigned int flags)
+{
+
+    if(s == 0)
+        return ACR_EINVAL;
+    if ((flags & ~ACR_SB_USRFLAGMSK) || length < 0) {
+        return ACR_EINVAL;
+    }
+    flags &= ACR_SB_USRFLAGMSK;
+    memset(s, 0, sizeof(acr_sb_t));
+    s->s_size  = length;
+    if (buf != 0) {
+        s->s_buf   = buf;
+        s->s_max   = length;
+        s->s_flags = flags;
+        return 0;
+    }
+    s->s_flags = flags | ACR_SB_AUTOEXTEND;
+    s->s_size  = sbuf_extend_size(s->s_size);
+    s->s_buf   = malloc(s->s_size);
+    s->s_max   = INT_MAX - 65536;
+    if (s->s_buf == 0)
+        return ACR_ENOMEM;
+    SBUF_SETFLAG(s, ACR_SB_DYNAMIC);
+    return 0;
+}
+
+/*
+ * Clear an sbuf and reset its position.
+ */
+void
+AcrSbClear(acr_sb_t *s)
+{
+
+    if (s != 0) {
+        /* don't care if it's finished or not */
+        SBUF_CLRFLAG(s, ACR_SB_FINISHED);
+        if (s->s_buf)
+            SBUF_CLRFLAG(s, ACR_SB_OVERFLOWED);
+        s->s_len = 0;
+    }
+}
+
+/*
+ * Set the sbuf's end position to an arbitrary value.
+ * Effectively truncates the sbuf at the new position.
+ */
+int
+AcrSbSetPos(acr_sb_t *s, int pos)
+{
+
+    if (pos >= s->s_size) {
+        return ACR_EINVAL;
+    }
+    if (pos > s->s_len)
+        return ACR_EOVERFLOW;
+    SBUF_CLRFLAG(s, ACR_SB_FINISHED);
+    SBUF_CLRFLAG(s, ACR_SB_OVERFLOWED);
+    s->s_len = pos;
+    return 0;
+}
+
+/*
+ * Set the sbuf's maximum size.
+ */
+int
+AcrSbSetMax(acr_sb_t *s, int len)
+{
+
+    if (len < s->s_size) {
+        return ACR_EINVAL;
+    }
+    s->s_max = len;
+    return 0;
+}
+
+/*
+ * Append a byte string to an sbuf.
+ */
+int
+AcrSbCatb(acr_sb_t *s, const void *buf, int len)
+{
+    if (SBUF_HASOVERFLOWED(s)) {
+        return ACR_EOVERFLOW;
+    }
+    if (buf == 0 || len < 1) {
+        /* Nothing to do */
+        return 0;
+    }
+    if (len > SBUF_FREESPACE(s)) {
+        size_t x = len - SBUF_FREESPACE(s);
+        if (sbuf_extend(s, x) < 0)
+            return ACR_ENOMEM;
+    }
+    memcpy(s->s_buf + s->s_len, buf, len);
+    s->s_len += len;
+    return 0;
+}
+
+/*
+ * Copy a byte string into an sbuf.
+ */
+int
+AcrSbCpyb(acr_sb_t *s, const void *buf, int len)
+{
+
+    AcrSbClear(s);
+    return AcrSbCatb(s, buf, len);
+}
+
+/*
+ * Append a string to an sbuf.
+ */
+int
+AcrSbCat(acr_sb_t *s, const char *str)
+{
+
+    if (SBUF_HASOVERFLOWED(s)) {
+        return ACR_EOVERFLOW;
+    }
+    if (IS_EMPTY_STR(str)) {
+        /* Nothing to do.
+         * Empty strings cannot be added.
+         * We use finish() for that
+         */
+        return 0;
+    }
+    return AcrSbCatb(s, str, (int)strlen(str));
+}
+
+/*
+ * Copy a string into an sbuf.
+ */
+int
+AcrSbCpy(acr_sb_t *s, const char *str)
+{
+
+    AcrSbClear(s);
+    return AcrSbCat(s, str);
+}
+
+
+int
+AcrSbCatl(acr_sb_t *s, va_list ap)
+{
+    int   rc = 0;
+    char *src;
+
+    while ((src = va_arg(ap, char *)) != 0) {
+        rc = AcrSbCat(s, src);
+        if (rc != 0)
+            break;
+    }
+    return rc;
+}
+
+int
+AcrSbCatv(acr_sb_t *s, ...)
+{
+    int rc = 0;
+    va_list  ap;
+
+    va_start(ap, s);
+    rc = AcrSbCatl(s, ap);
+    va_end(ap);
+    return rc;
+}
+
+/*
+ * Append a character to an sbuf.
+ */
+int
+AcrSbPutc(acr_sb_t *s, int c)
+{
+
+    if (SBUF_HASOVERFLOWED(s)) {
+        return ACR_EOVERFLOW;
+    }
+    if (c == 0) {
+        /* Nothing to add */
+        return 0;
+    }
+    if (!SBUF_HASROOM(s) && sbuf_extend(s, 1) < 0) {
+        SBUF_SETFLAG(s, ACR_SB_OVERFLOWED);
+        return ACR_ENOMEM;
+    }
+    s->s_buf[s->s_len++] = (char)(c & 0xFF);
+    return 0;
+}
+
+/*
+ * Append a character to an sbuf allowing NUL.
+ */
+int
+AcrSbPutb(acr_sb_t *s, int c)
+{
+
+    if (SBUF_HASOVERFLOWED(s)) {
+        return ACR_EOVERFLOW;
+    }
+    if (!SBUF_HASROOM(s) && sbuf_extend(s, 1) < 0) {
+        SBUF_SETFLAG(s, ACR_SB_OVERFLOWED);
+        return ACR_ENOMEM;
+    }
+    s->s_buf[s->s_len++] = (char)(c & 0xFF);
+    return 0;
+}
+
+int
+AcrSbEndc(acr_sb_t *s)
+{
+
+    if (SBUF_HASOVERFLOWED(s)) {
+        ACR_SET_OS_ERROR(ACR_EOVERFLOW);
+        return -1;
+    }
+    return (unsigned char)s->s_buf[s->s_len];
+}
+
+int
+AcrSbGetc(acr_sb_t *s)
+{
+
+    if (SBUF_HASOVERFLOWED(s)) {
+        ACR_SET_OS_ERROR(ACR_EOVERFLOW);
+        return -1;
+    }
+    if (s->s_len > 0)
+        return (unsigned char)s->s_buf[s->s_len--];
+    else
+        return -1;
+}
+
+/*
+ * Trim whitespace characters from end of an sbuf.
+ */
+int
+AcrSbRightTrim(acr_sb_t *s)
+{
+
+    if (SBUF_HASOVERFLOWED(s)) {
+        return ACR_EOVERFLOW;
+    }
+    while (s->s_len && isspace((unsigned char)(s->s_buf[s->s_len-1])))
+        --s->s_len;
+
+    return 0;
+}
+
+/*
+ * Return pointer to the first non white space character
+ * in sbuf. The AcrSbfinish must be called before this
+ * function
+ */
+char *
+AcrSbLeftTrim(acr_sb_t *s)
+{
+
+    unsigned char *p;
+
+    p = (unsigned char *)s->s_buf;
+    if (SBUF_HASOVERFLOWED(s)) {
+        ACR_SET_OS_ERROR(ACR_EOVERFLOW);
+        return 0;
+    }
+    if (!SBUF_ISFINISHED(s))
+        return (char *)p;
+    while (*p && isspace(*p))
+        p++;
+
+    return (char *)p;
+}
+
+/*
+ * Trim the sbuf.
+ */
+char *
+AcrSbTrim(acr_sb_t *s)
+{
+
+    unsigned char *p;
+
+    p = (unsigned char *)s->s_buf;
+    if (SBUF_HASOVERFLOWED(s)) {
+        ACR_SET_OS_ERROR(ACR_EOVERFLOW);
+        return 0;
+    }
+
+    AcrSbRightTrim(s);
+    AcrSbFinish(s);
+
+    while (*p && isspace(*p))
+        p++;
+
+    return (char *)p;
+}
+
+/*
+ * Check if an sbuf overflowed
+ */
+int
+AcrSbOverflowed(acr_sb_t *s)
+{
+    return SBUF_HASOVERFLOWED(s);
+}
+
+/*
+ * Finish off an sbuf.
+ */
+void
+AcrSbFinish(acr_sb_t *s)
+{
+    if (s->s_buf) {
+        s->s_buf[s->s_len] = '\0';
+        SBUF_CLRFLAG(s, ACR_SB_OVERFLOWED);
+    }
+    SBUF_SETFLAG(s, ACR_SB_FINISHED);
+}
+
+/*
+ * Flush off an sbuf by terminating it with zero
+ */
+void
+AcrSbFlush(acr_sb_t *s)
+{
+    if (s->s_buf) {
+        s->s_buf[s->s_len] = '\0';
+    }
+}
+
+/*
+ * Detach a pointer to the sbuf data.
+ */
+char *
+AcrSbDetach(acr_sb_t *s)
+{
+    char *b;
+
+    if (s != 0) {
+        b = s->s_buf;
+        SBUF_SETFLAG(s, ACR_SB_FINISHED);
+        SBUF_SETFLAG(s, ACR_SB_OVERFLOWED);
+        s->s_buf  = 0;
+        s->s_len  = 0;
+        s->s_size = 0;
+        return b;
+    }
+    else
+        return 0;
+}
+
+/*
+ * Return the length of the sbuf data.
+ */
+int
+AcrSbLen(acr_sb_t *s)
+{
+    /* don't care if it's finished or not */
+    if (SBUF_HASOVERFLOWED(s)) {
+        ACR_SET_OS_ERROR(ACR_EOVERFLOW);
+        return -1;
+    }
+    return s->s_len;
+}
+
+/*
+ * Clear an sbuf, free its buffer if necessary.
+ */
+void
+AcrSbFree(acr_sb_t *s)
+{
+    int isdyn;
+
+    if (s != 0) {
+        /* don't care if it's finished or not */
+        if (SBUF_ISDYNAMIC(s))
+            AcrFree(s->s_buf);
+        isdyn = SBUF_ISDYNSTRUCT(s);
+        if (isdyn)
+            AcrFree(s);
+        else
+            memset(s, 0, sizeof(acr_sb_t));
+    }
+}
+
+/*
+ * Check if an sbuf has been finished.
+ */
+int
+AcrSbDone(acr_sb_t *s)
+{
+    return SBUF_ISFINISHED(s);
+}
+
+int
+AcrSbCapacity(acr_sb_t *s)
+{
+    if (SBUF_HASOVERFLOWED(s)) {
+        ACR_SET_OS_ERROR(ACR_EOVERFLOW);
+        return -1;
+    }
+    else
+        return SBUF_FREESPACE(s);
+}

Propchange: commons/sandbox/runtime/trunk/src/main/native/shared/sbuf.c
------------------------------------------------------------------------------
    svn:eol-style = native