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 } 142