Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
/***************************************************************************/
2
/*                                                                         */
3
/*  ftutil.c                                                               */
4
/*                                                                         */
5
/*    FreeType utility file for memory and list management (body).         */
6
/*                                                                         */
7
/*  Copyright 2002, 2004-2007, 2013 by                                     */
8
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9
/*                                                                         */
10
/*  This file is part of the FreeType project, and may only be used,       */
11
/*  modified, and distributed under the terms of the FreeType project      */
12
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13
/*  this file you indicate that you have read the license and              */
14
/*  understand and accept it fully.                                        */
15
/*                                                                         */
16
/***************************************************************************/
17
 
18
 
19
#include 
20
#include FT_INTERNAL_DEBUG_H
21
#include FT_INTERNAL_MEMORY_H
22
#include FT_INTERNAL_OBJECTS_H
23
#include FT_LIST_H
24
 
25
 
26
  /*************************************************************************/
27
  /*                                                                       */
28
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
29
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
30
  /* messages during execution.                                            */
31
  /*                                                                       */
32
#undef  FT_COMPONENT
33
#define FT_COMPONENT  trace_memory
34
 
35
 
36
  /*************************************************************************/
37
  /*************************************************************************/
38
  /*************************************************************************/
39
  /*****                                                               *****/
40
  /*****                                                               *****/
41
  /*****               M E M O R Y   M A N A G E M E N T               *****/
42
  /*****                                                               *****/
43
  /*****                                                               *****/
44
  /*************************************************************************/
45
  /*************************************************************************/
46
  /*************************************************************************/
47
 
48
 
49
  FT_BASE_DEF( FT_Pointer )
50
  ft_mem_alloc( FT_Memory  memory,
51
                FT_Long    size,
52
                FT_Error  *p_error )
53
  {
54
    FT_Error    error;
55
    FT_Pointer  block = ft_mem_qalloc( memory, size, &error );
56
 
57
    if ( !error && size > 0 )
58
      FT_MEM_ZERO( block, size );
59
 
60
    *p_error = error;
61
    return block;
62
  }
63
 
64
 
65
  FT_BASE_DEF( FT_Pointer )
66
  ft_mem_qalloc( FT_Memory  memory,
67
                 FT_Long    size,
68
                 FT_Error  *p_error )
69
  {
70
    FT_Error    error = FT_Err_Ok;
71
    FT_Pointer  block = NULL;
72
 
73
 
74
    if ( size > 0 )
75
    {
76
      block = memory->alloc( memory, size );
77
      if ( block == NULL )
78
        error = FT_THROW( Out_Of_Memory );
79
    }
80
    else if ( size < 0 )
81
    {
82
      /* may help catch/prevent security issues */
83
      error = FT_THROW( Invalid_Argument );
84
    }
85
 
86
    *p_error = error;
87
    return block;
88
  }
89
 
90
 
91
  FT_BASE_DEF( FT_Pointer )
92
  ft_mem_realloc( FT_Memory  memory,
93
                  FT_Long    item_size,
94
                  FT_Long    cur_count,
95
                  FT_Long    new_count,
96
                  void*      block,
97
                  FT_Error  *p_error )
98
  {
99
    FT_Error  error = FT_Err_Ok;
100
 
101
 
102
    block = ft_mem_qrealloc( memory, item_size,
103
                             cur_count, new_count, block, &error );
104
    if ( !error && new_count > cur_count )
105
      FT_MEM_ZERO( (char*)block + cur_count * item_size,
106
                   ( new_count - cur_count ) * item_size );
107
 
108
    *p_error = error;
109
    return block;
110
  }
111
 
112
 
113
  FT_BASE_DEF( FT_Pointer )
114
  ft_mem_qrealloc( FT_Memory  memory,
115
                   FT_Long    item_size,
116
                   FT_Long    cur_count,
117
                   FT_Long    new_count,
118
                   void*      block,
119
                   FT_Error  *p_error )
120
  {
121
    FT_Error  error = FT_Err_Ok;
122
 
123
 
124
    /* Note that we now accept `item_size == 0' as a valid parameter, in
125
     * order to cover very weird cases where an ALLOC_MULT macro would be
126
     * called.
127
     */
128
    if ( cur_count < 0 || new_count < 0 || item_size < 0 )
129
    {
130
      /* may help catch/prevent nasty security issues */
131
      error = FT_THROW( Invalid_Argument );
132
    }
133
    else if ( new_count == 0 || item_size == 0 )
134
    {
135
      ft_mem_free( memory, block );
136
      block = NULL;
137
    }
138
    else if ( new_count > FT_INT_MAX/item_size )
139
    {
140
      error = FT_THROW( Array_Too_Large );
141
    }
142
    else if ( cur_count == 0 )
143
    {
144
      FT_ASSERT( block == NULL );
145
 
146
      block = ft_mem_alloc( memory, new_count*item_size, &error );
147
    }
148
    else
149
    {
150
      FT_Pointer  block2;
151
      FT_Long     cur_size = cur_count*item_size;
152
      FT_Long     new_size = new_count*item_size;
153
 
154
 
155
      block2 = memory->realloc( memory, cur_size, new_size, block );
156
      if ( block2 == NULL )
157
        error = FT_THROW( Out_Of_Memory );
158
      else
159
        block = block2;
160
    }
161
 
162
    *p_error = error;
163
    return block;
164
  }
165
 
166
 
167
  FT_BASE_DEF( void )
168
  ft_mem_free( FT_Memory   memory,
169
               const void *P )
170
  {
171
    if ( P )
172
      memory->free( memory, (void*)P );
173
  }
174
 
175
 
176
  FT_BASE_DEF( FT_Pointer )
177
  ft_mem_dup( FT_Memory    memory,
178
              const void*  address,
179
              FT_ULong     size,
180
              FT_Error    *p_error )
181
  {
182
    FT_Error    error;
183
    FT_Pointer  p = ft_mem_qalloc( memory, size, &error );
184
 
185
 
186
    if ( !error && address )
187
      ft_memcpy( p, address, size );
188
 
189
    *p_error = error;
190
    return p;
191
  }
192
 
193
 
194
  FT_BASE_DEF( FT_Pointer )
195
  ft_mem_strdup( FT_Memory    memory,
196
                 const char*  str,
197
                 FT_Error    *p_error )
198
  {
199
    FT_ULong  len = str ? (FT_ULong)ft_strlen( str ) + 1
200
                        : 0;
201
 
202
 
203
    return ft_mem_dup( memory, str, len, p_error );
204
  }
205
 
206
 
207
  FT_BASE_DEF( FT_Int )
208
  ft_mem_strcpyn( char*        dst,
209
                  const char*  src,
210
                  FT_ULong     size )
211
  {
212
    while ( size > 1 && *src != 0 )
213
    {
214
      *dst++ = *src++;
215
      size--;
216
    }
217
 
218
    *dst = 0;  /* always zero-terminate */
219
 
220
    return *src != 0;
221
  }
222
 
223
 
224
  /*************************************************************************/
225
  /*************************************************************************/
226
  /*************************************************************************/
227
  /*****                                                               *****/
228
  /*****                                                               *****/
229
  /*****            D O U B L Y   L I N K E D   L I S T S              *****/
230
  /*****                                                               *****/
231
  /*****                                                               *****/
232
  /*************************************************************************/
233
  /*************************************************************************/
234
  /*************************************************************************/
235
 
236
#undef  FT_COMPONENT
237
#define FT_COMPONENT  trace_list
238
 
239
  /* documentation is in ftlist.h */
240
 
241
  FT_EXPORT_DEF( FT_ListNode )
242
  FT_List_Find( FT_List  list,
243
                void*    data )
244
  {
245
    FT_ListNode  cur;
246
 
247
 
248
    cur = list->head;
249
    while ( cur )
250
    {
251
      if ( cur->data == data )
252
        return cur;
253
 
254
      cur = cur->next;
255
    }
256
 
257
    return (FT_ListNode)0;
258
  }
259
 
260
 
261
  /* documentation is in ftlist.h */
262
 
263
  FT_EXPORT_DEF( void )
264
  FT_List_Add( FT_List      list,
265
               FT_ListNode  node )
266
  {
267
    FT_ListNode  before = list->tail;
268
 
269
 
270
    node->next = 0;
271
    node->prev = before;
272
 
273
    if ( before )
274
      before->next = node;
275
    else
276
      list->head = node;
277
 
278
    list->tail = node;
279
  }
280
 
281
 
282
  /* documentation is in ftlist.h */
283
 
284
  FT_EXPORT_DEF( void )
285
  FT_List_Insert( FT_List      list,
286
                  FT_ListNode  node )
287
  {
288
    FT_ListNode  after = list->head;
289
 
290
 
291
    node->next = after;
292
    node->prev = 0;
293
 
294
    if ( !after )
295
      list->tail = node;
296
    else
297
      after->prev = node;
298
 
299
    list->head = node;
300
  }
301
 
302
 
303
  /* documentation is in ftlist.h */
304
 
305
  FT_EXPORT_DEF( void )
306
  FT_List_Remove( FT_List      list,
307
                  FT_ListNode  node )
308
  {
309
    FT_ListNode  before, after;
310
 
311
 
312
    before = node->prev;
313
    after  = node->next;
314
 
315
    if ( before )
316
      before->next = after;
317
    else
318
      list->head = after;
319
 
320
    if ( after )
321
      after->prev = before;
322
    else
323
      list->tail = before;
324
  }
325
 
326
 
327
  /* documentation is in ftlist.h */
328
 
329
  FT_EXPORT_DEF( void )
330
  FT_List_Up( FT_List      list,
331
              FT_ListNode  node )
332
  {
333
    FT_ListNode  before, after;
334
 
335
 
336
    before = node->prev;
337
    after  = node->next;
338
 
339
    /* check whether we are already on top of the list */
340
    if ( !before )
341
      return;
342
 
343
    before->next = after;
344
 
345
    if ( after )
346
      after->prev = before;
347
    else
348
      list->tail = before;
349
 
350
    node->prev       = 0;
351
    node->next       = list->head;
352
    list->head->prev = node;
353
    list->head       = node;
354
  }
355
 
356
 
357
  /* documentation is in ftlist.h */
358
 
359
  FT_EXPORT_DEF( FT_Error )
360
  FT_List_Iterate( FT_List            list,
361
                   FT_List_Iterator   iterator,
362
                   void*              user )
363
  {
364
    FT_ListNode  cur   = list->head;
365
    FT_Error     error = FT_Err_Ok;
366
 
367
 
368
    while ( cur )
369
    {
370
      FT_ListNode  next = cur->next;
371
 
372
 
373
      error = iterator( cur, user );
374
      if ( error )
375
        break;
376
 
377
      cur = next;
378
    }
379
 
380
    return error;
381
  }
382
 
383
 
384
  /* documentation is in ftlist.h */
385
 
386
  FT_EXPORT_DEF( void )
387
  FT_List_Finalize( FT_List             list,
388
                    FT_List_Destructor  destroy,
389
                    FT_Memory           memory,
390
                    void*               user )
391
  {
392
    FT_ListNode  cur;
393
 
394
 
395
    cur = list->head;
396
    while ( cur )
397
    {
398
      FT_ListNode  next = cur->next;
399
      void*        data = cur->data;
400
 
401
 
402
      if ( destroy )
403
        destroy( memory, data, user );
404
 
405
      FT_FREE( cur );
406
      cur = next;
407
    }
408
 
409
    list->head = 0;
410
    list->tail = 0;
411
  }
412
 
413
 
414
  FT_BASE_DEF( FT_UInt32 )
415
  ft_highpow2( FT_UInt32  value )
416
  {
417
    FT_UInt32  value2;
418
 
419
 
420
    /*
421
     *  We simply clear the lowest bit in each iteration.  When
422
     *  we reach 0, we know that the previous value was our result.
423
     */
424
    for ( ;; )
425
    {
426
      value2 = value & (value - 1);  /* clear lowest bit */
427
      if ( value2 == 0 )
428
        break;
429
 
430
      value = value2;
431
    }
432
    return value;
433
  }
434
 
435
 
436
/* END */