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 30typedef struct StringBlock_s 31{ 32 const char* str; 33 struct StringBlock_s* next; 34} StringBlock; 35 36struct dePoolStringBuilder_s 37{ 38 deMemPool* pool; 39 int length; 40 StringBlock* blockListHead; 41 StringBlock* blockListTail; 42}; 43 44dePoolStringBuilder* 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 58deBool dePoolStringBuilder_appendString (dePoolStringBuilder* builder, const char* str) 59{ 60 StringBlock* block = DE_POOL_NEW(builder->pool, StringBlock); 61 int len = (int)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 += len; 88 89 return DE_TRUE; 90} 91 92deBool 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 108int dePoolStringBuilder_getLength (dePoolStringBuilder* builder) 109{ 110 return builder->length; 111} 112 113char* dePoolStringBuilder_dupToString (dePoolStringBuilder* builder) 114{ 115 return dePoolStringBuilder_dupToPool(builder, builder->pool); 116} 117 118char* dePoolStringBuilder_dupToPool (dePoolStringBuilder* builder, deMemPool* pool) 119{ 120 char* resultStr = (char*)deMemPool_alloc(pool, 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