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