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