/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ /* * npassoc.c $Revision: 3.1 $ * some xp mime-type file extension associations */ #include "npassoc.h" #include "xp_mem.h" #include "xp_mcom.h" #include "net.h" static NPFileTypeAssoc *np_fassoc_list=0; /* should use xp hash */ extern void NET_cdataAdd(NET_cdataStruct *cd); #define NP_MAX_EXTS 64 static char *np_array[NP_MAX_EXTS]; /* allocate and fill a null-terminated array of extensions from a comma and space delimited list */ static char ** np_parse_exts(const char *exts) { char *p, *e, **res; int n=0; if(!exts) return 0; /* p is the current position, e is the start of the nth extension */ for(e=p=(char *)exts; *p; p++) { if( (*p==' ') || (*p==',') ) { if(*e == '.') e++; if(p>e) { if(!(np_array[n] = (char *)XP_ALLOC(p-e+1))) return 0; XP_MEMCPY(np_array[n], e, (p-e)); *(np_array[n]+(p-e)) = 0; n++; e = p+1; } } } if(*e == '.') e++; if(p>e) { if(!(np_array[n] = (char *)XP_ALLOC(p-e+1))) return 0; XP_MEMCPY(np_array[n], e, (p-e)); *(np_array[n]+(p-e)) = 0; n++; } if(!(res = (char **)XP_ALLOC((n+1)*sizeof(char *)))) return 0; XP_MEMCPY(res, np_array, n*sizeof(char *)); res[n] = 0; return res; } /* construct a file association from a mime type. * - extensions is a list of comma/space separated file extensions * with or without leading .s * - filetype is platform specific data for this list of extensions, * currently creator on mac and open file dialog descriptions on win. * filetype is callee owned data and must remain valid */ NPFileTypeAssoc * NPL_NewFileAssociation(const char *MIMEType, const char *extensions, const char *description, void *fileType) { NPFileTypeAssoc *fassoc = 0; /* make a file association struct */ if(!(fassoc=XP_NEW_ZAP(NPFileTypeAssoc))) return 0; StrAllocCopy((fassoc->type), MIMEType ? MIMEType : ""); StrAllocCopy((fassoc->description), description ? description : ""); StrAllocCopy((fassoc->extentstring), extensions ? extensions : ""); fassoc->fileType = fileType; /* caller owns this data */ fassoc->extentlist = np_parse_exts(extensions); return fassoc; } /* deletes a file association. Returns the platform specific fileType data that we dont know how to dispose of. */ void * NPL_DeleteFileAssociation(NPFileTypeAssoc *fassoc) { void* fileType; if (!fassoc) return NULL; fileType = fassoc->fileType; NPL_RemoveFileAssociation(fassoc); if (fassoc->type) { XP_FREE(fassoc->type); fassoc->type = NULL; } if (fassoc->description) { XP_FREE(fassoc->description); fassoc->description = NULL; } if (fassoc->extentstring) { XP_FREE(fassoc->extentstring); fassoc->extentstring = NULL; } { char** charPtrPtr; for (charPtrPtr = &fassoc->extentlist[0]; *charPtrPtr; *charPtrPtr=0, charPtrPtr++) XP_FREE(*charPtrPtr); fassoc->extentlist = NULL; } XP_FREE(fassoc); return fileType; } /* Register a file association with us and netlib. */ void NPL_RegisterFileAssociation(NPFileTypeAssoc *fassoc) { if (fassoc) { fassoc->pNext = np_fassoc_list; np_fassoc_list = fassoc; NET_cdataCommit(fassoc->type, fassoc->extentstring); /* * We need to add the description, too, which unfortunately requires * looking the cinfo up AGAIN and setting the desc field... */ if (fassoc->description) { NET_cdataStruct temp; NET_cdataStruct* cdata; XP_BZERO(&temp, sizeof(temp)); temp.ci.type = fassoc->type; cdata = NET_cdataExist(&temp); XP_ASSERT(cdata); if (cdata) StrAllocCopy(cdata->ci.desc, fassoc->description); } } } /* Unregister a file association. */ NPFileTypeAssoc * NPL_RemoveFileAssociation(NPFileTypeAssoc *fassoc) { NPFileTypeAssoc *f = np_fassoc_list; if(!fassoc) return 0; /* unregister with netlib */ if(fassoc == np_fassoc_list) np_fassoc_list = np_fassoc_list->pNext; else { for(; f; f=f->pNext) if(f->pNext == fassoc) { NPFileTypeAssoc *ft; ft = f->pNext; f->pNext = f->pNext->pNext; f = ft; break; } } return f; } /* returns a linked list of registered associations. * if type is NULL you get the entire list else the association matching * that MIME type */ NPFileTypeAssoc * NPL_GetFileAssociation(const char *type) { NPFileTypeAssoc *f=NULL; if(!np_fassoc_list) return NULL; if(type==NULL) return np_fassoc_list; for(f=np_fassoc_list; f; f=f->pNext) if(!(XP_STRCMP(type, f->type))) return f; return NULL; }