1 /*-------------------------------------------------------------------------
2  * drawElements Memory Pool Library
3  * --------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Memory pool management.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "dePoolStringBuilder.h"
25 
26 #include <string.h>
27 #include <stdarg.h>
28 #include <stdio.h>
29 
30 typedef struct StringBlock_s
31 {
32 	const char*				str;
33 	struct StringBlock_s*	next;
34 } StringBlock;
35 
36 struct dePoolStringBuilder_s
37 {
38 	deMemPool*		pool;
39 	int				length;
40 	StringBlock*	blockListHead;
41 	StringBlock*	blockListTail;
42 };
43 
dePoolStringBuilder_create(deMemPool * pool)44 dePoolStringBuilder* dePoolStringBuilder_create (deMemPool* pool)
45 {
46 	dePoolStringBuilder* builder = DE_POOL_NEW(pool, dePoolStringBuilder);
47 	if (!builder)
48 		return DE_NULL;
49 
50 	builder->pool			= pool;
51 	builder->length			= 0;
52 	builder->blockListHead	= DE_NULL;
53 	builder->blockListTail	= DE_NULL;
54 
55 	return builder;
56 }
57 
dePoolStringBuilder_appendString(dePoolStringBuilder * builder,const char * str)58 deBool dePoolStringBuilder_appendString (dePoolStringBuilder* builder, const char* str)
59 {
60 	StringBlock*	block		= DE_POOL_NEW(builder->pool, StringBlock);
61 	size_t			len			= strlen(str);
62 	char*			blockStr	= (char*)deMemPool_alloc(builder->pool, len + 1);
63 
64 	if (!block || !blockStr)
65 		return DE_FALSE;
66 
67 	/* Initialize block. */
68 	{
69 		char*		d	= blockStr;
70 		const char*	s	= str;
71 		while (*s)
72 			*d++ = *s++;
73 		*d = 0;
74 
75 		block->str	= blockStr;
76 		block->next	= DE_NULL;
77 	}
78 
79 	/* Add block to list. */
80 	if (builder->blockListTail)
81 		builder->blockListTail->next = block;
82 	else
83 		builder->blockListHead = block;
84 
85 	builder->blockListTail = block;
86 
87 	builder->length += (int)len;
88 
89 	return DE_TRUE;
90 }
91 
dePoolStringBuilder_appendFormat(dePoolStringBuilder * builder,const char * format,...)92 deBool dePoolStringBuilder_appendFormat (dePoolStringBuilder* builder, const char* format, ...)
93 {
94 	char	buf[512];
95 	va_list	args;
96 	deBool	ok;
97 
98 	va_start(args, format);
99 	vsnprintf(buf, DE_LENGTH_OF_ARRAY(buf), format, args);
100 	ok = dePoolStringBuilder_appendString(builder, buf);
101 	va_end(args);
102 
103 	return ok;
104 }
105 
106 /* \todo [2009-09-05 petri] Other appends? printf style? */
107 
dePoolStringBuilder_getLength(dePoolStringBuilder * builder)108 int dePoolStringBuilder_getLength (dePoolStringBuilder* builder)
109 {
110 	return builder->length;
111 }
112 
dePoolStringBuilder_dupToString(dePoolStringBuilder * builder)113 char* dePoolStringBuilder_dupToString (dePoolStringBuilder* builder)
114 {
115 	return dePoolStringBuilder_dupToPool(builder, builder->pool);
116 }
117 
dePoolStringBuilder_dupToPool(dePoolStringBuilder * builder,deMemPool * pool)118 char* dePoolStringBuilder_dupToPool (dePoolStringBuilder* builder, deMemPool* pool)
119 {
120 	char* resultStr = (char*)deMemPool_alloc(pool, (size_t)builder->length + 1);
121 
122 	if (resultStr)
123 	{
124 		StringBlock*	block	= builder->blockListHead;
125 		char*			dstPtr	= resultStr;
126 
127 		while (block)
128 		{
129 			const char* p = block->str;
130 			while (*p)
131 				*dstPtr++ = *p++;
132 			block = block->next;
133 		}
134 
135 		*dstPtr++ = 0;
136 
137 		DE_ASSERT((int)strlen(resultStr) == builder->length);
138 	}
139 
140 	return resultStr;
141 }
142