/*------------------------------------------------------------------------- * drawElements Memory Pool Library * -------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Memory pool management. *//*--------------------------------------------------------------------*/ #include "dePoolStringBuilder.h" #include <string.h> #include <stdarg.h> #include <stdio.h> typedef struct StringBlock_s { const char* str; struct StringBlock_s* next; } StringBlock; struct dePoolStringBuilder_s { deMemPool* pool; int length; StringBlock* blockListHead; StringBlock* blockListTail; }; dePoolStringBuilder* dePoolStringBuilder_create (deMemPool* pool) { dePoolStringBuilder* builder = DE_POOL_NEW(pool, dePoolStringBuilder); if (!builder) return DE_NULL; builder->pool = pool; builder->length = 0; builder->blockListHead = DE_NULL; builder->blockListTail = DE_NULL; return builder; } deBool dePoolStringBuilder_appendString (dePoolStringBuilder* builder, const char* str) { StringBlock* block = DE_POOL_NEW(builder->pool, StringBlock); int len = (int)strlen(str); char* blockStr = (char*)deMemPool_alloc(builder->pool, len + 1); if (!block || !blockStr) return DE_FALSE; /* Initialize block. */ { char* d = blockStr; const char* s = str; while (*s) *d++ = *s++; *d = 0; block->str = blockStr; block->next = DE_NULL; } /* Add block to list. */ if (builder->blockListTail) builder->blockListTail->next = block; else builder->blockListHead = block; builder->blockListTail = block; builder->length += len; return DE_TRUE; } deBool dePoolStringBuilder_appendFormat (dePoolStringBuilder* builder, const char* format, ...) { char buf[512]; va_list args; deBool ok; va_start(args, format); vsnprintf(buf, DE_LENGTH_OF_ARRAY(buf), format, args); ok = dePoolStringBuilder_appendString(builder, buf); va_end(args); return ok; } /* \todo [2009-09-05 petri] Other appends? printf style? */ int dePoolStringBuilder_getLength (dePoolStringBuilder* builder) { return builder->length; } char* dePoolStringBuilder_dupToString (dePoolStringBuilder* builder) { return dePoolStringBuilder_dupToPool(builder, builder->pool); } char* dePoolStringBuilder_dupToPool (dePoolStringBuilder* builder, deMemPool* pool) { char* resultStr = (char*)deMemPool_alloc(pool, builder->length + 1); if (resultStr) { StringBlock* block = builder->blockListHead; char* dstPtr = resultStr; while (block) { const char* p = block->str; while (*p) *dstPtr++ = *p++; block = block->next; } *dstPtr++ = 0; DE_ASSERT((int)strlen(resultStr) == builder->length); } return resultStr; }