~etc-pgh-launchpad/wildpockets/trunk

« back to all changes in this revision

Viewing changes to freetype2/src/base/ftrfork.c

  • Committer: etc-pgh-launchpad at cmu
  • Date: 2010-11-30 20:56:30 UTC
  • Revision ID: etc-pgh-launchpad@lists.andrew.cmu.edu-20101130205630-0blbkcz28ovjl8wj
Committing the Wild Pockets code base to Launchpad.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  ftrfork.c                                                              */
 
4
/*                                                                         */
 
5
/*    Embedded resource forks accessor (body).                             */
 
6
/*                                                                         */
 
7
/*  Copyright 2004, 2005, 2006, 2007 by                                    */
 
8
/*  Masatake YAMATO and Redhat K.K.                                        */
 
9
/*                                                                         */
 
10
/*  FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are     */
 
11
/*  derived from ftobjs.c.                                                 */
 
12
/*                                                                         */
 
13
/*  This file is part of the FreeType project, and may only be used,       */
 
14
/*  modified, and distributed under the terms of the FreeType project      */
 
15
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
 
16
/*  this file you indicate that you have read the license and              */
 
17
/*  understand and accept it fully.                                        */
 
18
/*                                                                         */
 
19
/***************************************************************************/
 
20
 
 
21
/***************************************************************************/
 
22
/* Development of the code in this file is support of                      */
 
23
/* Information-technology Promotion Agency, Japan.                         */
 
24
/***************************************************************************/
 
25
 
 
26
 
 
27
#include <ft2build.h>
 
28
#include FT_INTERNAL_DEBUG_H
 
29
#include FT_INTERNAL_STREAM_H
 
30
#include FT_INTERNAL_RFORK_H
 
31
 
 
32
 
 
33
#undef  FT_COMPONENT
 
34
#define FT_COMPONENT  trace_raccess
 
35
 
 
36
 
 
37
  /*************************************************************************/
 
38
  /*************************************************************************/
 
39
  /*************************************************************************/
 
40
  /****                                                                 ****/
 
41
  /****                                                                 ****/
 
42
  /****               Resource fork directory access                    ****/
 
43
  /****                                                                 ****/
 
44
  /****                                                                 ****/
 
45
  /*************************************************************************/
 
46
  /*************************************************************************/
 
47
  /*************************************************************************/
 
48
 
 
49
  FT_BASE_DEF( FT_Error )
 
50
  FT_Raccess_Get_HeaderInfo( FT_Library  library,
 
51
                             FT_Stream   stream,
 
52
                             FT_Long     rfork_offset,
 
53
                             FT_Long    *map_offset,
 
54
                             FT_Long    *rdata_pos )
 
55
  {
 
56
    FT_Error       error;
 
57
    unsigned char  head[16], head2[16];
 
58
    FT_Long        map_pos, rdata_len;
 
59
    int            allzeros, allmatch, i;
 
60
    FT_Long        type_list;
 
61
 
 
62
    FT_UNUSED( library );
 
63
 
 
64
 
 
65
    error = FT_Stream_Seek( stream, rfork_offset );
 
66
    if ( error )
 
67
      return error;
 
68
 
 
69
    error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
 
70
    if ( error )
 
71
      return error;
 
72
 
 
73
    *rdata_pos = rfork_offset + ( ( head[0] << 24 ) |
 
74
                                  ( head[1] << 16 ) |
 
75
                                  ( head[2] <<  8 ) |
 
76
                                    head[3]         );
 
77
    map_pos    = rfork_offset + ( ( head[4] << 24 ) |
 
78
                                  ( head[5] << 16 ) |
 
79
                                  ( head[6] <<  8 ) |
 
80
                                    head[7]         );
 
81
    rdata_len = ( head[ 8] << 24 ) |
 
82
                ( head[ 9] << 16 ) |
 
83
                ( head[10] <<  8 ) |
 
84
                  head[11];
 
85
 
 
86
    /* map_len = head[12] .. head[15] */
 
87
 
 
88
    if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset )
 
89
      return FT_Err_Unknown_File_Format;
 
90
 
 
91
    error = FT_Stream_Seek( stream, map_pos );
 
92
    if ( error )
 
93
      return error;
 
94
 
 
95
    head2[15] = (FT_Byte)( head[15] + 1 );       /* make it be different */
 
96
 
 
97
    error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
 
98
    if ( error )
 
99
      return error;
 
100
 
 
101
    allzeros = 1;
 
102
    allmatch = 1;
 
103
    for ( i = 0; i < 16; ++i )
 
104
    {
 
105
      if ( head2[i] != 0 )
 
106
        allzeros = 0;
 
107
      if ( head2[i] != head[i] )
 
108
        allmatch = 0;
 
109
    }
 
110
    if ( !allzeros && !allmatch )
 
111
      return FT_Err_Unknown_File_Format;
 
112
 
 
113
    /* If we have reached this point then it is probably a mac resource */
 
114
    /* file.  Now, does it contain any interesting resources?           */
 
115
    /* Skip handle to next resource map, the file resource number, and  */
 
116
    /* attributes.                                                      */
 
117
    (void)FT_STREAM_SKIP( 4        /* skip handle to next resource map */
 
118
                          + 2      /* skip file resource number */
 
119
                          + 2 );   /* skip attributes */
 
120
 
 
121
    if ( FT_READ_USHORT( type_list ) )
 
122
      return error;
 
123
    if ( type_list == -1 )
 
124
      return FT_Err_Unknown_File_Format;
 
125
 
 
126
    error = FT_Stream_Seek( stream, map_pos + type_list );
 
127
    if ( error )
 
128
      return error;
 
129
 
 
130
    *map_offset = map_pos + type_list;
 
131
    return FT_Err_Ok;
 
132
  }
 
133
 
 
134
 
 
135
  static int
 
136
  ft_raccess_sort_ref_by_id( FT_RFork_Ref*  a,
 
137
                             FT_RFork_Ref*  b )
 
138
  {
 
139
    if ( a->res_id < b->res_id )
 
140
      return -1;
 
141
    else if ( a->res_id > b->res_id )
 
142
      return 1;
 
143
    else
 
144
      return 0;
 
145
  }
 
146
 
 
147
 
 
148
  FT_BASE_DEF( FT_Error )
 
149
  FT_Raccess_Get_DataOffsets( FT_Library  library,
 
150
                              FT_Stream   stream,
 
151
                              FT_Long     map_offset,
 
152
                              FT_Long     rdata_pos,
 
153
                              FT_Long     tag,
 
154
                              FT_Long   **offsets,
 
155
                              FT_Long    *count )
 
156
  {
 
157
    FT_Error      error;
 
158
    int           i, j, cnt, subcnt;
 
159
    FT_Long       tag_internal, rpos;
 
160
    FT_Memory     memory = library->memory;
 
161
    FT_Long       temp;
 
162
    FT_Long       *offsets_internal;
 
163
    FT_RFork_Ref  *ref;
 
164
 
 
165
 
 
166
    error = FT_Stream_Seek( stream, map_offset );
 
167
    if ( error )
 
168
      return error;
 
169
 
 
170
    if ( FT_READ_USHORT( cnt ) )
 
171
      return error;
 
172
    cnt++;
 
173
 
 
174
    for ( i = 0; i < cnt; ++i )
 
175
    {
 
176
      if ( FT_READ_LONG( tag_internal ) ||
 
177
           FT_READ_USHORT( subcnt )     ||
 
178
           FT_READ_USHORT( rpos )       )
 
179
        return error;
 
180
 
 
181
      FT_TRACE2(( "Resource tags: %c%c%c%c\n",
 
182
                  (char)( 0xff & ( tag_internal >> 24 ) ),
 
183
                  (char)( 0xff & ( tag_internal >> 16 ) ),
 
184
                  (char)( 0xff & ( tag_internal >>  8 ) ),
 
185
                  (char)( 0xff & ( tag_internal >>  0 ) ) ));
 
186
 
 
187
      if ( tag_internal == tag )
 
188
      {
 
189
        *count = subcnt + 1;
 
190
        rpos  += map_offset;
 
191
 
 
192
        error = FT_Stream_Seek( stream, rpos );
 
193
        if ( error )
 
194
          return error;
 
195
 
 
196
        if ( FT_NEW_ARRAY( ref, *count ) )
 
197
          return error;
 
198
 
 
199
        for ( j = 0; j < *count; ++j )
 
200
        {
 
201
          if ( FT_READ_USHORT( ref[j].res_id ) )
 
202
            goto Exit;
 
203
          if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
 
204
            goto Exit;
 
205
          if ( FT_READ_LONG( temp ) )
 
206
            goto Exit;
 
207
          if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
 
208
            goto Exit;
 
209
 
 
210
          ref[j].offset = temp & 0xFFFFFFL;
 
211
        }
 
212
 
 
213
        ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),
 
214
                  ( int(*)(const void*, const void*) )
 
215
                  ft_raccess_sort_ref_by_id );
 
216
 
 
217
        if ( FT_NEW_ARRAY( offsets_internal, *count ) )
 
218
          goto Exit;
 
219
 
 
220
        /* XXX: duplicated reference ID,
 
221
         *      gap between reference IDs are acceptable?
 
222
         *      further investigation on Apple implementation is needed.
 
223
         */
 
224
        for ( j = 0; j < *count; ++j )
 
225
          offsets_internal[j] = rdata_pos + ref[j].offset;
 
226
 
 
227
        *offsets = offsets_internal;
 
228
        error    = FT_Err_Ok;
 
229
 
 
230
      Exit:
 
231
        FT_FREE( ref );
 
232
        return error;
 
233
      }
 
234
    }
 
235
 
 
236
    return FT_Err_Cannot_Open_Resource;
 
237
  }
 
238
 
 
239
 
 
240
#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
 
241
 
 
242
  /*************************************************************************/
 
243
  /*************************************************************************/
 
244
  /*************************************************************************/
 
245
  /****                                                                 ****/
 
246
  /****                                                                 ****/
 
247
  /****                     Guessing functions                          ****/
 
248
  /****                                                                 ****/
 
249
  /****            When you add a new guessing function,                ****/
 
250
  /****           update FT_RACCESS_N_RULES in ftrfork.h.               ****/
 
251
  /****                                                                 ****/
 
252
  /*************************************************************************/
 
253
  /*************************************************************************/
 
254
  /*************************************************************************/
 
255
 
 
256
  typedef FT_Error
 
257
  (*raccess_guess_func)( FT_Library  library,
 
258
                         FT_Stream   stream,
 
259
                         char       *base_file_name,
 
260
                         char      **result_file_name,
 
261
                         FT_Long    *result_offset );
 
262
 
 
263
 
 
264
  static FT_Error
 
265
  raccess_guess_apple_double( FT_Library  library,
 
266
                              FT_Stream   stream,
 
267
                              char       *base_file_name,
 
268
                              char      **result_file_name,
 
269
                              FT_Long    *result_offset );
 
270
 
 
271
  static FT_Error
 
272
  raccess_guess_apple_single( FT_Library  library,
 
273
                              FT_Stream   stream,
 
274
                              char       *base_file_name,
 
275
                              char      **result_file_name,
 
276
                              FT_Long    *result_offset );
 
277
 
 
278
  static FT_Error
 
279
  raccess_guess_darwin_ufs_export( FT_Library  library,
 
280
                                   FT_Stream   stream,
 
281
                                   char       *base_file_name,
 
282
                                   char      **result_file_name,
 
283
                                   FT_Long    *result_offset );
 
284
 
 
285
  static FT_Error
 
286
  raccess_guess_darwin_newvfs( FT_Library  library,
 
287
                               FT_Stream   stream,
 
288
                               char       *base_file_name,
 
289
                               char      **result_file_name,
 
290
                               FT_Long    *result_offset );
 
291
 
 
292
  static FT_Error
 
293
  raccess_guess_darwin_hfsplus( FT_Library  library,
 
294
                                FT_Stream   stream,
 
295
                                char       *base_file_name,
 
296
                                char      **result_file_name,
 
297
                                FT_Long    *result_offset );
 
298
 
 
299
  static FT_Error
 
300
  raccess_guess_vfat( FT_Library  library,
 
301
                      FT_Stream   stream,
 
302
                      char       *base_file_name,
 
303
                      char      **result_file_name,
 
304
                      FT_Long    *result_offset );
 
305
 
 
306
  static FT_Error
 
307
  raccess_guess_linux_cap( FT_Library  library,
 
308
                           FT_Stream   stream,
 
309
                           char       *base_file_name,
 
310
                           char      **result_file_name,
 
311
                           FT_Long    *result_offset );
 
312
 
 
313
  static FT_Error
 
314
  raccess_guess_linux_double( FT_Library  library,
 
315
                              FT_Stream   stream,
 
316
                              char       *base_file_name,
 
317
                              char      **result_file_name,
 
318
                              FT_Long    *result_offset );
 
319
 
 
320
  static FT_Error
 
321
  raccess_guess_linux_netatalk( FT_Library  library,
 
322
                                FT_Stream   stream,
 
323
                                char       *base_file_name,
 
324
                                char      **result_file_name,
 
325
                                FT_Long    *result_offset );
 
326
 
 
327
 
 
328
  /*************************************************************************/
 
329
  /****                                                                 ****/
 
330
  /****                       Helper functions                          ****/
 
331
  /****                                                                 ****/
 
332
  /*************************************************************************/
 
333
 
 
334
  static FT_Error
 
335
  raccess_guess_apple_generic( FT_Library  library,
 
336
                               FT_Stream   stream,
 
337
                               char       *base_file_name,
 
338
                               FT_Int32    magic,
 
339
                               FT_Long    *result_offset );
 
340
 
 
341
  static FT_Error
 
342
  raccess_guess_linux_double_from_file_name( FT_Library  library,
 
343
                                             char *      file_name,
 
344
                                             FT_Long    *result_offset );
 
345
 
 
346
  static char *
 
347
  raccess_make_file_name( FT_Memory    memory,
 
348
                          const char  *original_name,
 
349
                          const char  *insertion );
 
350
 
 
351
 
 
352
  FT_BASE_DEF( void )
 
353
  FT_Raccess_Guess( FT_Library  library,
 
354
                    FT_Stream   stream,
 
355
                    char*       base_name,
 
356
                    char      **new_names,
 
357
                    FT_Long    *offsets,
 
358
                    FT_Error   *errors )
 
359
  {
 
360
    FT_Long  i;
 
361
 
 
362
 
 
363
    raccess_guess_func  funcs[FT_RACCESS_N_RULES] =
 
364
    {
 
365
      raccess_guess_apple_double,
 
366
      raccess_guess_apple_single,
 
367
      raccess_guess_darwin_ufs_export,
 
368
      raccess_guess_darwin_newvfs,
 
369
      raccess_guess_darwin_hfsplus,
 
370
      raccess_guess_vfat,
 
371
      raccess_guess_linux_cap,
 
372
      raccess_guess_linux_double,
 
373
      raccess_guess_linux_netatalk,
 
374
    };
 
375
 
 
376
    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
 
377
    {
 
378
      new_names[i] = NULL;
 
379
      if ( NULL != stream )
 
380
        errors[i] = FT_Stream_Seek( stream, 0 );
 
381
      else
 
382
        errors[i] = FT_Err_Ok;
 
383
 
 
384
      if ( errors[i] )
 
385
        continue ;
 
386
 
 
387
      errors[i] = (funcs[i])( library, stream, base_name,
 
388
                              &(new_names[i]), &(offsets[i]) );
 
389
    }
 
390
 
 
391
    return;
 
392
  }
 
393
 
 
394
 
 
395
  static FT_Error
 
396
  raccess_guess_apple_double( FT_Library  library,
 
397
                              FT_Stream   stream,
 
398
                              char       *base_file_name,
 
399
                              char      **result_file_name,
 
400
                              FT_Long    *result_offset )
 
401
  {
 
402
    FT_Int32  magic = ( 0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x07 );
 
403
 
 
404
 
 
405
    *result_file_name = NULL;
 
406
    if ( NULL == stream )
 
407
      return FT_Err_Cannot_Open_Stream;
 
408
 
 
409
    return raccess_guess_apple_generic( library, stream, base_file_name,
 
410
                                        magic, result_offset );
 
411
  }
 
412
 
 
413
 
 
414
  static FT_Error
 
415
  raccess_guess_apple_single( FT_Library  library,
 
416
                              FT_Stream   stream,
 
417
                              char       *base_file_name,
 
418
                              char      **result_file_name,
 
419
                              FT_Long    *result_offset )
 
420
  {
 
421
    FT_Int32  magic = (0x00 << 24 | 0x05 << 16 | 0x16 << 8 | 0x00);
 
422
 
 
423
 
 
424
    *result_file_name = NULL;
 
425
    if ( NULL == stream )
 
426
      return FT_Err_Cannot_Open_Stream;
 
427
 
 
428
    return raccess_guess_apple_generic( library, stream, base_file_name,
 
429
                                        magic, result_offset );
 
430
  }
 
431
 
 
432
 
 
433
  static FT_Error
 
434
  raccess_guess_darwin_ufs_export( FT_Library  library,
 
435
                                   FT_Stream   stream,
 
436
                                   char       *base_file_name,
 
437
                                   char      **result_file_name,
 
438
                                   FT_Long    *result_offset )
 
439
  {
 
440
    char*      newpath;
 
441
    FT_Error   error;
 
442
    FT_Memory  memory;
 
443
 
 
444
    FT_UNUSED( stream );
 
445
 
 
446
 
 
447
    memory  = library->memory;
 
448
    newpath = raccess_make_file_name( memory, base_file_name, "._" );
 
449
    if ( !newpath )
 
450
      return FT_Err_Out_Of_Memory;
 
451
 
 
452
    error = raccess_guess_linux_double_from_file_name( library, newpath,
 
453
                                                       result_offset );
 
454
    if ( !error )
 
455
      *result_file_name = newpath;
 
456
    else
 
457
      FT_FREE( newpath );
 
458
 
 
459
    return error;
 
460
  }
 
461
 
 
462
 
 
463
  static FT_Error
 
464
  raccess_guess_darwin_hfsplus( FT_Library  library,
 
465
                                FT_Stream   stream,
 
466
                                char       *base_file_name,
 
467
                                char      **result_file_name,
 
468
                                FT_Long    *result_offset )
 
469
  {
 
470
    /*
 
471
      Only meaningful on systems with hfs+ drivers (or Macs).
 
472
     */
 
473
    FT_Error   error;
 
474
    char*      newpath;
 
475
    FT_Memory  memory;
 
476
    FT_Long    base_file_len = ft_strlen( base_file_name );
 
477
 
 
478
    FT_UNUSED( stream );
 
479
 
 
480
 
 
481
    memory = library->memory;
 
482
 
 
483
    if ( base_file_len + 6 > FT_INT_MAX )
 
484
      return FT_Err_Array_Too_Large;
 
485
 
 
486
    if ( FT_ALLOC( newpath, base_file_len + 6 ) )
 
487
      return error;
 
488
 
 
489
    FT_MEM_COPY( newpath, base_file_name, base_file_len );
 
490
    FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
 
491
 
 
492
    *result_file_name = newpath;
 
493
    *result_offset    = 0;
 
494
 
 
495
    return FT_Err_Ok;
 
496
  }
 
497
 
 
498
 
 
499
  static FT_Error
 
500
  raccess_guess_darwin_newvfs( FT_Library  library,
 
501
                               FT_Stream   stream,
 
502
                               char       *base_file_name,
 
503
                               char      **result_file_name,
 
504
                               FT_Long    *result_offset )
 
505
  {
 
506
    /*
 
507
      Only meaningful on systems with Mac OS X (> 10.1).
 
508
     */
 
509
    FT_Error   error;
 
510
    char*      newpath;
 
511
    FT_Memory  memory;
 
512
    FT_Long    base_file_len = ft_strlen( base_file_name );
 
513
 
 
514
    FT_UNUSED( stream );
 
515
 
 
516
 
 
517
    memory = library->memory;
 
518
 
 
519
    if ( base_file_len + 18 > FT_INT_MAX )
 
520
      return FT_Err_Array_Too_Large;
 
521
 
 
522
    if ( FT_ALLOC( newpath, base_file_len + 18 ) )
 
523
      return error;
 
524
 
 
525
    FT_MEM_COPY( newpath, base_file_name, base_file_len );
 
526
    FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );
 
527
 
 
528
    *result_file_name = newpath;
 
529
    *result_offset    = 0;
 
530
 
 
531
    return FT_Err_Ok;
 
532
  }
 
533
 
 
534
 
 
535
  static FT_Error
 
536
  raccess_guess_vfat( FT_Library  library,
 
537
                      FT_Stream   stream,
 
538
                      char       *base_file_name,
 
539
                      char      **result_file_name,
 
540
                      FT_Long    *result_offset )
 
541
  {
 
542
    char*      newpath;
 
543
    FT_Memory  memory;
 
544
 
 
545
    FT_UNUSED( stream );
 
546
 
 
547
 
 
548
    memory = library->memory;
 
549
 
 
550
    newpath = raccess_make_file_name( memory, base_file_name,
 
551
                                      "resource.frk/" );
 
552
    if ( !newpath )
 
553
      return FT_Err_Out_Of_Memory;
 
554
 
 
555
    *result_file_name = newpath;
 
556
    *result_offset    = 0;
 
557
 
 
558
    return FT_Err_Ok;
 
559
  }
 
560
 
 
561
 
 
562
  static FT_Error
 
563
  raccess_guess_linux_cap( FT_Library  library,
 
564
                           FT_Stream   stream,
 
565
                           char       *base_file_name,
 
566
                           char      **result_file_name,
 
567
                           FT_Long    *result_offset )
 
568
  {
 
569
    char*      newpath;
 
570
    FT_Memory  memory;
 
571
 
 
572
    FT_UNUSED( stream );
 
573
 
 
574
 
 
575
    memory = library->memory;
 
576
 
 
577
    newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
 
578
    if ( !newpath )
 
579
      return FT_Err_Out_Of_Memory;
 
580
 
 
581
    *result_file_name = newpath;
 
582
    *result_offset    = 0;
 
583
 
 
584
    return FT_Err_Ok;
 
585
  }
 
586
 
 
587
 
 
588
  static FT_Error
 
589
  raccess_guess_linux_double( FT_Library  library,
 
590
                              FT_Stream   stream,
 
591
                              char       *base_file_name,
 
592
                              char      **result_file_name,
 
593
                              FT_Long    *result_offset )
 
594
  {
 
595
    char*      newpath;
 
596
    FT_Error   error;
 
597
    FT_Memory  memory;
 
598
 
 
599
    FT_UNUSED( stream );
 
600
 
 
601
 
 
602
    memory = library->memory;
 
603
 
 
604
    newpath = raccess_make_file_name( memory, base_file_name, "%" );
 
605
    if ( !newpath )
 
606
      return FT_Err_Out_Of_Memory;
 
607
 
 
608
    error = raccess_guess_linux_double_from_file_name( library, newpath,
 
609
                                                       result_offset );
 
610
    if ( !error )
 
611
      *result_file_name = newpath;
 
612
    else
 
613
      FT_FREE( newpath );
 
614
 
 
615
    return error;
 
616
  }
 
617
 
 
618
 
 
619
  static FT_Error
 
620
  raccess_guess_linux_netatalk( FT_Library  library,
 
621
                                FT_Stream   stream,
 
622
                                char       *base_file_name,
 
623
                                char      **result_file_name,
 
624
                                FT_Long    *result_offset )
 
625
  {
 
626
    char*      newpath;
 
627
    FT_Error   error;
 
628
    FT_Memory  memory;
 
629
 
 
630
    FT_UNUSED( stream );
 
631
 
 
632
 
 
633
    memory = library->memory;
 
634
 
 
635
    newpath = raccess_make_file_name( memory, base_file_name,
 
636
                                      ".AppleDouble/" );
 
637
    if ( !newpath )
 
638
      return FT_Err_Out_Of_Memory;
 
639
 
 
640
    error = raccess_guess_linux_double_from_file_name( library, newpath,
 
641
                                                       result_offset );
 
642
    if ( !error )
 
643
      *result_file_name = newpath;
 
644
    else
 
645
      FT_FREE( newpath );
 
646
 
 
647
    return error;
 
648
  }
 
649
 
 
650
 
 
651
  static FT_Error
 
652
  raccess_guess_apple_generic( FT_Library  library,
 
653
                               FT_Stream   stream,
 
654
                               char       *base_file_name,
 
655
                               FT_Int32    magic,
 
656
                               FT_Long    *result_offset )
 
657
  {
 
658
    FT_Int32   magic_from_stream;
 
659
    FT_Error   error;
 
660
    FT_Int32   version_number = 0;
 
661
    FT_UShort  n_of_entries;
 
662
 
 
663
    int        i;
 
664
    FT_UInt32  entry_id, entry_offset, entry_length = 0;
 
665
 
 
666
    const FT_UInt32  resource_fork_entry_id = 0x2;
 
667
 
 
668
    FT_UNUSED( library );
 
669
    FT_UNUSED( base_file_name );
 
670
    FT_UNUSED( version_number );
 
671
    FT_UNUSED( entry_length   );
 
672
 
 
673
 
 
674
    if ( FT_READ_LONG( magic_from_stream ) )
 
675
      return error;
 
676
    if ( magic_from_stream != magic )
 
677
      return FT_Err_Unknown_File_Format;
 
678
 
 
679
    if ( FT_READ_LONG( version_number ) )
 
680
      return error;
 
681
 
 
682
    /* filler */
 
683
    error = FT_Stream_Skip( stream, 16 );
 
684
    if ( error )
 
685
      return error;
 
686
 
 
687
    if ( FT_READ_USHORT( n_of_entries ) )
 
688
      return error;
 
689
    if ( n_of_entries == 0 )
 
690
      return FT_Err_Unknown_File_Format;
 
691
 
 
692
    for ( i = 0; i < n_of_entries; i++ )
 
693
    {
 
694
      if ( FT_READ_LONG( entry_id ) )
 
695
        return error;
 
696
      if ( entry_id == resource_fork_entry_id )
 
697
      {
 
698
        if ( FT_READ_LONG( entry_offset ) ||
 
699
             FT_READ_LONG( entry_length ) )
 
700
          continue;
 
701
        *result_offset = entry_offset;
 
702
 
 
703
        return FT_Err_Ok;
 
704
      }
 
705
      else
 
706
        FT_Stream_Skip( stream, 4 + 4 );    /* offset + length */
 
707
      }
 
708
 
 
709
    return FT_Err_Unknown_File_Format;
 
710
  }
 
711
 
 
712
 
 
713
  static FT_Error
 
714
  raccess_guess_linux_double_from_file_name( FT_Library  library,
 
715
                                             char       *file_name,
 
716
                                             FT_Long    *result_offset )
 
717
  {
 
718
    FT_Open_Args  args2;
 
719
    FT_Stream     stream2;
 
720
    char *        nouse = NULL;
 
721
    FT_Error      error;
 
722
 
 
723
 
 
724
    args2.flags    = FT_OPEN_PATHNAME;
 
725
    args2.pathname = file_name;
 
726
    error = FT_Stream_New( library, &args2, &stream2 );
 
727
    if ( error )
 
728
      return error;
 
729
 
 
730
    error = raccess_guess_apple_double( library, stream2, file_name,
 
731
                                        &nouse, result_offset );
 
732
 
 
733
    FT_Stream_Free( stream2, 0 );
 
734
 
 
735
    return error;
 
736
  }
 
737
 
 
738
 
 
739
  static char*
 
740
  raccess_make_file_name( FT_Memory    memory,
 
741
                          const char  *original_name,
 
742
                          const char  *insertion )
 
743
  {
 
744
    char*        new_name;
 
745
    char*        tmp;
 
746
    const char*  slash;
 
747
    unsigned     new_length;
 
748
    FT_Error     error = FT_Err_Ok;
 
749
 
 
750
    FT_UNUSED( error );
 
751
 
 
752
 
 
753
    new_length = ft_strlen( original_name ) + ft_strlen( insertion );
 
754
    if ( FT_ALLOC( new_name, new_length + 1 ) )
 
755
      return NULL;
 
756
 
 
757
    tmp = ft_strrchr( original_name, '/' );
 
758
    if ( tmp )
 
759
    {
 
760
      ft_strncpy( new_name, original_name, tmp - original_name + 1 );
 
761
      new_name[tmp - original_name + 1] = '\0';
 
762
      slash = tmp + 1;
 
763
    }
 
764
    else
 
765
    {
 
766
      slash       = original_name;
 
767
      new_name[0] = '\0';
 
768
    }
 
769
 
 
770
    ft_strcat( new_name, insertion );
 
771
    ft_strcat( new_name, slash );
 
772
 
 
773
    return new_name;
 
774
  }
 
775
 
 
776
 
 
777
#else   /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
 
778
 
 
779
 
 
780
  /*************************************************************************/
 
781
  /*                  Dummy function; just sets errors                     */
 
782
  /*************************************************************************/
 
783
 
 
784
  FT_BASE_DEF( void )
 
785
  FT_Raccess_Guess( FT_Library  library,
 
786
                    FT_Stream   stream,
 
787
                    char       *base_name,
 
788
                    char      **new_names,
 
789
                    FT_Long    *offsets,
 
790
                    FT_Error   *errors )
 
791
  {
 
792
    int  i;
 
793
 
 
794
    FT_UNUSED( library );
 
795
    FT_UNUSED( stream );
 
796
    FT_UNUSED( base_name );
 
797
 
 
798
 
 
799
    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
 
800
    {
 
801
      new_names[i] = NULL;
 
802
      offsets[i]   = 0;
 
803
      errors[i]    = FT_Err_Unimplemented_Feature;
 
804
    }
 
805
  }
 
806
 
 
807
 
 
808
#endif  /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
 
809
 
 
810
 
 
811
/* END */