| /*------------------------------------------------------------------------- |
| * 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); |
| size_t len = 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 += (int)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, (size_t)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; |
| } |