diff --git a/mozilla/network/cstream/Makefile b/mozilla/network/cstream/Makefile new file mode 100644 index 00000000000..10a5573cc02 --- /dev/null +++ b/mozilla/network/cstream/Makefile @@ -0,0 +1,32 @@ +#!gmake +# +# 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. + +DEPTH = ../.. + +MODULE = cstream +LIBRARY_NAME = cstream + +CSRCS = \ + cstream.c \ + $(NULL) + +EXPORTS= cstream.h strmutil.h + +REQUIRES = network nspr2 dbm util pref js java fileurl security layer img jtools + +include $(DEPTH)/config/rules.mk + diff --git a/mozilla/network/cstream/cstream.c b/mozilla/network/cstream/cstream.c new file mode 100644 index 00000000000..30c1615f542 --- /dev/null +++ b/mozilla/network/cstream/cstream.c @@ -0,0 +1,1244 @@ +/* -*- 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. + */ +/* + * Do stream related stuff like push data down the + * stream and determine which converter to use to + * set up the stream. + * Additions/Changes by Judson Valeski 1998 + */ +#include "mkutils.h" +#include "cstream.h" +#include "plstr.h" +#include "prmem.h" +#include "mkgeturl.h" +#include "netstream.h" +#include "strmutil.h" +#include "mktcp.h" + +/* for XP_GetString() */ +#include "xpgetstr.h" +extern int XP_ALERT_CANTFIND_CONVERTER; + + +#ifdef PROFILE +#pragma profile on +#endif + +typedef struct _net_ConverterStruct { + XP_List * converter_stack; /* the ordered list of converters; + * elements are net_ConverterElement's + */ + char * format_in; /* the input (mime) type that the + * function accepts + */ + char * encoding_in; /* the input content-encoding that the + * function accepts, or 0 for `any'. + */ + FO_Present_Types format_out; /* the output type of the function */ + Bool bAutomated; /* this flag currently only used by Window on the + client side. */ +} net_ConverterStruct; + +typedef struct _net_ConverterElement { + NET_Converter * converter; /* the converter function */ + void * data_obj; /* a converter specific data object + * passed in at the + * time of registration + */ +} net_ConverterElement; + +/* MWH - this is an ugly implement to get get around the following: I need to pass + a flag to NET_RegisterContentTypeConverter(), but I don't want to change the API. + If we changed this API please fixed this problem. +*/ + +static Bool autoFlag = 0; + +#define MAX_FORMATS_OUT FO_ONLY_FROM_CACHE_AND_LOAD_HTML_HELP_MAP_FILE +1 + +static Bool needInit = TRUE; /* this is the flag to tell us that we need to initialize + net_converter_list, and net_decoder_list. */ + +PRIVATE XP_List * net_converter_list[MAX_FORMATS_OUT]; /* a list of converters */ +PRIVATE XP_List * net_decoder_list[MAX_FORMATS_OUT]; /* a list of decoders */ + +#define NET_MIME_EXACT_MATCH 1 +#define NET_MIME_PARTIAL_MATCH 2 +#define NET_WILDCARD_MATCH 3 + +/* will compare two mime times and return + * NET_MIME_EXACT_MATCH if they match exactly + * or NET_MIME_PARTIAL_MATCH if they match due + * to a wildcard entry (image.*, or movie.*). + * + * if 'partial' equals '*' then + * NET_WILDCARD_MATCH is returned + * + * If there is no match then 0(zero) is returned + */ +PRIVATE int +net_compare_mime_types(char * absolute, char * partial) +{ + char *star; + + TRACEMSG(("StreamBuilder: Comparing %s and %s\n",absolute, partial)); + + if(!PL_strcasecmp(absolute, partial)) + return(NET_MIME_EXACT_MATCH); + + if(!PL_strcmp(partial, "*")) + return(NET_WILDCARD_MATCH); + + if((star = PL_strchr(partial, '*')) == 0) + return(0); /* not a wildcard mime type */ + + /* compare just the part before the slash star + * + */ + if(!PL_strncasecmp(absolute, partial, (star-1)-partial)) + return(NET_MIME_PARTIAL_MATCH); + + return(0); /* no match */ +} + +PUBLIC XP_Bool +NET_HaveConverterForMimeType(char *content_type) +{ + net_ConverterStruct * cs_ptr; + XP_List * ct_list_ptr = net_converter_list[FO_PRESENT]; + + while ((cs_ptr=(net_ConverterStruct *) XP_ListNextObject(ct_list_ptr)) + != 0) + { + if (FO_PRESENT == cs_ptr->format_out) + { + int compare_val = net_compare_mime_types (content_type, cs_ptr->format_in); + if (compare_val == NET_MIME_PARTIAL_MATCH || compare_val == NET_MIME_EXACT_MATCH) + return TRUE; + } + } + + return FALSE; +} + +/* Find a converter routine to create a stream and return the stream struct +*/ +PUBLIC NET_StreamClass * +NET_StreamBuilder (FO_Present_Types format_out, + URL_Struct *URL_s, + MWContext *context) +{ + net_ConverterStruct * cs_ptr; + XP_List * ct_list_ptr = net_converter_list[format_out]; + + + + XP_List * ce_list_ptr = net_decoder_list[format_out]; + + assert (URL_s->content_type); + + TRACEMSG(("Entering StreamBuilder:\n\ + F-in: %s\n\ + F-out: %d\n\ + Enc: %s\n",URL_s->content_type,format_out, + (URL_s->content_encoding ? URL_s->content_encoding : "None Specified"))); + +#if 0 + /* First, determine whether there is a content-type converter for this + document; if there isn't one, then the only way to handle it is to + send it straight to disk, so try that. + */ + if (format_out != FO_SAVE_TO_DISK) + { + while ((cs_ptr=(net_ConverterStruct *) XP_ListNextObject(ct_list_ptr)) + != 0) + { + if (format_out == cs_ptr->format_out && + net_compare_mime_types (URL_s->content_type, + cs_ptr->format_in)) + break; + } + + if (! cs_ptr) /* There is no content-type converter; save it. */ + format_out = FO_SAVE_TO_DISK; + ct_list_ptr = net_converter_list; /* Reset for next traversal. */ + } +#endif + + + /* if there are content encodings then + * execute decoders first + */ + /* go through list of converters and choose + * the first exact or partial match we + * find. The order of the list + * is guarenteed by the registration + * routines + * + * the format-out is compared as well. + * + * if there are transfer_encodings use them even before + * content_encodings + */ + if ((URL_s->transfer_encoding && *URL_s->transfer_encoding) + || (URL_s->content_encoding && *URL_s->content_encoding)) + { + char *encoding; + + if(URL_s->transfer_encoding && *URL_s->transfer_encoding) + encoding = URL_s->transfer_encoding; + else + encoding = URL_s->content_encoding; + + + while ((cs_ptr=(net_ConverterStruct *) XP_ListNextObject(ce_list_ptr)) + != 0) + { + if (format_out == cs_ptr->format_out && + net_compare_mime_types (URL_s->content_type, + cs_ptr->format_in) && + net_compare_mime_types (encoding, + cs_ptr->encoding_in)) + { + net_ConverterElement *elem = XP_ListPeekTopObject(cs_ptr->converter_stack); + PR_ASSERT(elem != (net_ConverterElement *)0); + return ((NET_StreamClass *) + ((*elem->converter) + (format_out, elem->data_obj, URL_s, context))); + } + } + } + + /* now search for content-type converters + */ + /* go through list of converters and choose + * the first exact or partial match we + * find. The order of the list + * is guarenteed by the registration + * routines + */ + while((cs_ptr=(net_ConverterStruct *) XP_ListNextObject(ct_list_ptr)) != 0) + { + if(format_out == cs_ptr->format_out) + if(net_compare_mime_types(URL_s->content_type, cs_ptr->format_in)) + { + net_ConverterElement *elem = XP_ListPeekTopObject(cs_ptr->converter_stack); + PR_ASSERT(elem != (net_ConverterElement *)0); + return( (NET_StreamClass *) (*elem->converter) (format_out, + elem->data_obj, URL_s, context)); + } + } + + TRACEMSG(("Alert! did not find a converter or decoder\n")); + FE_Alert(context, XP_GetString(XP_ALERT_CANTFIND_CONVERTER)); + + return(0); /* Uh-oh. didn't find a converter. VERY VERY BAD! */ +} + +/* prints out all presentation mime types during successive calls + * call with first equal true to reset to the beginning + * and with first equal false to print out the next + * converter in the list. Returns zero when all converters + * are printed out. + */ +MODULE_PRIVATE char * +XP_ListNextPresentationType(PRBool first) +{ + static XP_List * converter_list_ptr; + net_ConverterStruct * converter; + + /* reset list pointers + */ + if(first) + converter_list_ptr = net_converter_list[FO_PRESENT]; + + /* print out next converter if there are any more + */ + converter = (net_ConverterStruct *) XP_ListNextObject(converter_list_ptr); + + if(converter && converter->format_out == FO_PRESENT) + return(converter->format_in); + + /* else */ + return(NULL); +} + +/* prints out all encoding mime types during successive calls + * call with first equal true to reset to the beginning + * and with first equal false to print out the next + * converter in the list. Returns zero when all converters + * are printed out. + */ +MODULE_PRIVATE char * +XP_ListNextEncodingType(PRBool first) +{ + static XP_List * decoder_list_ptr; + net_ConverterStruct * converter; + static int count; + static index = 0; + static int curArrayIndex = 0; + + + while ((index < count) && (curArrayIndex < MAX_FORMATS_OUT)) { + decoder_list_ptr = net_decoder_list[curArrayIndex]; + count = XP_ListCount(decoder_list_ptr); + if (count > 0) { + index = 0; + break; + } + else count++; + } +#if 0 + /* reset list pointers + */ + if(first) + { + decoder_list_ptr = net_decoder_list; + } +#endif + converter = (net_ConverterStruct *) XP_ListNextObject(decoder_list_ptr); + if(converter) { + index++; + return(converter->format_in); + } + + /* else */ + return(NULL); +} + +PRIVATE void +net_RegisterGenericConverterOrDecoder(XP_List ** conv_list, + char * format_in, + char * encoding_in, + FO_Present_Types format_out, + void * data_obj, + NET_Converter * converter_func) +{ + XP_List * list_ptr = *conv_list; + net_ConverterStruct * converter_struct_ptr; + net_ConverterStruct * new_converter_struct; + net_ConverterElement *elem; + int f_in_type; + XP_List *pList; + int i; + + if (needInit) { /* MWH - this will only happen once. It is pretty ugly, + but I don't know how to get around it. */ + needInit = FALSE; + + for (i = 0; i format_out) + /* Rewritten to logic equivalent but should-be-faster version:*/ + if (((!encoding_in && !converter_struct_ptr->encoding_in) || + (encoding_in && converter_struct_ptr->encoding_in && + !PL_strcmp (encoding_in, + converter_struct_ptr->encoding_in))) + && !PL_strcasecmp(format_in, converter_struct_ptr->format_in) +#ifdef XP_WIN + && (converter_struct_ptr->bAutomated == autoFlag) +#endif + ) + { + /* Add a new converter element to the list */ + net_ConverterElement *elem = PR_NEWZAP(net_ConverterElement); + if( elem == (net_ConverterElement *)0 ) return; + elem->converter = converter_func; + elem->data_obj = data_obj; + XP_ListAddObject(converter_struct_ptr->converter_stack, elem); + return; + } + } + /* find out the type of entry format_in is + */ + f_in_type = NET_MIME_EXACT_MATCH; + if(PL_strchr(format_in, '*')) + { + if(!PL_strcmp(format_in, "*")) + f_in_type = NET_WILDCARD_MATCH; + else + f_in_type = NET_MIME_PARTIAL_MATCH; + } + + /* if existing converter not found/replaced + * add this converter to the list in + * its order of importance so that we can + * take the first exact or partial fit + */ + new_converter_struct = PR_NEW(net_ConverterStruct); + if(!new_converter_struct) { + return; + } + + new_converter_struct->converter_stack = XP_ListNew(); + if( new_converter_struct->converter_stack == (XP_List *)0 ) + { + PR_Free(new_converter_struct); + return; + } + + elem = PR_NEWZAP(net_ConverterElement); + if( elem == (net_ConverterElement *)0 ) + { + XP_ListDestroy(new_converter_struct->converter_stack); + PR_Free(new_converter_struct); + return; + } + + elem->converter = converter_func; + elem->data_obj = data_obj; + new_converter_struct->format_in = 0; + StrAllocCopy(new_converter_struct->format_in, format_in); + new_converter_struct->encoding_in = (encoding_in + ? PL_strdup (encoding_in) : 0); + new_converter_struct->format_out = format_out; + XP_ListAddObject(new_converter_struct->converter_stack, elem); + new_converter_struct->bAutomated = autoFlag; + + + if(!pList) { +/* if(!*conv_list) */ + /* create the list and add this object + * don't worry about order since there + * can't be any + */ + pList = XP_ListNew(); + if(!pList) + return; /* big error */ + conv_list[format_out] = pList; + XP_ListAddObject(pList, new_converter_struct); + return; + } + if(f_in_type == NET_MIME_EXACT_MATCH) + { +#if defined(XP_WIN) && defined (MOZILLA_CLIENT) + net_ConverterStruct *pRegistered; + XP_List *tempList = pList; + int count = XP_ListCount(tempList); + for (i = 0; i < count; i++) { + pRegistered = (net_ConverterStruct *) XP_ListNextObject(tempList); + + if(new_converter_struct->bAutomated == TRUE) { + if(pRegistered->bAutomated == FALSE) { + XP_ListInsertObject (pList, pRegistered, new_converter_struct); + return; + } + } + + /* if it is an exact match type + * then we can just add it to the beginning + * of the list + */ + if (!PL_strcasecmp(pRegistered->format_in, new_converter_struct->format_in) + && ((!pRegistered->encoding_in && !new_converter_struct->format_in) + || !PL_strcasecmp(pRegistered->encoding_in, new_converter_struct->encoding_in))) { + if(new_converter_struct->bAutomated == TRUE) { + PR_Free( new_converter_struct); + return; + } + + // Overwrite + memcpy(pRegistered, new_converter_struct, sizeof(net_ConverterStruct)); + PR_Free( new_converter_struct); + return; + } + } + + + + + + + + XP_ListInsertObject (pList, pRegistered, new_converter_struct); +#else + XP_ListAddObject(pList, new_converter_struct); + TRACEMSG(("Adding Converter to Beginning of list")); +#endif + } + else if(f_in_type == NET_MIME_PARTIAL_MATCH) + { + /* this is a partial wildcard of the form (image/(star)) + * store it at the end of all the exact match pairs + */ + list_ptr = pList; + while((converter_struct_ptr = (net_ConverterStruct *) XP_ListNextObject(list_ptr)) != 0) + { + if(PL_strchr(converter_struct_ptr->format_in, '*')) + { + XP_ListInsertObject (pList, + converter_struct_ptr, + new_converter_struct); + return; + } + } + /* else no * objects in list */ + XP_ListAddObjectToEnd(pList, new_converter_struct); + TRACEMSG(("Adding Converter to Middle of list")); + } + else + { + /* this is a very wild wildcard match of the form "*" only. + * It has the least precedence so store it at the end + * of the list. (There must always be at least one + * item in the list (see above)) + */ + XP_ListAddObjectToEnd(pList, new_converter_struct); + TRACEMSG(("Adding Converter to end of list")); + } +} + +struct net_encoding_converter +{ + char *encoding_in; + void *data_obj; + NET_Converter * converter_func; +}; + +static struct net_encoding_converter *net_all_encoding_converters; +static int net_encoding_converter_size = 0; +static int net_encoding_converter_fp = 0; + +PUBLIC void* NET_GETDataObject(XP_List* list, char* mineType, void** obj) +{ + net_ConverterStruct* converter_struct_ptr; + + *obj = (void*)0; + + while((converter_struct_ptr = (net_ConverterStruct *)XP_ListNextObject(list)) != NULL) { + if(converter_struct_ptr->bAutomated) { + if(!PL_strcmp(converter_struct_ptr->format_in, mineType)) { + net_ConverterElement *elem = XP_ListPeekTopObject(converter_struct_ptr->converter_stack); + *obj = (void*)converter_struct_ptr; + return elem->data_obj; + } + } + } + + return (void*)0; +} + +PUBLIC XP_List* NET_GetRegConverterList(FO_Present_Types iFormatOut) +{ + return net_converter_list[iFormatOut]; + +} +/* register a routine to decode a stream + */ + +PUBLIC void +NET_RegisterEncodingConverter(char *encoding_in, + void * data_obj, + NET_Converter * converter_func) +{ + + /* Don't register anything right now, but remember that we have a + decoder for this so that we can register it hither and yon at + a later date. + */ + if (net_encoding_converter_size <= net_encoding_converter_fp) + { + net_encoding_converter_size += 10; + if (net_all_encoding_converters) + net_all_encoding_converters = (struct net_encoding_converter *) + PR_Realloc (net_all_encoding_converters, + net_encoding_converter_size + * sizeof (*net_all_encoding_converters)); + else + net_all_encoding_converters = (struct net_encoding_converter *) + PR_Calloc (net_encoding_converter_size, + sizeof (*net_all_encoding_converters)); + } + + { /* Don't register the same decoder twice; having too many + decoders is multiplicatively expensive with respect to the number of + calls to net_RegisterGenericConverterOrDecoder() from the loop inside + NET_RegisterAllEncodingConverters(). */ + int i; + for (i=0; i < net_encoding_converter_fp; i++) + if ((net_all_encoding_converters[i].data_obj == data_obj) + && (net_all_encoding_converters[i].converter_func == converter_func) + && (strcmp(net_all_encoding_converters[i].encoding_in,encoding_in) + == 0)) + return; + } + + net_all_encoding_converters [net_encoding_converter_fp].encoding_in + = PL_strdup (encoding_in); + net_all_encoding_converters [net_encoding_converter_fp].data_obj + = data_obj; + net_all_encoding_converters [net_encoding_converter_fp].converter_func + = converter_func; + net_encoding_converter_fp++; + +} + + +#ifdef MOZILLA_CLIENT + +void +NET_DumpDecoders() +{ +#ifdef DEBUG + net_ConverterStruct * cs_ptr; + XP_List *list_ptr = net_decoder_list[FO_PRESENT]; + + while((cs_ptr = XP_ListNextObject(list_ptr))) + { + char *msg = PR_smprintf("in: %s out: %d\n",cs_ptr->encoding_in, cs_ptr->format_out); + + TRACEMSG(("%s", msg)); + FREE(msg); + } +#endif /* DEBUG */ +} + +/* register an encoding converter that is used for everything, + * no exeptions + * this is necessary for chunked encoding + */ +MODULE_PRIVATE void +NET_RegisterUniversalEncodingConverter(char *encoding_in, + void * data_obj, + NET_Converter * converter_func) +{ + int i; + + /* for each list in the net_decoder_list array */ + for (i = 0; i < MAX_FORMATS_OUT; i++) + { + + net_RegisterGenericConverterOrDecoder (net_decoder_list, + "*", + encoding_in, + i, /* format out */ + data_obj, + converter_func); + } + +} + +void +NET_RegisterAllEncodingConverters (char *format_in, + FO_Present_Types format_out) +{ + int i; + +#ifdef XP_UNIX + /* On Unix at least, there should be *some* registered... */ + assert (net_encoding_converter_fp > 0); +#endif + + for (i = 0; i < net_encoding_converter_fp; i++) + { + char *encoding_in = net_all_encoding_converters [i].encoding_in; + void *data_obj = net_all_encoding_converters [i].data_obj; + NET_Converter *func = net_all_encoding_converters [i].converter_func; + + net_RegisterGenericConverterOrDecoder (net_decoder_list, + format_in, + encoding_in, + format_out, + data_obj, + func); + + net_RegisterGenericConverterOrDecoder (net_decoder_list, + format_in, + encoding_in, + format_out | FO_CACHE_ONLY, + data_obj, + func); + + net_RegisterGenericConverterOrDecoder (net_decoder_list, + format_in, + encoding_in, + format_out | FO_ONLY_FROM_CACHE, + data_obj, + func); + } +} + +#endif /* MOZILLA_CLIENT */ + + + + +/* Register a routine to convert between format_in and format_out + * + */ +#if (defined(XP_WIN) || defined(XP_OS2)) && defined(MOZILLA_CLIENT) +/* Reroute XP handling of streams for windows. + * MWH -This routine should not be called recursively. + It rely on the static global variable to set the + * automatedflag. The reason for this is I don't to + change the API on NET_RegisterContentTypeConverter + because some other group still depend on this API. + * If we decided to change API, please fix this. + */ +PUBLIC void +NET_RegContentTypeConverter (char * format_in, + FO_Present_Types format_out, + void * data_obj, + NET_Converter * converter_func, + Bool bAutomated) +{ + autoFlag = bAutomated; + NET_RegisterContentTypeConverter (format_in, format_out, + data_obj, + converter_func); + autoFlag = FALSE; + +} + +#endif + +PUBLIC void +NET_RegisterContentTypeConverter (char * format_in, + FO_Present_Types format_out, + void * data_obj, + NET_Converter * converter_func) +{ + net_RegisterGenericConverterOrDecoder(net_converter_list, + format_in, + 0, + format_out, + data_obj, + converter_func); + +} + +#ifdef MOZILLA_CLIENT +#ifdef XP_UNIX + +#include "cvview.h" +#include "cvextcon.h" + +/* register a mime type and a command to be executed + * + * if stream_block_size is zero then the data will be completely + * pooled and the external viewer called with the filename. + * if stream_block_size is greater than zero the viewer will be + * called with a popen and the stream_block_size will be used as + * the maximum size of each buffer to pass to the viewer + */ +MODULE_PRIVATE void +NET_RegisterExternalViewerCommand(char * format_in, + char * system_command, + unsigned int stream_block_size) +{ + CV_ExtViewStruct * new_obj = PR_NEW(CV_ExtViewStruct); + + if(!new_obj) + return; + + memset(new_obj, 0, sizeof(CV_ExtViewStruct)); + + /* make a new copy of the command so it can be passed + * as the data object + */ + StrAllocCopy(new_obj->system_command, system_command); + new_obj->stream_block_size = stream_block_size; + + /* register the routine + */ + NET_RegisterContentTypeConverter(format_in, FO_PRESENT, new_obj, NET_ExtViewerConverter); + + /* Also register the content-encoding converters on this type. + Those get registered only on types we know how to display, + either internally or externally - and don't get registered + on types we know nothing about. + */ + NET_RegisterAllEncodingConverters (format_in, FO_PRESENT); +} + +/* removes all external viewer commands + */ +PUBLIC void +NET_ClearExternalViewerConverters(void) +{ + XP_List * list_ptr; + XP_List *temp_list; + net_ConverterStruct * converter_struct_ptr; + int i; + + for (i = 0; i converter_stack)) != (net_ConverterElement *)0 ) + { + if( elem->converter == NET_ExtViewerConverter ) + { + PR_FREEIF(elem->data_obj); + PR_Free(elem); + continue; + } + else + { + XP_ListAddObjectToEnd(new, elem); + } + } + + XP_ListDestroy(converter_struct_ptr->converter_stack); + + if( XP_ListCount(new) > 0 ) + { + converter_struct_ptr->converter_stack = new; + } + else + { + XP_ListDestroy(new); + XP_ListRemoveObject(temp_list, converter_struct_ptr); + PR_Free(converter_struct_ptr->format_in); + PR_Free(converter_struct_ptr->encoding_in); + PR_Free(converter_struct_ptr); + } + } + } +} + +/* removes all registered converters of any kind + */ +PUBLIC void +NET_ClearAllConverters(void) +{ + net_ConverterStruct * aConverter; + net_ConverterElement * aConverterStackElement; + XP_List * theList; + int i; + + /* for each list in the net_converter_list array */ + for (i = 0; i < MAX_FORMATS_OUT; i++) { + theList = net_converter_list[i]; + /* Traverse it, removing each converter, and freeing its data */ + while( aConverter = (net_ConverterStruct *) XP_ListRemoveTopObject(theList) ) + { + FREEIF(aConverter->format_in); + FREEIF(aConverter->encoding_in); + while( aConverterStackElement = XP_ListRemoveTopObject(aConverter->converter_stack) ) + { +#ifdef XP_UNIX + if(aConverterStackElement->converter == NET_ExtViewerConverter) + PR_FREEIF(aConverterStackElement->data_obj); +#endif /* XP_UNIX */ + PR_Free(aConverterStackElement); + } + XP_ListDestroy(aConverter->converter_stack); + FREE(aConverter); + } + XP_ListDestroy(theList); + net_converter_list[i] = NULL; + } + + /* for each list in the net_decoder_list array */ + for (i = 0; i < MAX_FORMATS_OUT; i++) { + theList = net_decoder_list[i]; + /* Traverse it, removing each converter, and freeing its data */ + while( aConverter = (net_ConverterStruct *) XP_ListRemoveTopObject(theList) ) + { + FREEIF(aConverter->format_in); + FREEIF(aConverter->encoding_in); + while( aConverterStackElement = XP_ListRemoveTopObject(aConverter->converter_stack) ) + { +#ifdef XP_UNIX + if(aConverterStackElement->converter == NET_ExtViewerConverter) + PR_FREEIF(aConverterStackElement->data_obj); +#endif /* XP_UNIX */ + PR_Free(aConverterStackElement); + } + XP_ListDestroy(aConverter->converter_stack); + FREE(aConverter); + } + XP_ListDestroy(theList); + net_decoder_list[i] = NULL; + } +} + +/* register an external program to act as a content-type + * converter + */ +MODULE_PRIVATE void +NET_RegisterExternalConverterCommand(char * format_in, + int format_out, + char * system_command, + char * new_format) +{ + CV_ExtConverterStruct * new_obj = PR_NEW(CV_ExtConverterStruct); + + if(!new_obj) + return; + + memset(new_obj, 0, sizeof(CV_ExtConverterStruct)); + + /* make a new copy of the command so it can be passed + * as the data object + */ + StrAllocCopy(new_obj->command, system_command); + StrAllocCopy(new_obj->new_format, new_format); + new_obj->is_encoding_converter = FALSE; + + /* register the routine + */ + NET_RegisterContentTypeConverter(format_in, format_out, new_obj, NET_ExtConverterConverter); +} + +/* register an external program to act as a content-encoding + * converter + */ +PUBLIC void +NET_RegisterExternalDecoderCommand (char * format_in, + char * format_out, + char * system_command) +{ + CV_ExtConverterStruct * new_obj = PR_NEW(CV_ExtConverterStruct); + + if(!new_obj) + return; + + memset(new_obj, 0, sizeof(CV_ExtConverterStruct)); + + /* make a new copy of the command so it can be passed + * as the data object + */ + StrAllocCopy(new_obj->command, system_command); + StrAllocCopy(new_obj->new_format, format_out); + new_obj->is_encoding_converter = TRUE; + + /* register the routine + */ + NET_RegisterEncodingConverter (format_in, new_obj, + NET_ExtConverterConverter); +} + + +#endif /* XP_UNIX */ +#endif /* MOZILLA_CLIENT */ + +/* NewMKStream + * Utility to create a new initialized NET_StreamClass object + */ +NET_StreamClass * +NET_NewStream (char *name, + MKStreamWriteFunc process, + MKStreamCompleteFunc complete, + MKStreamAbortFunc abort, + MKStreamWriteReadyFunc ready, + void *streamData, + MWContext *windowID) +{ + NET_StreamClass *stream = PR_NEW (NET_StreamClass); + if (!stream) + return nil; + + stream->name = name; + stream->window_id = windowID; + stream->data_object = streamData; + stream->put_block = process; + stream->complete = complete; + stream->abort = abort; + stream->is_write_ready = ready; + + return stream; +} + +PRIVATE XP_List * +net_GetConverterOrDecoderList(XP_List ** conv_list, + char * format_in, + char * encoding_in, + FO_Present_Types format_out) +{ + XP_List * list_ptr = *conv_list; + net_ConverterStruct * converter_struct_ptr; + + while((converter_struct_ptr = (net_ConverterStruct *) XP_ListNextObject(list_ptr)) != 0) + if(format_out == converter_struct_ptr->format_out) + if(!PL_strcasecmp(format_in, converter_struct_ptr->format_in) + && ((!encoding_in && !converter_struct_ptr->encoding_in) || + (encoding_in && converter_struct_ptr->encoding_in && + !PL_strcmp (encoding_in, + converter_struct_ptr->encoding_in))) + ) + { + return converter_struct_ptr->converter_stack; + } + + return (XP_List *)0; +} + +PUBLIC void +NET_DeregisterContentTypeConverter(char *format_in, FO_Present_Types format_out) +{ + XP_List *l; + net_ConverterElement *elem; + + l = net_GetConverterOrDecoderList(net_converter_list, format_in, 0, format_out); + if( l == (XP_List *)0 ) return; + + elem = XP_ListRemoveTopObject(l); +# ifdef XP_UNIX + /* total kludge!! */ + if( elem->converter == NET_ExtViewerConverter ) + PR_FREEIF(elem->data_obj); +# endif + PR_Free(elem); + + return; +} + +#ifdef DEBUG +MODULE_PRIVATE void +NET_DisplayStreamInfoAsHTML(ActiveEntry *cur_entry) +{ + char *buffer = (char*)PR_Malloc(2048); + NET_StreamClass * stream; + int i; + + static char *fo_names[] = { + /* 0 */ "(unknown)", + /* 1 */ "Present", + /* 2 */ "Internal Image", + /* 3 */ "Out to Proxy Client", + /* 4 */ "View Source", + /* 5 */ "Save As", + /* 6 */ "Save as Text", + /* 7 */ "Save as Postscript", + /* 8 */ "Quote Message", + /* 9 */ "Mail To", + /* 10 */ "OLE Network", + /* 11 */ "Multipart Image", + /* 12 */ "Embed", + /* 13 */ "Print", + /* 14 */ "Plugin", + /* 15 */ "Append to Folder", + /* 16 */ "Do Java", + /* 17 */ "Byterange", + /* 18 */ "EDT Save Image", + /* 19 */ "Edit", + /* 20 */ "Load HTML Help Map File", + /* 21 */ "Save to News DB", + /* 22 */ "Open Draft", + }; + + if(!buffer) + { + cur_entry->status = MK_UNABLE_TO_CONVERT; + return; + } + + StrAllocCopy(cur_entry->URL_s->content_type, TEXT_HTML); + + cur_entry->format_out = CLEAR_CACHE_BIT(cur_entry->format_out); + stream = NET_StreamBuilder(cur_entry->format_out, + cur_entry->URL_s, + cur_entry->window_id); + + if(!stream) + { + cur_entry->status = MK_UNABLE_TO_CONVERT; + FREE(buffer); + return; + } + + + /* define a macro to push a string up the stream + * and handle errors + */ +#define PUT_PART(part) \ +cur_entry->status = (*stream->put_block)(stream, \ + part ? part : "Unknown", \ + part ? PL_strlen(part) : 7); \ +if(cur_entry->status < 0) \ + goto END; + + sprintf(buffer, +"Information about the Netscape streams configuration\n" +"

Information about the Netscape streams configuration

\n" +); + + PUT_PART(buffer); + + sprintf(buffer, "

Converter List

\n\n"); + PUT_PART(buffer); + + sprintf(buffer, "

Decoder List

\n\n"); + PUT_PART(buffer); + + END: + PR_Free(buffer); + if( cur_entry->status < 0 ) + (*stream->abort)(stream, cur_entry->status); + else + (*stream->complete)(stream); + + return; +} + +#endif /* DEBUG */ + +#ifdef PROFILE +#pragma profile off +#endif + diff --git a/mozilla/network/cstream/cstream.h b/mozilla/network/cstream/cstream.h new file mode 100644 index 00000000000..dc40eab4c7b --- /dev/null +++ b/mozilla/network/cstream/cstream.h @@ -0,0 +1,142 @@ +/* -*- 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. + */ +#ifndef CSTREAM_H +#define CSTREAM_H + +XP_BEGIN_PROTOS + +/* builds an outgoing stream and returns a stream class structure + * containing a stream function table + */ +extern NET_StreamClass * NET_StreamBuilder ( + FO_Present_Types format_out, + URL_Struct * anchor, + MWContext * window_id); + +/* stream functions + */ +typedef unsigned int +(*MKStreamWriteReadyFunc) (NET_StreamClass *stream); + +#define MAX_WRITE_READY (((unsigned) (~0) << 1) >> 1) /* must be <= than MAXINT */ + +typedef int +(*MKStreamWriteFunc) (NET_StreamClass *stream, const char *str, int32 len); + +typedef void +(*MKStreamCompleteFunc) (NET_StreamClass *stream); + +typedef void +(*MKStreamAbortFunc) (NET_StreamClass *stream, int status); + +/* + * NewMKStream + * Utility to create a new initialized NET_StreamClass object + */ +extern NET_StreamClass * NET_NewStream(char *, + MKStreamWriteFunc, + MKStreamCompleteFunc, + MKStreamAbortFunc, + MKStreamWriteReadyFunc, + void *, + MWContext *); +/* streamclass function + */ +struct _NET_StreamClass { + + char * name; /* Just for diagnostics */ + + MWContext * window_id; /* used for progress messages, etc. */ + + void * data_object; /* a pointer to whatever + * structure you wish to have + * passed to the routines below + * during writes, etc... + * + * this data object should hold + * the document, document + * structure or a pointer to the + * document. + */ + + MKStreamWriteReadyFunc is_write_ready; /* checks to see if the stream is ready + * for writing. Returns 0 if not ready + * or the number of bytes that it can + * accept for write + */ + + MKStreamWriteFunc put_block; /* writes a block of data to the stream */ + MKStreamCompleteFunc complete; /* normal end */ + MKStreamAbortFunc abort; /* abnormal end */ + + Bool is_multipart; /* is the stream part of a multipart sequence */ +}; + + + +/* prints out all converter mime types during successive calls + * call with first equal true to reset to the beginning + * and with first equal false to print out the next + * converter in the list. Returns zero when all converters + * are printed out. + */ +extern char * +XP_ListNextPresentationType(XP_Bool first); + +/* prints out all encoding mime types during successive calls + * call with first equal true to reset to the beginning + * and with first equal false to print out the next + * converter in the list. Returns zero when all converters + * are printed out. + */ +extern char * +XP_ListNextEncodingType(XP_Bool first); + +/* register a mime type and a command to be executed + */ +extern void +NET_RegisterExternalViewerCommand(char * format_in, + char * system_command, + unsigned int stream_block_size); + +/* removes all external viewer commands + */ +extern void NET_ClearExternalViewerConverters(void); + +MODULE_PRIVATE void +NET_RegisterExternalConverterCommand(char * format_in, + FO_Present_Types format_out, + char * system_command, + char * new_format); + +void +NET_RegisterAllEncodingConverters (char *format_in, + FO_Present_Types format_out); + +/* register an encoding converter that is used for everything, + * no exeptions + * this is necessary for chunked encoding + */ +void +NET_RegisterUniversalEncodingConverter(char *encoding_in, + void * data_obj, + NET_Converter * converter_func); + +XP_END_PROTOS + +#endif /* CSTREAM.h */ diff --git a/mozilla/network/cstream/makefile.win b/mozilla/network/cstream/makefile.win new file mode 100644 index 00000000000..128a84b6d2c --- /dev/null +++ b/mozilla/network/cstream/makefile.win @@ -0,0 +1,89 @@ +#!gmake +# +# 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. + +IGNORE_MANIFEST=1 +# + +#------------------------------------------------------------------------ +# +# Makefile to build the cstream LIB +# +#------------------------------------------------------------------------ + +# +# Make sure we have MOZILLA_CLIENT defined so we get the +# proper JS includes +# +LCFLAGS = $(LCFLAGS) -DMOZILLA_CLIENT + +!ifdef BUILD_DEBUG_GC +LCFLAGS = $(LCFLAGS) -DDEBUG_GC +!endif + +LLIBS= \ + $(NULL) +MISCDEP=$(LLIBS) +OBJS= \ + .\$(OBJDIR)\cstream.obj \ + $(NULL) + + +CSRCS = \ + cstream.c \ + $(NULL) + + +LIBRARY_NAME=cstream + +MODULE=cstream +DEPTH=..\.. + +EXTRA_LIBS= + +REQUIRES= network nspr2 +EXPORTS= cstream.h strmutil.h + +C_OBJS = \ + $(NULL) + + +# use LINCS on win32 for now since REQUIRES seems to be broken +#!if "$(MOZ_BITS)" != "16" +LINCS= \ + -I$(XPDIST)\public\nspr2 \ + -I$(XPDIST)\public\dbm \ + -I$(XPDIST)\public\util \ + -I$(XPDIST)\public\pref \ + -I$(XPDIST)\public\network \ + -I$(XPDIST)\public\js \ + -I$(XPDIST)\public\java \ + -I$(XPDIST)\public\fileurl \ + -I$(XPDIST)\public\security \ + -I$(XPDIST)\public\jtools +#!endif + +include <$(DEPTH)\config\rules.mak> + +libs:: $(LIBRARY) + +install:: + $(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib + + +symbols:: + @echo "LIBRARY_NAME is $(LIBRARY_NAME)" + @echo "LIBRARY is $(LIBRARY)" diff --git a/mozilla/network/cstream/strmutil.h b/mozilla/network/cstream/strmutil.h new file mode 100644 index 00000000000..2bd582b8403 --- /dev/null +++ b/mozilla/network/cstream/strmutil.h @@ -0,0 +1,9 @@ + +#ifndef STRMUTIL_H +#define STRMUTIL_H + +#ifdef DEBUG +extern void NET_DisplayStreamInfoAsHTML(ActiveEntry *cur_entry); +#endif /* DEBUG */ + +#endif /* STRMUTIL_H */