xref: /aosp_15_r20/external/deqp/framework/delibs/depool/dePoolStringBuilder.c (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 bool 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 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 true;
90 }
91 
dePoolStringBuilder_appendFormat(dePoolStringBuilder * builder,const char * format,...)92 bool dePoolStringBuilder_appendFormat(dePoolStringBuilder *builder, const char *format, ...)
93 {
94     char buf[512];
95     va_list args;
96     bool 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