Graphviz  2.29.20120523.0446
lib/graph/agxbuf.c
Go to the documentation of this file.
00001 /* $Id$ $Revision$ */
00002 /* vim:set shiftwidth=4 ts=8: */
00003 
00004 /*************************************************************************
00005  * Copyright (c) 2011 AT&T Intellectual Property 
00006  * All rights reserved. This program and the accompanying materials
00007  * are made available under the terms of the Eclipse Public License v1.0
00008  * which accompanies this distribution, and is available at
00009  * http://www.eclipse.org/legal/epl-v10.html
00010  *
00011  * Contributors: See CVS logs. Details at http://www.graphviz.org/
00012  *************************************************************************/
00013 
00014 
00015 #include <stdio.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <agxbuf.h>
00019 
00020 #define N_GNEW(n,t)      (t*)malloc((n)*sizeof(t))
00021 
00022 /* agxbinit:
00023  * Assume if init is non-null, hint = sizeof(init[])
00024  */
00025 void agxbinit(agxbuf * xb, unsigned int hint, unsigned char *init)
00026 {
00027     if (init) {
00028         xb->buf = init;
00029         xb->dyna = 0;
00030     } else {
00031         if (hint == 0)
00032             hint = BUFSIZ;
00033         xb->dyna = 1;
00034         xb->buf = N_GNEW(hint, unsigned char);
00035     }
00036     xb->eptr = xb->buf + hint;
00037     xb->ptr = xb->buf;
00038     *xb->ptr = '\0';
00039 }
00040 
00041 /* agxbmore;
00042  * Expand buffer to hold at least ssz more bytes.
00043  */
00044 int agxbmore(agxbuf * xb, unsigned int ssz)
00045 {
00046     int cnt;                    /* current no. of characters in buffer */
00047     int size;                   /* current buffer size */
00048     int nsize;                  /* new buffer size */
00049     unsigned char *nbuf;        /* new buffer */
00050 
00051     size = xb->eptr - xb->buf;
00052     nsize = 2 * size;
00053     if (size + ssz > nsize)
00054         nsize = size + ssz;
00055     cnt = xb->ptr - xb->buf;
00056     if (xb->dyna) {
00057         nbuf = (unsigned char*)realloc(xb->buf, nsize);
00058     } else {
00059         nbuf = N_GNEW(nsize, unsigned char);
00060         memcpy(nbuf, xb->buf, cnt);
00061         xb->dyna = 1;
00062     }
00063     xb->buf = nbuf;
00064     xb->ptr = xb->buf + cnt;
00065     xb->eptr = xb->buf + nsize;
00066     return 0;
00067 }
00068 
00069 /* agxbput_n:
00070  * Append string s of length n onto xb
00071  */
00072 int agxbput_n(agxbuf * xb, const char *s, unsigned int ssz)
00073 {
00074     if (xb->ptr + ssz > xb->eptr)
00075         agxbmore(xb, ssz);
00076     memcpy(xb->ptr, s, ssz);
00077     xb->ptr += ssz;
00078     return ssz;
00079 }
00080 
00081 /* agxbput:
00082  * Append string s into xb
00083  */
00084 int agxbput(agxbuf * xb, const char *s)
00085 {
00086     unsigned int ssz = strlen(s);
00087 
00088     return agxbput_n(xb, s, ssz);
00089 }
00090 
00091 /* agxbfree:
00092  * Free any malloced resources.
00093  */
00094 void agxbfree(agxbuf * xb)
00095 {
00096     if (xb->dyna)
00097         free(xb->buf);
00098 }
00099 
00100 /* agxbpop:
00101  * Removes last character added, if any.
00102  */
00103 int agxbpop(agxbuf * xb)
00104 {
00105     int c;
00106     if (xb->ptr > xb->buf) {
00107         c = *xb->ptr--;
00108         return c;
00109     } else
00110         return -1;
00111 
00112 }