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