Merge vk-gl-cts/opengl-es-cts-3.2.3 into vk-gl-cts/opengl-es-cts-3.2.4
[platform/upstream/VK-GL-CTS.git] / framework / delibs / depool / dePoolStringBuilder.c
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
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
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
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
108 int dePoolStringBuilder_getLength (dePoolStringBuilder* builder)
109 {
110         return builder->length;
111 }
112
113 char* dePoolStringBuilder_dupToString (dePoolStringBuilder* builder)
114 {
115         return dePoolStringBuilder_dupToPool(builder, builder->pool);
116 }
117
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 }