1
///////////////////////////////////////////////////////////////////////////
3
// Copyright (c) 2000-2003 Intel Corporation
4
// All rights reserved.
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are met:
9
// * Redistributions of source code must retain the above copyright notice,
10
// this list of conditions and the following disclaimer.
11
// * Redistributions in binary form must reproduce the above copyright notice,
12
// this list of conditions and the following disclaimer in the documentation
13
// and/or other materials provided with the distribution.
14
// * Neither name of Intel Corporation nor the names of its contributors
15
// may be used to endorse or promote products derived from this software
16
// without specific prior written permission.
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
22
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
///////////////////////////////////////////////////////////////////////////
32
/************************************************************************
33
* Purpose: This file contains functions that operate on memory and
34
* buffers, allocation, re-allocation, and modification of the memory
35
************************************************************************/
41
#include <membuffer.h>
45
/************************************************************************
47
************************************************************************/
49
/************************************************************************
50
* Function : str_alloc
53
* IN const char* str ; input string object
54
* IN size_t str_len ; input string length
56
* Description : Allocate memory and copy information from the input
57
* string to the newly allocated memory.
60
* Pointer to the newly allocated memory.
61
* NULL if memory cannot be allocated.
64
************************************************************************/
66
str_alloc( IN const char *str,
71
s = ( char * )malloc( str_len + 1 );
73
return NULL; // no mem
76
memcpy( s, str, str_len );
82
/************************************************************************
84
************************************************************************/
86
/************************************************************************
87
* Function : memptr_cmp
90
* IN memptr* m ; input memory object
91
* IN const char* s ; constatnt string for the memory object to be
94
* Description : Compares characters of strings passed for number of
95
* bytes. If equal for the number of bytes, the length of the bytes
96
* determines which buffer is shorter.
99
* < 0 string1 substring less than string2 substring
100
* 0 string1 substring identical to string2 substring
101
* > 0 string1 substring greater than string2 substring
104
************************************************************************/
106
memptr_cmp( IN memptr * m,
111
cmp = strncmp( m->buf, s, m->length );
113
if( cmp == 0 && m->length < strlen( s ) ) {
114
// both strings equal for 'm->length' chars
115
// if m is shorter than s, then s is greater
122
/************************************************************************
123
* Function : memptr_cmp_nocase
126
* IN memptr* m ; input memory object
127
* IN const char* s ; constatnt string for the memory object to be
130
* Description : Compares characters of 2 strings irrespective of the
131
* case for a specific count of bytes If the character comparison
132
* is the same the length of the 2 srings determines the shorter
136
* < 0 string1 substring less than string2 substring
137
* 0 string1 substring identical to string2 substring
138
* > 0 string1 substring greater than string2 substring
141
************************************************************************/
143
memptr_cmp_nocase( IN memptr * m,
148
cmp = strncasecmp( m->buf, s, m->length );
149
if( cmp == 0 && m->length < strlen( s ) ) {
150
// both strings equal for 'm->length' chars
151
// if m is shorter than s, then s is greater
158
/************************************************************************
160
************************************************************************/
162
/************************************************************************
163
* Function : membuffer_initialize
166
* INOUT membuffer* m ; buffer to be initialized
168
* Description : Initialize the buffer
173
************************************************************************/
175
membuffer_initialize( INOUT membuffer * m )
182
/************************************************************************
183
* Function : membuffer_set_size
186
* INOUT membuffer* m ; buffer whose size is to be modified
187
* IN size_t new_length ; new size to which the buffer will be
190
* Description : Increases or decreases buffer cap so that at least
191
* 'new_length' bytes can be stored
194
* UPNP_E_SUCCESS - On Success
195
* UPNP_E_OUTOF_MEMORY - On failure to allocate memory.
198
************************************************************************/
200
membuffer_set_size( INOUT membuffer * m,
201
IN size_t new_length )
207
if( new_length >= m->length ) // increase length
210
if( new_length <= m->capacity ) {
211
return 0; // have enough mem; done
214
diff = new_length - m->length;
215
alloc_len = MAXVAL( m->size_inc, diff ) + m->capacity;
216
} else // decrease length
218
assert( new_length <= m->length );
220
// if diff is 0..m->size_inc, don't free
221
if( ( m->capacity - new_length ) <= m->size_inc ) {
225
alloc_len = new_length + m->size_inc;
228
assert( alloc_len >= new_length );
230
temp_buf = realloc( m->buf, alloc_len + 1 ); //LEAK_FIX_MK
232
//temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );//LEAK_FIX_MK
234
if( temp_buf == NULL ) {
236
alloc_len = new_length;
237
temp_buf = realloc( m->buf, alloc_len + 1 ); //LEAK_FIX_MK
238
//temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );//LEAK_FIX_MK
240
if( temp_buf == NULL ) {
241
return UPNP_E_OUTOF_MEMORY;
246
m->capacity = alloc_len;
250
/************************************************************************
251
* Function : membuffer_init
254
* INOUT membuffer* m ; buffer to be initialized
256
* Description : Wrapper to membuffer_initialize().
257
* Set the size of the buffer to MEMBUF_DEF_SIZE_INC
258
* Initializes m->buf to NULL, length=0
263
************************************************************************/
265
membuffer_init( INOUT membuffer * m )
269
m->size_inc = MEMBUF_DEF_SIZE_INC;
270
membuffer_initialize( m );
273
/************************************************************************
274
* Function : membuffer_destroy
277
* INOUT membuffer* m ; buffer to be destroyed
279
* Description : Free's memory allocated for membuffer* m.
284
************************************************************************/
286
membuffer_destroy( INOUT membuffer * m )
296
/************************************************************************
297
* Function : membuffer_assign
300
* INOUT membuffer* m ; buffer whose memory is to be allocated and
302
* IN const void* buf ; source buffer whose contents will be copied
303
* IN size_t buf_len ; length of the source buffer
305
* Description : Allocate memory to membuffer* m and copy the contents
306
* of the in parameter IN const void* buf.
310
* UPNP_E_OUTOF_MEMORY
313
************************************************************************/
315
membuffer_assign( INOUT membuffer * m,
325
membuffer_destroy( m );
329
return_code = membuffer_set_size( m, buf_len );
330
if( return_code != 0 ) {
335
memcpy( m->buf, buf, buf_len );
336
m->buf[buf_len] = 0; // null-terminate
343
/************************************************************************
344
* Function : membuffer_assign_str
347
* INOUT membuffer* m ; buffer to be allocated and assigned
348
* IN const char* c_str ; source buffer whose contents will be
351
* Description : Wrapper function for membuffer_assign()
355
* UPNP_E_OUTOF_MEMORY
358
************************************************************************/
360
membuffer_assign_str( INOUT membuffer * m,
361
IN const char *c_str )
363
return membuffer_assign( m, c_str, strlen( c_str ) );
366
/************************************************************************
367
* Function : membuffer_append
370
* INOUT membuffer* m ; buffer whose memory is to be appended.
371
* IN const void* buf ; source buffer whose contents will be
373
* IN size_t buf_len ; length of the source buffer
375
* Description : Invokes function to appends data from a constant buffer
381
************************************************************************/
383
membuffer_append( INOUT membuffer * m,
389
return membuffer_insert( m, buf, buf_len, m->length );
392
/************************************************************************
393
* Function : membuffer_append_str
396
* INOUT membuffer* m ; buffer whose memory is to be appended.
397
* IN const char* c_str ; source buffer whose contents will be
400
* Description : Invokes function to appends data from a constant string
406
************************************************************************/
408
membuffer_append_str( INOUT membuffer * m,
409
IN const char *c_str )
411
return membuffer_insert( m, c_str, strlen( c_str ), m->length );
414
/************************************************************************
415
* Function : membuffer_insert
418
* INOUT membuffer* m ; buffer whose memory size is to be increased
420
* IN const void* buf ; source buffer whose contents will be
422
* IN size_t buf_len ; size of the source buffer
423
* int index ; index to determine the bounds while movinf the data
425
* Description : Allocates memory for the new data to be inserted. Does
426
* memory management by moving the data from the existing memory to
427
* the newly allocated memory and then appending the new data.
432
************************************************************************/
434
membuffer_insert( INOUT membuffer * m,
443
if( index < 0 || index > ( int )m->length )
444
return UPNP_E_OUTOF_BOUNDS;
446
if( buf == NULL || buf_len == 0 ) {
450
return_code = membuffer_set_size( m, m->length + buf_len );
451
if( return_code != 0 ) {
456
// move data to right of insertion point
457
memmove( m->buf + index + buf_len, m->buf + index, m->length - index );
458
memcpy( m->buf + index, buf, buf_len );
459
m->length += buf_len;
460
m->buf[m->length] = 0; // null-terminate
465
/************************************************************************
466
* Function : membuffer_delete
469
* INOUT membuffer* m ; buffer whose memory size is to be decreased
470
* and copied to the odified location
471
* IN int index ; index to determine bounds while moving data
472
* IN size_t num_bytes ; number of bytes that the data needs to
475
* Description : Shrink the size of the buffer depending on the current
476
* size of the bufer and te input parameters. Move contents from the
477
* old buffer to the new sized buffer.
482
************************************************************************/
484
membuffer_delete( INOUT membuffer * m,
486
IN size_t num_bytes )
494
if( m->length == 0 ) {
498
assert( index >= 0 && index < ( int )m->length );
500
// shrink count if it goes beyond buffer
501
if( index + num_bytes > m->length ) {
502
num_bytes = m->length - ( size_t ) index;
503
copy_len = 0; // every thing at and after index purged
505
// calc num bytes after deleted string
506
copy_len = m->length - ( index + num_bytes );
509
memmove( m->buf + index, m->buf + index + num_bytes, copy_len );
511
new_length = m->length - num_bytes;
512
return_value = membuffer_set_size( m, new_length ); // trim buffer
513
assert( return_value == 0 ); // shrinking should always work
515
// don't modify until buffer is set
516
m->length = new_length;
517
m->buf[new_length] = 0;
520
/************************************************************************
521
* Function : membuffer_detach
524
* INOUT membuffer* m ; buffer to be returned and updated.
526
* Description : Detaches current buffer and returns it. The caller
527
* must free the returned buffer using free().
528
* After this call, length becomes 0.
531
* a pointer to the current buffer
534
************************************************************************/
536
membuffer_detach( INOUT membuffer * m )
545
membuffer_initialize( m );
550
/************************************************************************
551
* Function : membuffer_attach
554
* INOUT membuffer* m ; buffer to be updated
555
* IN char* new_buf ; source buffer which will be assigned to the
556
* buffer to be updated
557
* IN size_t buf_len ; length of the source buffer
559
* Description : Free existing memory in membuffer and assign the new
560
* buffer in its place.
564
* Note : 'new_buf' must be allocted using malloc or realloc so
565
* that it can be freed using free()
566
************************************************************************/
568
membuffer_attach( INOUT membuffer * m,
574
membuffer_destroy( m );
577
m->capacity = buf_len;