1/* $Id$ $Revision$ */
2/* vim:set shiftwidth=4 ts=8: */
3
4/*************************************************************************
5 * Copyright (c) 2011 AT&T Intellectual Property
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors: See CVS logs. Details at http://www.graphviz.org/
12 *************************************************************************/
13
14
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <agxbuf.h>
19
20#define N_GNEW(n,t) (t*)malloc((n)*sizeof(t))
21
22/* agxbinit:
23 * Assume if init is non-null, hint = sizeof(init[])
24 */
25void agxbinit(agxbuf * xb, unsigned int hint, unsigned char *init)
26{
27 if (init) {
28 xb->buf = init;
29 xb->dyna = 0;
30 } else {
31 if (hint == 0)
32 hint = BUFSIZ;
33 xb->dyna = 1;
34 xb->buf = N_GNEW(hint, unsigned char);
35 }
36 xb->eptr = xb->buf + hint;
37 xb->ptr = xb->buf;
38 *xb->ptr = '\0';
39}
40
41/* agxbmore;
42 * Expand buffer to hold at least ssz more bytes.
43 */
44int agxbmore(agxbuf * xb, size_t ssz)
45{
46 size_t cnt = 0; /* current no. of characters in buffer */
47 size_t size = 0; /* current buffer size */
48 size_t nsize = 0; /* new buffer size */
49 unsigned char *nbuf; /* new buffer */
50
51 size = (size_t) (xb->eptr - xb->buf);
52 nsize = 2 * size;
53 if (size + ssz > nsize)
54 nsize = size + ssz;
55 cnt = (size_t) (xb->ptr - xb->buf);
56 if (xb->dyna) {
57 nbuf = realloc(xb->buf, nsize);
58 } else {
59 nbuf = N_GNEW(nsize, unsigned char);
60 memcpy(nbuf, xb->buf, cnt);
61 xb->dyna = 1;
62 }
63 xb->buf = nbuf;
64 xb->ptr = xb->buf + cnt;
65 xb->eptr = xb->buf + nsize;
66 return 0;
67}
68
69/* agxbput_n:
70 * Append string s of length n onto xb
71 */
72size_t agxbput_n(agxbuf * xb, const char *s, size_t ssz)
73{
74 if (xb->ptr + ssz > xb->eptr)
75 agxbmore(xb, ssz);
76 memcpy(xb->ptr, s, ssz);
77 xb->ptr += ssz;
78 return ssz;
79}
80
81/* agxbput:
82 * Append string s into xb
83 */
84size_t agxbput(agxbuf * xb, const char *s)
85{
86 size_t ssz = strlen(s);
87
88 return agxbput_n(xb, s, ssz);
89}
90
91/* agxbfree:
92 * Free any malloced resources.
93 */
94void agxbfree(agxbuf * xb)
95{
96 if (xb->dyna)
97 free(xb->buf);
98}
99
100/* agxbpop:
101 * Removes last character added, if any.
102 */
103int agxbpop(agxbuf * xb)
104{
105 int c;
106 if (xb->ptr > xb->buf) {
107 c = *xb->ptr--;
108 return c;
109 } else
110 return -1;
111
112}
113