~vanvugt/ubuntu/oneiric/mediatomb/fix-770964-784431

« back to all changes in this revision

Viewing changes to tombupnp/upnp/src/genlib/util/membuffer.c

  • Committer: Bazaar Package Importer
  • Author(s): Andres Mejia
  • Date: 2008-02-02 01:42:48 UTC
  • Revision ID: james.westby@ubuntu.com-20080202014248-cjouolddb8gi2zkz
Tags: upstream-0.10.0.dfsg1
ImportĀ upstreamĀ versionĀ 0.10.0.dfsg1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// Copyright (c) 2000-2003 Intel Corporation 
 
4
// All rights reserved. 
 
5
//
 
6
// Redistribution and use in source and binary forms, with or without 
 
7
// modification, are permitted provided that the following conditions are met: 
 
8
//
 
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.
 
17
// 
 
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.
 
29
//
 
30
///////////////////////////////////////////////////////////////////////////
 
31
 
 
32
/************************************************************************
 
33
* Purpose: This file contains functions that operate on memory and 
 
34
*       buffers, allocation, re-allocation, and modification of the memory 
 
35
************************************************************************/
 
36
 
 
37
#include "config.h"
 
38
#include <assert.h>
 
39
#include <stdlib.h>
 
40
#include <string.h>
 
41
#include <membuffer.h>
 
42
#include "upnp.h"
 
43
#include "unixutil.h"
 
44
 
 
45
/************************************************************************
 
46
*                                                                string                                                                 *
 
47
************************************************************************/
 
48
 
 
49
/************************************************************************
 
50
*       Function :      str_alloc
 
51
*
 
52
*       Parameters :
 
53
*               IN const char* str ;    input string object
 
54
*               IN size_t str_len ;             input string length
 
55
*
 
56
*       Description :   Allocate memory and copy information from the input 
 
57
*               string to the newly allocated memory.
 
58
*
 
59
*       Return : char* ;
 
60
*               Pointer to the newly allocated memory.
 
61
*               NULL if memory cannot be allocated.
 
62
*
 
63
*       Note :
 
64
************************************************************************/
 
65
char *
 
66
str_alloc( IN const char *str,
 
67
           IN size_t str_len )
 
68
{
 
69
    char *s;
 
70
 
 
71
    s = ( char * )malloc( str_len + 1 );
 
72
    if( s == NULL ) {
 
73
        return NULL;            // no mem
 
74
    }
 
75
 
 
76
    memcpy( s, str, str_len );
 
77
    s[str_len] = '\0';
 
78
 
 
79
    return s;
 
80
}
 
81
 
 
82
/************************************************************************
 
83
*                                                               memptr                                                                  *
 
84
************************************************************************/
 
85
 
 
86
/************************************************************************
 
87
*       Function :      memptr_cmp
 
88
*
 
89
*       Parameters :
 
90
*               IN memptr* m ;  input memory object
 
91
*               IN const char* s ;      constatnt string for the memory object to be 
 
92
*                                       compared with
 
93
*
 
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.
 
97
*
 
98
*       Return : int ;
 
99
*               < 0 string1 substring less than string2 substring 
 
100
*               0 string1 substring identical to string2 substring 
 
101
*               > 0 string1 substring greater than string2 substring 
 
102
*
 
103
*       Note :
 
104
************************************************************************/
 
105
int
 
106
memptr_cmp( IN memptr * m,
 
107
            IN const char *s )
 
108
{
 
109
    int cmp;
 
110
 
 
111
    cmp = strncmp( m->buf, s, m->length );
 
112
 
 
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
 
116
        return -1;
 
117
    }
 
118
 
 
119
    return cmp;
 
120
}
 
121
 
 
122
/************************************************************************
 
123
*       Function :      memptr_cmp_nocase
 
124
*
 
125
*       Parameters :
 
126
*               IN memptr* m ;  input memory object
 
127
*               IN const char* s ;      constatnt string for the memory object to be 
 
128
*                                       compared with
 
129
*
 
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 
 
133
*               of the 2 strings.
 
134
*
 
135
*       Return : int ;
 
136
*               < 0 string1 substring less than string2 substring 
 
137
*               0 string1 substring identical to string2 substring 
 
138
*               > 0 string1 substring greater than string2 substring 
 
139
*  
 
140
*       Note :
 
141
************************************************************************/
 
142
int
 
143
memptr_cmp_nocase( IN memptr * m,
 
144
                   IN const char *s )
 
145
{
 
146
    int cmp;
 
147
 
 
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
 
152
        return -1;
 
153
    }
 
154
 
 
155
    return cmp;
 
156
}
 
157
 
 
158
/************************************************************************
 
159
*                                                        membuffer                                                                      *
 
160
************************************************************************/
 
161
 
 
162
/************************************************************************
 
163
*       Function :      membuffer_initialize
 
164
*
 
165
*       Parameters :
 
166
*               INOUT membuffer* m ;    buffer to be initialized
 
167
*
 
168
*       Description :   Initialize the buffer
 
169
*
 
170
*       Return : void ;
 
171
*
 
172
*       Note :
 
173
************************************************************************/
 
174
static XINLINE void
 
175
membuffer_initialize( INOUT membuffer * m )
 
176
{
 
177
    m->buf = NULL;
 
178
    m->length = 0;
 
179
    m->capacity = 0;
 
180
}
 
181
 
 
182
/************************************************************************
 
183
*       Function :      membuffer_set_size
 
184
*
 
185
*       Parameters :
 
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 
 
188
*                                       modified
 
189
*
 
190
*       Description : Increases or decreases buffer cap so that at least
 
191
*          'new_length' bytes can be stored
 
192
*
 
193
*       Return : int ;
 
194
*               UPNP_E_SUCCESS - On Success
 
195
*               UPNP_E_OUTOF_MEMORY - On failure to allocate memory.
 
196
*
 
197
*       Note :
 
198
************************************************************************/
 
199
int
 
200
membuffer_set_size( INOUT membuffer * m,
 
201
                    IN size_t new_length )
 
202
{
 
203
    size_t diff;
 
204
    size_t alloc_len;
 
205
    char *temp_buf;
 
206
 
 
207
    if( new_length >= m->length )   // increase length
 
208
    {
 
209
        // need more mem?
 
210
        if( new_length <= m->capacity ) {
 
211
            return 0;           // have enough mem; done
 
212
        }
 
213
 
 
214
        diff = new_length - m->length;
 
215
        alloc_len = MAXVAL( m->size_inc, diff ) + m->capacity;
 
216
    } else                      // decrease length
 
217
    {
 
218
        assert( new_length <= m->length );
 
219
 
 
220
        // if diff is 0..m->size_inc, don't free
 
221
        if( ( m->capacity - new_length ) <= m->size_inc ) {
 
222
            return 0;
 
223
        }
 
224
 
 
225
        alloc_len = new_length + m->size_inc;
 
226
    }
 
227
 
 
228
    assert( alloc_len >= new_length );
 
229
 
 
230
    temp_buf = realloc( m->buf, alloc_len + 1 );    //LEAK_FIX_MK
 
231
 
 
232
    //temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );//LEAK_FIX_MK
 
233
 
 
234
    if( temp_buf == NULL ) {
 
235
        // try smaller size
 
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
 
239
 
 
240
        if( temp_buf == NULL ) {
 
241
            return UPNP_E_OUTOF_MEMORY;
 
242
        }
 
243
    }
 
244
    // save
 
245
    m->buf = temp_buf;
 
246
    m->capacity = alloc_len;
 
247
    return 0;
 
248
}
 
249
 
 
250
/************************************************************************
 
251
*       Function :      membuffer_init
 
252
*
 
253
*       Parameters :
 
254
*               INOUT membuffer* m ; buffer     to be initialized
 
255
*
 
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
 
259
*
 
260
*       Return : void ;
 
261
*
 
262
*       Note :
 
263
************************************************************************/
 
264
void
 
265
membuffer_init( INOUT membuffer * m )
 
266
{
 
267
    assert( m != NULL );
 
268
 
 
269
    m->size_inc = MEMBUF_DEF_SIZE_INC;
 
270
    membuffer_initialize( m );
 
271
}
 
272
 
 
273
/************************************************************************
 
274
*       Function :      membuffer_destroy
 
275
*
 
276
*       Parameters :
 
277
*               INOUT membuffer* m ;    buffer to be destroyed
 
278
*
 
279
*       Description : Free's memory allocated for membuffer* m.
 
280
*
 
281
*       Return : void ;
 
282
*
 
283
*       Note :
 
284
************************************************************************/
 
285
void
 
286
membuffer_destroy( INOUT membuffer * m )
 
287
{
 
288
    if( m == NULL ) {
 
289
        return;
 
290
    }
 
291
 
 
292
    free( m->buf );
 
293
    membuffer_init( m );
 
294
}
 
295
 
 
296
/************************************************************************
 
297
*       Function :      membuffer_assign
 
298
*
 
299
*       Parameters :
 
300
*               INOUT membuffer* m ; buffer whose memory is to be allocated and 
 
301
*                                       assigned.
 
302
*               IN const void* buf ; source buffer whose contents will be copied
 
303
*               IN size_t buf_len ;      length of the source buffer
 
304
*
 
305
*       Description : Allocate memory to membuffer* m and copy the contents 
 
306
*               of the in parameter IN const void* buf.
 
307
*
 
308
*       Return : int ;
 
309
*        UPNP_E_SUCCESS
 
310
*        UPNP_E_OUTOF_MEMORY
 
311
*
 
312
*       Note :
 
313
************************************************************************/
 
314
int
 
315
membuffer_assign( INOUT membuffer * m,
 
316
                  IN const void *buf,
 
317
                  IN size_t buf_len )
 
318
{
 
319
    int return_code;
 
320
 
 
321
    assert( m != NULL );
 
322
 
 
323
    // set value to null
 
324
    if( buf == NULL ) {
 
325
        membuffer_destroy( m );
 
326
        return 0;
 
327
    }
 
328
    // alloc mem
 
329
    return_code = membuffer_set_size( m, buf_len );
 
330
    if( return_code != 0 ) {
 
331
        return return_code;
 
332
    }
 
333
    // copy
 
334
    if( buf_len ) {
 
335
        memcpy( m->buf, buf, buf_len );
 
336
        m->buf[buf_len] = 0;        // null-terminate
 
337
    }
 
338
    m->length = buf_len;
 
339
 
 
340
    return 0;
 
341
}
 
342
 
 
343
/************************************************************************
 
344
*       Function :      membuffer_assign_str
 
345
*
 
346
*       Parameters :
 
347
*               INOUT membuffer* m ;    buffer to be allocated and assigned
 
348
*               IN const char* c_str ;  source buffer whose contents will be 
 
349
*                                       copied
 
350
*
 
351
*       Description : Wrapper function for membuffer_assign()
 
352
*
 
353
*       Return : int ;
 
354
*        UPNP_E_SUCCESS
 
355
*        UPNP_E_OUTOF_MEMORY
 
356
*
 
357
*       Note :
 
358
************************************************************************/
 
359
int
 
360
membuffer_assign_str( INOUT membuffer * m,
 
361
                      IN const char *c_str )
 
362
{
 
363
    return membuffer_assign( m, c_str, strlen( c_str ) );
 
364
}
 
365
 
 
366
/************************************************************************
 
367
*       Function :      membuffer_append
 
368
*
 
369
*       Parameters :
 
370
*               INOUT membuffer* m ; buffer whose memory is to be appended.
 
371
*               IN const void* buf ; source buffer whose contents will be 
 
372
*                                       copied
 
373
*               IN size_t buf_len ;     length of the source buffer
 
374
*
 
375
*       Description : Invokes function to appends data from a constant buffer 
 
376
*               to the buffer 
 
377
*
 
378
*       Return : int ;
 
379
*
 
380
*       Note :
 
381
************************************************************************/
 
382
int
 
383
membuffer_append( INOUT membuffer * m,
 
384
                  IN const void *buf,
 
385
                  IN size_t buf_len )
 
386
{
 
387
    assert( m != NULL );
 
388
 
 
389
    return membuffer_insert( m, buf, buf_len, m->length );
 
390
}
 
391
 
 
392
/************************************************************************
 
393
*       Function :      membuffer_append_str
 
394
*
 
395
*       Parameters :
 
396
*               INOUT membuffer* m ;    buffer whose memory is to be appended.
 
397
*               IN const char* c_str ;  source buffer whose contents will be 
 
398
*                                       copied
 
399
*
 
400
*       Description : Invokes function to appends data from a constant string 
 
401
*               to the buffer   
 
402
*
 
403
*       Return : int ;
 
404
*
 
405
*       Note :
 
406
************************************************************************/
 
407
int
 
408
membuffer_append_str( INOUT membuffer * m,
 
409
                      IN const char *c_str )
 
410
{
 
411
    return membuffer_insert( m, c_str, strlen( c_str ), m->length );
 
412
}
 
413
 
 
414
/************************************************************************
 
415
*       Function :      membuffer_insert
 
416
*
 
417
*       Parameters :
 
418
*               INOUT membuffer* m ; buffer whose memory size is to be increased  
 
419
*                                       and appended.
 
420
*               IN const void* buf ; source buffer whose contents will be 
 
421
*                                       copied
 
422
*                IN size_t buf_len ; size of the source buffer
 
423
*               int index ;     index to determine the bounds while movinf the data
 
424
*
 
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.
 
428
*
 
429
*       Return : int ;
 
430
*
 
431
*       Note :
 
432
************************************************************************/
 
433
int
 
434
membuffer_insert( INOUT membuffer * m,
 
435
                  IN const void *buf,
 
436
                  IN size_t buf_len,
 
437
                  int index )
 
438
{
 
439
    int return_code;
 
440
 
 
441
    assert( m != NULL );
 
442
 
 
443
    if( index < 0 || index > ( int )m->length )
 
444
        return UPNP_E_OUTOF_BOUNDS;
 
445
 
 
446
    if( buf == NULL || buf_len == 0 ) {
 
447
        return 0;
 
448
    }
 
449
    // alloc mem
 
450
    return_code = membuffer_set_size( m, m->length + buf_len );
 
451
    if( return_code != 0 ) {
 
452
        return return_code;
 
453
    }
 
454
    // insert data
 
455
 
 
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
 
461
 
 
462
    return 0;
 
463
}
 
464
 
 
465
/************************************************************************
 
466
*       Function :      membuffer_delete
 
467
*
 
468
*       Parameters :
 
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 
 
473
*                                       shrink by
 
474
*
 
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.
 
478
*
 
479
*       Return : void ;
 
480
*
 
481
*       Note :
 
482
************************************************************************/
 
483
void
 
484
membuffer_delete( INOUT membuffer * m,
 
485
                  IN int index,
 
486
                  IN size_t num_bytes )
 
487
{
 
488
    int return_value;
 
489
    int new_length;
 
490
    size_t copy_len;
 
491
 
 
492
    assert( m != NULL );
 
493
 
 
494
    if( m->length == 0 ) {
 
495
        return;
 
496
    }
 
497
 
 
498
    assert( index >= 0 && index < ( int )m->length );
 
499
 
 
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
 
504
    } else {
 
505
        // calc num bytes after deleted string
 
506
        copy_len = m->length - ( index + num_bytes );
 
507
    }
 
508
 
 
509
    memmove( m->buf + index, m->buf + index + num_bytes, copy_len );
 
510
 
 
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
 
514
 
 
515
    // don't modify until buffer is set
 
516
    m->length = new_length;
 
517
    m->buf[new_length] = 0;
 
518
}
 
519
 
 
520
/************************************************************************
 
521
*       Function :      membuffer_detach
 
522
*
 
523
*       Parameters :
 
524
*               INOUT membuffer* m ; buffer to be returned and updated. 
 
525
*
 
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.
 
529
*
 
530
*       Return : char* ;
 
531
*               a pointer to the current buffer
 
532
*
 
533
*       Note :
 
534
************************************************************************/
 
535
char *
 
536
membuffer_detach( INOUT membuffer * m )
 
537
{
 
538
    char *buf;
 
539
 
 
540
    assert( m != NULL );
 
541
 
 
542
    buf = m->buf;
 
543
 
 
544
    // free all
 
545
    membuffer_initialize( m );
 
546
 
 
547
    return buf;
 
548
}
 
549
 
 
550
/************************************************************************
 
551
*       Function :      membuffer_attach
 
552
*
 
553
*       Parameters :
 
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 
 
558
*
 
559
*       Description : Free existing memory in membuffer and assign the new 
 
560
*               buffer in its place.
 
561
*
 
562
*       Return : void ;
 
563
*
 
564
*       Note : 'new_buf' must be allocted using malloc or realloc so
 
565
*               that it can be freed using free()
 
566
************************************************************************/
 
567
void
 
568
membuffer_attach( INOUT membuffer * m,
 
569
                  IN char *new_buf,
 
570
                  IN size_t buf_len )
 
571
{
 
572
    assert( m != NULL );
 
573
 
 
574
    membuffer_destroy( m );
 
575
    m->buf = new_buf;
 
576
    m->length = buf_len;
 
577
    m->capacity = buf_len;
 
578
}