/* Copyright 2000 by Abacus Research and * Development, Inc. All rights reserved. */ #if !defined (OMIT_RCSID_STRINGS) char ROMlib_rcsid_suffix_maps[] = "$Id: suffix_maps.c 63 2004-12-24 18:19:43Z ctm $"; #endif #include "rsys/common.h" #include "rsys/suffix_maps.h" #include "rsys/file.h" #include /* * This file contains the routines needed to create mappings from file * suffixes to (Creator, Type) pairs. When a file is created with a suffix * that is in the list, the normal % file won't be created. When the file's * creator and type is queried, the creator and type from the list will be * read. */ typedef struct suffix_entry { char *suffix; uint32 creator; uint32 type; const char *application; struct suffix_entry *next; } suffix_entry_t; PRIVATE suffix_entry_t *suffix_head; PRIVATE boolean_t str_to_hex (const char *str, uint32 *valp) { boolean_t retval; int len; len = strlen (str); retval = (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') && len >= 3 && len <= 10); if (retval) { uint32 val; val = 0; for (str += 2; retval && *str; ++str) if (isxdigit (*str)) val = (val << 4) | ROMlib_fromhex (*str); else retval = FALSE; *valp = val; } return retval; } PUBLIC void ROMlib_add_suffix_quad (const char *suffixp, const char *creator_hexp, const char *type_hexp, const char *applicationp) { uint32 creator; uint32 type; if (str_to_hex (creator_hexp, &creator) && str_to_hex (type_hexp, &type)) { suffix_entry_t *new; new = malloc (sizeof *new); if (new) { new->suffix = strdup (suffixp); if (!new->suffix) free (new); else { new->creator = creator; new->type = type; new->application = strdup (applicationp); new->next = suffix_head; suffix_head = new; } } } } PRIVATE suffix_entry_t ** find_suffixpp (const char *suffix) { suffix_entry_t **retval; retval = &suffix_head; while (*retval && strcasecmp ((*retval)->suffix, suffix) != 0) retval = &(*retval)->next; return retval; } /* * Best match is (creator, 'APPL') * next best is (creator, type) * next best is (creator, X) * worst is (X, type) */ PUBLIC const char * ROMlib_find_best_creator_type_match (uint32 creator, uint32 type) { enum { no_match, type_match, creator_match, both_match, appl_match } match; suffix_entry_t **pp; const char *retval; retval = NULL; for (match = no_match, pp = &suffix_head; match != appl_match && *pp; pp = &(*pp)->next) { if (*(*pp)->application) { if ((*pp)->creator == creator) { if ((*pp)->type == TICK("APPL")) { retval = (*pp)->application; match = appl_match; } else if (match < both_match && (*pp)->type == type) { retval = (*pp)->application; match = both_match; } else if (match < creator_match) { retval = (*pp)->application; match = creator_match; } } else if ((*pp)->type == type && match < type_match) { retval = (*pp)->application; match = type_match; } } } return retval; } PRIVATE boolean_t filename_suffix_match (const char *suffix, int len, const char *filename) { boolean_t retval; int suffix_len; suffix_len = strlen (suffix); retval = (len >= suffix_len && strncasecmp (suffix, filename + len - suffix_len, suffix_len) == 0); return retval; } PRIVATE suffix_entry_t ** find_filenamepp (int len, const char *filename) { suffix_entry_t **retval; retval = &suffix_head; while (*retval && !filename_suffix_match ((*retval)->suffix, len, filename)) retval = &(*retval)->next; return retval; } PUBLIC boolean_t ROMlib_creator_and_type_from_suffix (const char *suffix, uint32 *creatorp, uint32 *typep) { boolean_t retval; suffix_entry_t **pp; pp = find_suffixpp (suffix); if (!*pp) retval = FALSE; else { retval = TRUE; if (creatorp) *creatorp = (*pp)->creator; if (typep) *typep = (*pp)->type; } return retval; } PUBLIC boolean_t ROMlib_creator_and_type_from_filename (int len, const char *filename, uint32 *creatorp, uint32 *typep) { boolean_t retval; suffix_entry_t **pp; pp = find_filenamepp (len, filename); if (!*pp) retval = FALSE; else { retval = TRUE; if (creatorp) *creatorp = (*pp)->creator; if (typep) *typep = (*pp)->type; } return retval; } PRIVATE void release_entry (suffix_entry_t *to_release) { free (to_release->suffix); free (to_release); } PUBLIC boolean_t ROMlib_delete_suffix (const char *suffix) { boolean_t retval; suffix_entry_t **pp; pp = find_suffixpp (suffix); if (!*pp) retval = FALSE; else { suffix_entry_t *to_release; retval = TRUE; to_release = *pp; *pp = (*pp)->next; release_entry (to_release); } return retval; }