Home | History | Annotate | Download | only in depool
      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