~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/freetype/src/base/ftrfork.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

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, 2008, 2009, 2010 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
  typedef enum  FT_RFork_Rule_ {
 
353
    FT_RFork_Rule_invalid = -2,
 
354
    FT_RFork_Rule_uknown, /* -1 */
 
355
    FT_RFork_Rule_apple_double,
 
356
    FT_RFork_Rule_apple_single,
 
357
    FT_RFork_Rule_darwin_ufs_export,
 
358
    FT_RFork_Rule_darwin_newvfs,
 
359
    FT_RFork_Rule_darwin_hfsplus,
 
360
    FT_RFork_Rule_vfat,
 
361
    FT_RFork_Rule_linux_cap,
 
362
    FT_RFork_Rule_linux_double,
 
363
    FT_RFork_Rule_linux_netatalk
 
364
  } FT_RFork_Rule;
 
365
 
 
366
  /* For fast translation between rule index and rule type,
 
367
   * the macros FT_RFORK_xxx should be kept consistent with
 
368
   * the raccess_guess_funcs table
 
369
   */
 
370
  typedef struct raccess_guess_rec_ {
 
371
    raccess_guess_func  func;
 
372
    FT_RFork_Rule       type;
 
373
  } raccess_guess_rec;
 
374
 
 
375
  static raccess_guess_rec  raccess_guess_table[FT_RACCESS_N_RULES] =
 
376
  {
 
377
    { raccess_guess_apple_double,       FT_RFork_Rule_apple_double, },
 
378
    { raccess_guess_apple_single,       FT_RFork_Rule_apple_single, },
 
379
    { raccess_guess_darwin_ufs_export,  FT_RFork_Rule_darwin_ufs_export, },
 
380
    { raccess_guess_darwin_newvfs,      FT_RFork_Rule_darwin_newvfs, },
 
381
    { raccess_guess_darwin_hfsplus,     FT_RFork_Rule_darwin_hfsplus, },
 
382
    { raccess_guess_vfat,               FT_RFork_Rule_vfat, },
 
383
    { raccess_guess_linux_cap,          FT_RFork_Rule_linux_cap, },
 
384
    { raccess_guess_linux_double,       FT_RFork_Rule_linux_double, },
 
385
    { raccess_guess_linux_netatalk,     FT_RFork_Rule_linux_netatalk, },
 
386
  };
 
387
 
 
388
  FT_BASE_DEF( void )
 
389
  FT_Raccess_Guess( FT_Library  library,
 
390
                    FT_Stream   stream,
 
391
                    char*       base_name,
 
392
                    char      **new_names,
 
393
                    FT_Long    *offsets,
 
394
                    FT_Error   *errors )
 
395
  {
 
396
    FT_Long  i;
 
397
 
 
398
 
 
399
    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
 
400
    {
 
401
      new_names[i] = NULL;
 
402
      if ( NULL != stream )
 
403
        errors[i] = FT_Stream_Seek( stream, 0 );
 
404
      else
 
405
        errors[i] = FT_Err_Ok;
 
406
 
 
407
      if ( errors[i] )
 
408
        continue ;
 
409
 
 
410
      errors[i] = (raccess_guess_table[i].func)( library,
 
411
                                                 stream, base_name,
 
412
                                                 &(new_names[i]),
 
413
                                                 &(offsets[i]) );
 
414
    }
 
415
 
 
416
    return;
 
417
  }
 
418
 
 
419
 
 
420
  static FT_RFork_Rule
 
421
  raccess_get_rule_type_from_rule_index( FT_UInt  rule_index )
 
422
  {
 
423
    if ( rule_index >= FT_RACCESS_N_RULES )
 
424
      return FT_RFork_Rule_invalid;
 
425
 
 
426
    return raccess_guess_table[rule_index].type;
 
427
  }
 
428
 
 
429
 
 
430
  FT_LOCAL_DEF( FT_Bool )
 
431
  raccess_rule_by_darwin_vfs( FT_UInt  rule_index )
 
432
  {
 
433
    switch( raccess_get_rule_type_from_rule_index( rule_index ) )
 
434
    {
 
435
      case FT_RFork_Rule_darwin_newvfs:
 
436
      case FT_RFork_Rule_darwin_hfsplus:
 
437
        return TRUE;
 
438
 
 
439
      default:
 
440
        return FALSE;
 
441
    }
 
442
  }
 
443
 
 
444
 
 
445
  static FT_Error
 
446
  raccess_guess_apple_double( FT_Library  library,
 
447
                              FT_Stream   stream,
 
448
                              char       *base_file_name,
 
449
                              char      **result_file_name,
 
450
                              FT_Long    *result_offset )
 
451
  {
 
452
    FT_Int32  magic = ( 0x00 << 24 ) |
 
453
                      ( 0x05 << 16 ) |
 
454
                      ( 0x16 <<  8 ) |
 
455
                        0x07;
 
456
 
 
457
 
 
458
    *result_file_name = NULL;
 
459
    if ( NULL == stream )
 
460
      return FT_Err_Cannot_Open_Stream;
 
461
 
 
462
    return raccess_guess_apple_generic( library, stream, base_file_name,
 
463
                                        magic, result_offset );
 
464
  }
 
465
 
 
466
 
 
467
  static FT_Error
 
468
  raccess_guess_apple_single( FT_Library  library,
 
469
                              FT_Stream   stream,
 
470
                              char       *base_file_name,
 
471
                              char      **result_file_name,
 
472
                              FT_Long    *result_offset )
 
473
  {
 
474
    FT_Int32  magic = ( 0x00 << 24 ) |
 
475
                      ( 0x05 << 16 ) |
 
476
                      ( 0x16 <<  8 ) |
 
477
                        0x00;
 
478
 
 
479
 
 
480
    *result_file_name = NULL;
 
481
    if ( NULL == stream )
 
482
      return FT_Err_Cannot_Open_Stream;
 
483
 
 
484
    return raccess_guess_apple_generic( library, stream, base_file_name,
 
485
                                        magic, result_offset );
 
486
  }
 
487
 
 
488
 
 
489
  static FT_Error
 
490
  raccess_guess_darwin_ufs_export( FT_Library  library,
 
491
                                   FT_Stream   stream,
 
492
                                   char       *base_file_name,
 
493
                                   char      **result_file_name,
 
494
                                   FT_Long    *result_offset )
 
495
  {
 
496
    char*      newpath;
 
497
    FT_Error   error;
 
498
    FT_Memory  memory;
 
499
 
 
500
    FT_UNUSED( stream );
 
501
 
 
502
 
 
503
    memory  = library->memory;
 
504
    newpath = raccess_make_file_name( memory, base_file_name, "._" );
 
505
    if ( !newpath )
 
506
      return FT_Err_Out_Of_Memory;
 
507
 
 
508
    error = raccess_guess_linux_double_from_file_name( library, newpath,
 
509
                                                       result_offset );
 
510
    if ( !error )
 
511
      *result_file_name = newpath;
 
512
    else
 
513
      FT_FREE( newpath );
 
514
 
 
515
    return error;
 
516
  }
 
517
 
 
518
 
 
519
  static FT_Error
 
520
  raccess_guess_darwin_hfsplus( FT_Library  library,
 
521
                                FT_Stream   stream,
 
522
                                char       *base_file_name,
 
523
                                char      **result_file_name,
 
524
                                FT_Long    *result_offset )
 
525
  {
 
526
    /*
 
527
      Only meaningful on systems with hfs+ drivers (or Macs).
 
528
     */
 
529
    FT_Error   error;
 
530
    char*      newpath;
 
531
    FT_Memory  memory;
 
532
    FT_Long    base_file_len = ft_strlen( base_file_name );
 
533
 
 
534
    FT_UNUSED( stream );
 
535
 
 
536
 
 
537
    memory = library->memory;
 
538
 
 
539
    if ( base_file_len + 6 > FT_INT_MAX )
 
540
      return FT_Err_Array_Too_Large;
 
541
 
 
542
    if ( FT_ALLOC( newpath, base_file_len + 6 ) )
 
543
      return error;
 
544
 
 
545
    FT_MEM_COPY( newpath, base_file_name, base_file_len );
 
546
    FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
 
547
 
 
548
    *result_file_name = newpath;
 
549
    *result_offset    = 0;
 
550
 
 
551
    return FT_Err_Ok;
 
552
  }
 
553
 
 
554
 
 
555
  static FT_Error
 
556
  raccess_guess_darwin_newvfs( FT_Library  library,
 
557
                               FT_Stream   stream,
 
558
                               char       *base_file_name,
 
559
                               char      **result_file_name,
 
560
                               FT_Long    *result_offset )
 
561
  {
 
562
    /*
 
563
      Only meaningful on systems with Mac OS X (> 10.1).
 
564
     */
 
565
    FT_Error   error;
 
566
    char*      newpath;
 
567
    FT_Memory  memory;
 
568
    FT_Long    base_file_len = ft_strlen( base_file_name );
 
569
 
 
570
    FT_UNUSED( stream );
 
571
 
 
572
 
 
573
    memory = library->memory;
 
574
 
 
575
    if ( base_file_len + 18 > FT_INT_MAX )
 
576
      return FT_Err_Array_Too_Large;
 
577
 
 
578
    if ( FT_ALLOC( newpath, base_file_len + 18 ) )
 
579
      return error;
 
580
 
 
581
    FT_MEM_COPY( newpath, base_file_name, base_file_len );
 
582
    FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );
 
583
 
 
584
    *result_file_name = newpath;
 
585
    *result_offset    = 0;
 
586
 
 
587
    return FT_Err_Ok;
 
588
  }
 
589
 
 
590
 
 
591
  static FT_Error
 
592
  raccess_guess_vfat( FT_Library  library,
 
593
                      FT_Stream   stream,
 
594
                      char       *base_file_name,
 
595
                      char      **result_file_name,
 
596
                      FT_Long    *result_offset )
 
597
  {
 
598
    char*      newpath;
 
599
    FT_Memory  memory;
 
600
 
 
601
    FT_UNUSED( stream );
 
602
 
 
603
 
 
604
    memory = library->memory;
 
605
 
 
606
    newpath = raccess_make_file_name( memory, base_file_name,
 
607
                                      "resource.frk/" );
 
608
    if ( !newpath )
 
609
      return FT_Err_Out_Of_Memory;
 
610
 
 
611
    *result_file_name = newpath;
 
612
    *result_offset    = 0;
 
613
 
 
614
    return FT_Err_Ok;
 
615
  }
 
616
 
 
617
 
 
618
  static FT_Error
 
619
  raccess_guess_linux_cap( FT_Library  library,
 
620
                           FT_Stream   stream,
 
621
                           char       *base_file_name,
 
622
                           char      **result_file_name,
 
623
                           FT_Long    *result_offset )
 
624
  {
 
625
    char*      newpath;
 
626
    FT_Memory  memory;
 
627
 
 
628
    FT_UNUSED( stream );
 
629
 
 
630
 
 
631
    memory = library->memory;
 
632
 
 
633
    newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
 
634
    if ( !newpath )
 
635
      return FT_Err_Out_Of_Memory;
 
636
 
 
637
    *result_file_name = newpath;
 
638
    *result_offset    = 0;
 
639
 
 
640
    return FT_Err_Ok;
 
641
  }
 
642
 
 
643
 
 
644
  static FT_Error
 
645
  raccess_guess_linux_double( FT_Library  library,
 
646
                              FT_Stream   stream,
 
647
                              char       *base_file_name,
 
648
                              char      **result_file_name,
 
649
                              FT_Long    *result_offset )
 
650
  {
 
651
    char*      newpath;
 
652
    FT_Error   error;
 
653
    FT_Memory  memory;
 
654
 
 
655
    FT_UNUSED( stream );
 
656
 
 
657
 
 
658
    memory = library->memory;
 
659
 
 
660
    newpath = raccess_make_file_name( memory, base_file_name, "%" );
 
661
    if ( !newpath )
 
662
      return FT_Err_Out_Of_Memory;
 
663
 
 
664
    error = raccess_guess_linux_double_from_file_name( library, newpath,
 
665
                                                       result_offset );
 
666
    if ( !error )
 
667
      *result_file_name = newpath;
 
668
    else
 
669
      FT_FREE( newpath );
 
670
 
 
671
    return error;
 
672
  }
 
673
 
 
674
 
 
675
  static FT_Error
 
676
  raccess_guess_linux_netatalk( FT_Library  library,
 
677
                                FT_Stream   stream,
 
678
                                char       *base_file_name,
 
679
                                char      **result_file_name,
 
680
                                FT_Long    *result_offset )
 
681
  {
 
682
    char*      newpath;
 
683
    FT_Error   error;
 
684
    FT_Memory  memory;
 
685
 
 
686
    FT_UNUSED( stream );
 
687
 
 
688
 
 
689
    memory = library->memory;
 
690
 
 
691
    newpath = raccess_make_file_name( memory, base_file_name,
 
692
                                      ".AppleDouble/" );
 
693
    if ( !newpath )
 
694
      return FT_Err_Out_Of_Memory;
 
695
 
 
696
    error = raccess_guess_linux_double_from_file_name( library, newpath,
 
697
                                                       result_offset );
 
698
    if ( !error )
 
699
      *result_file_name = newpath;
 
700
    else
 
701
      FT_FREE( newpath );
 
702
 
 
703
    return error;
 
704
  }
 
705
 
 
706
 
 
707
  static FT_Error
 
708
  raccess_guess_apple_generic( FT_Library  library,
 
709
                               FT_Stream   stream,
 
710
                               char       *base_file_name,
 
711
                               FT_Int32    magic,
 
712
                               FT_Long    *result_offset )
 
713
  {
 
714
    FT_Int32   magic_from_stream;
 
715
    FT_Error   error;
 
716
    FT_Int32   version_number = 0;
 
717
    FT_UShort  n_of_entries;
 
718
 
 
719
    int        i;
 
720
    FT_UInt32  entry_id, entry_offset, entry_length = 0;
 
721
 
 
722
    const FT_UInt32  resource_fork_entry_id = 0x2;
 
723
 
 
724
    FT_UNUSED( library );
 
725
    FT_UNUSED( base_file_name );
 
726
    FT_UNUSED( version_number );
 
727
    FT_UNUSED( entry_length   );
 
728
 
 
729
 
 
730
    if ( FT_READ_LONG( magic_from_stream ) )
 
731
      return error;
 
732
    if ( magic_from_stream != magic )
 
733
      return FT_Err_Unknown_File_Format;
 
734
 
 
735
    if ( FT_READ_LONG( version_number ) )
 
736
      return error;
 
737
 
 
738
    /* filler */
 
739
    error = FT_Stream_Skip( stream, 16 );
 
740
    if ( error )
 
741
      return error;
 
742
 
 
743
    if ( FT_READ_USHORT( n_of_entries ) )
 
744
      return error;
 
745
    if ( n_of_entries == 0 )
 
746
      return FT_Err_Unknown_File_Format;
 
747
 
 
748
    for ( i = 0; i < n_of_entries; i++ )
 
749
    {
 
750
      if ( FT_READ_LONG( entry_id ) )
 
751
        return error;
 
752
      if ( entry_id == resource_fork_entry_id )
 
753
      {
 
754
        if ( FT_READ_LONG( entry_offset ) ||
 
755
             FT_READ_LONG( entry_length ) )
 
756
          continue;
 
757
        *result_offset = entry_offset;
 
758
 
 
759
        return FT_Err_Ok;
 
760
      }
 
761
      else
 
762
      {
 
763
        error = FT_Stream_Skip( stream, 4 + 4 );    /* offset + length */
 
764
        if ( error )
 
765
          return error;
 
766
      }
 
767
    }
 
768
 
 
769
    return FT_Err_Unknown_File_Format;
 
770
  }
 
771
 
 
772
 
 
773
  static FT_Error
 
774
  raccess_guess_linux_double_from_file_name( FT_Library  library,
 
775
                                             char       *file_name,
 
776
                                             FT_Long    *result_offset )
 
777
  {
 
778
    FT_Open_Args  args2;
 
779
    FT_Stream     stream2;
 
780
    char *        nouse = NULL;
 
781
    FT_Error      error;
 
782
 
 
783
 
 
784
    args2.flags    = FT_OPEN_PATHNAME;
 
785
    args2.pathname = file_name;
 
786
    error = FT_Stream_New( library, &args2, &stream2 );
 
787
    if ( error )
 
788
      return error;
 
789
 
 
790
    error = raccess_guess_apple_double( library, stream2, file_name,
 
791
                                        &nouse, result_offset );
 
792
 
 
793
    FT_Stream_Free( stream2, 0 );
 
794
 
 
795
    return error;
 
796
  }
 
797
 
 
798
 
 
799
  static char*
 
800
  raccess_make_file_name( FT_Memory    memory,
 
801
                          const char  *original_name,
 
802
                          const char  *insertion )
 
803
  {
 
804
    char*        new_name = NULL;
 
805
    const char*  tmp;
 
806
    const char*  slash;
 
807
    size_t       new_length;
 
808
    FT_Error     error = FT_Err_Ok;
 
809
 
 
810
    FT_UNUSED( error );
 
811
 
 
812
 
 
813
    new_length = ft_strlen( original_name ) + ft_strlen( insertion );
 
814
    if ( FT_ALLOC( new_name, new_length + 1 ) )
 
815
      return NULL;
 
816
 
 
817
    tmp = ft_strrchr( original_name, '/' );
 
818
    if ( tmp )
 
819
    {
 
820
      ft_strncpy( new_name, original_name, tmp - original_name + 1 );
 
821
      new_name[tmp - original_name + 1] = '\0';
 
822
      slash = tmp + 1;
 
823
    }
 
824
    else
 
825
    {
 
826
      slash       = original_name;
 
827
      new_name[0] = '\0';
 
828
    }
 
829
 
 
830
    ft_strcat( new_name, insertion );
 
831
    ft_strcat( new_name, slash );
 
832
 
 
833
    return new_name;
 
834
  }
 
835
 
 
836
 
 
837
#else   /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
 
838
 
 
839
 
 
840
  /*************************************************************************/
 
841
  /*                  Dummy function; just sets errors                     */
 
842
  /*************************************************************************/
 
843
 
 
844
  FT_BASE_DEF( void )
 
845
  FT_Raccess_Guess( FT_Library  library,
 
846
                    FT_Stream   stream,
 
847
                    char       *base_name,
 
848
                    char      **new_names,
 
849
                    FT_Long    *offsets,
 
850
                    FT_Error   *errors )
 
851
  {
 
852
    int  i;
 
853
 
 
854
    FT_UNUSED( library );
 
855
    FT_UNUSED( stream );
 
856
    FT_UNUSED( base_name );
 
857
 
 
858
 
 
859
    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
 
860
    {
 
861
      new_names[i] = NULL;
 
862
      offsets[i]   = 0;
 
863
      errors[i]    = FT_Err_Unimplemented_Feature;
 
864
    }
 
865
  }
 
866
 
 
867
 
 
868
#endif  /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
 
869
 
 
870
 
 
871
/* END */