Form submission performance / maintability improvements (bug 120682) r=alexsavulov,r=sicking,sr=jst

This commit is contained in:
jkeiser%netscape.com 2002-02-16 01:19:24 +00:00
Родитель 2afd472bc6
Коммит fe1d4d2f35
39 изменённых файлов: 3046 добавлений и 458 удалений

Просмотреть файл

@ -3,6 +3,7 @@
#
nsIForm.h
nsIFormControl.h
nsIFormSubmission.h
nsILink.h
nsIOptionElement.h
nsIScriptElement.h

Просмотреть файл

@ -40,6 +40,7 @@ EXPORTS = \
nsIOptionElement.h \
nsITextControlElement.h \
nsIScriptElement.h \
nsIFormSubmission.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -32,6 +32,7 @@ EXPORTS= \
nsIOptionElement.h \
nsIScriptElement.h \
nsITextControlElement.h \
nsIFormSubmission.h \
$(NULL)
MODULE=content

Просмотреть файл

@ -45,6 +45,7 @@ class nsIPresState;
class nsIContent;
class nsString;
class nsIFormProcessor;
class nsIFormSubmission;
#define NS_FORM_BROWSE 0
#define NS_FORM_BUTTON_BUTTON 1
@ -97,6 +98,8 @@ public:
/**
* Set the form for this form control.
* @param aForm the form
* @param aRemoveFromForm set false if you do not want this element removed
* from the form. (Used by evil DemoteForm() method.)
* @return NS_OK
*/
NS_IMETHOD SetForm(nsIDOMHTMLFormElement* aForm,
@ -109,16 +112,21 @@ public:
*/
NS_IMETHOD GetType(PRInt32* aType) = 0;
/**
* Reset this form control
*/
NS_IMETHOD Reset() = 0;
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval) = 0;
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval) = 0;
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames) = 0;
/**
* Tells the form control to submit its names and values to the form
* submission object
* @param aFormSubmission the form submission to notify of names/values/files
* to submit
* @param aSubmitElement the element that was pressed to submit (possibly
* null)
*/
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement) = 0;
/**
* Save to presentation state

Просмотреть файл

@ -0,0 +1,130 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIFormSubmission_h___
#define nsIFormSubmission_h___
#include "nsISupports.h"
class nsAString;
class nsACString;
class nsIURI;
class nsIInputStream;
class nsIForm;
class nsIPresContext;
class nsIContent;
class nsIFormControl;
class nsIDOMHTMLElement;
#define NS_IFORMSUBMITTER_IID \
{ 0x7ee38e3a, 0x1dd2, 0x11b2, \
{0x89, 0x6f, 0xab, 0x28, 0x03, 0x96, 0x25, 0xa9} }
/**
* Interface for form submissions; encompasses the function to call to submit as
* well as the form submission name/value pairs
*/
class nsIFormSubmission : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFORMSUBMITTER_IID)
/**
* Find out whether or not this form submission accepts files
*
* @param aAcceptsFiles the boolean output
*/
NS_IMETHOD AcceptsFiles(PRBool* aAcceptsFiles) = 0;
/**
* Call to perform the submission
*
* @param aActionURL the URL to submit to (may be modified with GET contents)
* @param aTarget the target window
* @param aSource the element responsible for the submission (for web shell)
* @param aPresContext the presentation context
*/
NS_IMETHOD SubmitTo(nsIURI* aActionURL, const nsAString& aTarget,
nsIContent* aSource, nsIPresContext* aPresContext) = 0;
/**
* Submit a name/value pair
*
* @param aSource the control sending the parameter
* @param aName the name of the parameter
* @param aValue the value of the parameter
*/
NS_IMETHOD AddNameValuePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aValue) = 0;
/**
* Submit a name/file pair
*
* @param aSource the control sending the parameter
* @param aName the name of the parameter
* @param aFilename the name of the file (pass null to provide no name)
* @param aStream the stream containing the file data to be sent
* @param aContentType the content-type of the file data being sent
* @param aMoreFilesToCome true if another name/file pair with the same name
* will be sent soon
*/
NS_IMETHOD AddNameFilePair(nsIDOMHTMLElement* aSource,
const nsAString& aName,
const nsAString& aFilename,
nsIInputStream* aStream,
const nsACString& aContentType,
PRBool aMoreFilesToCome) = 0;
};
//
// Factory methods
//
/**
* Get a submission object based on attributes in the form (ENCTYPE and METHOD)
*
* @param aForm the form to get a submission object based on
* @param aPresContext the presentation context
* @param aFormSubmission the form submission object (out param)
*/
nsresult GetSubmissionFromForm(nsIForm* aForm, nsIPresContext* aPresContext,
nsIFormSubmission** aFormSubmission);
#endif /* nsIFormSubmission_h___ */

Просмотреть файл

@ -59,7 +59,7 @@ CPPSRCS = \
nsGenericHTMLElement.cpp \
nsGenericDOMHTMLCollection.cpp \
GenericElementCollection.cpp \
nsFormSubmitter.cpp \
nsFormSubmission.cpp \
nsHTMLAnchorElement.cpp \
nsHTMLAppletElement.cpp \
nsHTMLAreaElement.cpp \

Просмотреть файл

@ -65,7 +65,7 @@ CPP_OBJS= \
.\$(OBJDIR)\nsGenericHTMLElement.obj \
.\$(OBJDIR)\nsGenericDOMHTMLCollection.obj \
.\$(OBJDIR)\GenericElementCollection.obj \
.\$(OBJDIR)\nsFormSubmitter.obj \
.\$(OBJDIR)\nsFormSubmission.obj \
.\$(OBJDIR)\nsHTMLAnchorElement.obj \
.\$(OBJDIR)\nsHTMLAppletElement.obj \
.\$(OBJDIR)\nsHTMLAreaElement.obj \

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -48,6 +48,7 @@
#include "nsIPresContext.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIFormSubmission.h"
#include "nsIURL.h"
#include "nsIFrame.h"
@ -90,12 +91,8 @@ public:
// overrided nsIFormControl method
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD Reset();
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval);
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval);
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames);
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
// nsIContent overrides...
NS_IMETHOD GetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
@ -126,7 +123,6 @@ private:
// The analogue of defaultValue in the DOM for input and textarea
nsresult SetDefaultValue(const nsAReadableString& aDefaultValue);
nsresult GetDefaultValue(nsAWritableString& aDefaultValue);
};
@ -582,63 +578,56 @@ nsHTMLButtonElement::SetDefaultValue(const nsAReadableString& aDefaultValue)
return SetAttr(kNameSpaceID_HTML, nsHTMLAtoms::value, aDefaultValue, PR_TRUE);
}
nsresult
NS_IMETHODIMP
nsHTMLButtonElement::Reset()
{
return NS_OK;
}
nsresult
nsHTMLButtonElement::IsSuccessful(nsIContent* aSubmitElement,
PRBool *_retval)
NS_IMETHODIMP
nsHTMLButtonElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
*_retval = PR_FALSE;
nsresult rv = NS_OK;
//
// We only submit if we were the button pressed
//
if (aSubmitElement != this) {
return NS_OK;
}
// if it's disabled, it won't submit
//
// Disabled elements don't submit
//
PRBool disabled;
nsresult rv = GetDisabled(&disabled);
NS_ENSURE_SUCCESS(rv, rv);
if (disabled) {
return NS_OK;
rv = GetDisabled(&disabled);
if (NS_FAILED(rv) || disabled) {
return rv;
}
// If there is no name, it won't submit
nsAutoString val;
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, val);
*_retval = rv != NS_CONTENT_ATTR_NOT_THERE;
return NS_OK;
}
nsresult
nsHTMLButtonElement::GetMaxNumValues(PRInt32 *_retval)
{
*_retval = 1;
return NS_OK;
}
nsresult
nsHTMLButtonElement::GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames)
{
NS_ENSURE_TRUE(aMaxNumValues >= 1, NS_ERROR_UNEXPECTED);
// We'll of course use the name of the control for the submit
//
// Get the name (if no name, no submit)
//
nsAutoString name;
nsresult rv = GetName(name);
NS_ENSURE_SUCCESS(rv, rv);
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, name);
if (NS_FAILED(rv) || rv == NS_CONTENT_ATTR_NOT_THERE) {
return rv;
}
//
// Get the value
//
nsAutoString value;
rv = GetValue(value);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
return rv;
}
aNames[0] = name;
aValues[0] = value;
aNumValues = 1;
return NS_OK;
//
// Submit
//
rv = aFormSubmission->AddNameValuePair(this, name, value);
return rv;
}

Просмотреть файл

@ -75,10 +75,8 @@ public:
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD Reset();
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval);
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval);
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues,
nsString* aValues, nsString* aNames);
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
#ifdef DEBUG
// nsIContent
@ -208,27 +206,9 @@ nsHTMLFieldSetElement::Reset()
return NS_OK;
}
nsresult
nsHTMLFieldSetElement::IsSuccessful(nsIContent* aSubmitElement,
PRBool *_retval)
NS_IMETHODIMP
nsHTMLFieldSetElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
*_retval = PR_FALSE;
return NS_OK;
}
nsresult
nsHTMLFieldSetElement::GetMaxNumValues(PRInt32 *_retval)
{
*_retval = 0;
return NS_OK;
}
nsresult
nsHTMLFieldSetElement::GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames)
{
aNumValues = 0;
return NS_OK;
}

Просмотреть файл

@ -39,7 +39,7 @@
#include "nsIForm.h"
#include "nsIFormControl.h"
#include "nsIFormManager.h"
#include "nsFormSubmitter.h"
#include "nsIFormSubmission.h"
#include "nsIDOMHTMLFormElement.h"
#include "nsIDOMNSHTMLFormElement.h"
#include "nsIHTMLDocument.h"
@ -63,7 +63,18 @@
#include "nsHashtable.h"
#include "nsContentList.h"
#include "nsGUIEvent.h"
// form submission
#include "nsIFormSubmitObserver.h"
#include "nsIURI.h"
#include "nsIObserverService.h"
#include "nsICategoryManager.h"
#include "nsISimpleEnumerator.h"
#include "nsIDOMWindowInternal.h"
#include "nsRange.h"
#include "nsIScriptSecurityManager.h"
#include "nsNetUtil.h"
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
@ -131,16 +142,72 @@ protected:
nsresult DoSubmitOrReset(nsIPresContext* aPresContext,
nsEvent* aEvent,
PRInt32 aMessage);
nsresult DoReset();
NS_IMETHOD OnReset(nsIPresContext* aPresContext);
nsresult RemoveSelfAsWebProgressListener();
//
// Submit Helpers
//
//
/**
* Actually perform the submit (called by DoSubmitOrReset)
*
* @param aPresContext the presentation context
* @param aEvent the DOM event that was passed to us for the submit
*/
nsresult DoSubmit(nsIPresContext* aPresContext, nsEvent* aEvent);
/**
* Walk over the form elements and call SubmitNamesValues() on them to get
* their data pumped into the FormSubmitter.
*
* @param aFormSubmission the form submission object
* @param aSubmitElement the element that was clicked on (nsnull if none)
*/
nsresult WalkFormElements(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
/**
* Get the full URL to submit to. Do not submit if the returned URL is null.
*
* @param aActionURL the full, unadulterated URL you'll be submitting to
*/
nsresult GetActionURL(nsIURI** aActionURL);
/**
* Notify any submit observsers of the submit.
*
* @param aActionURL the URL being submitted to
* @param aCancelSubmit out param where submit observers can specify that the
* submit should be cancelled.
*/
nsresult NotifySubmitObservers(nsIURI* aActionURL, PRBool* aCancelSubmit);
/**
* Compare two nodes in the same tree (Negative result means a < b, 0 ==,
* positive >). This function may fail if the nodes are not in a tree
* or are in different trees.
*
* @param a the first node
* @param b the second node
* @param retval whether a < b (negative), a == b (0), or a > b (positive)
*/
static nsresult CompareNodes(nsIDOMNode* a,
nsIDOMNode* b,
PRInt32* retval);
//
// Data members
//
nsFormControlList *mControls;
PRPackedBool mGeneratingSubmit;
PRPackedBool mGeneratingReset;
PRPackedBool mDemotingForm;
protected:
// Detection of first form to notify observers
static PRBool gFirstFormSubmitted;
};
PRBool nsHTMLFormElement::gFirstFormSubmitted = PR_FALSE;
// nsFormControlList
class nsFormControlList : public nsIDOMNSHTMLFormControlList,
public nsIDOMHTMLCollection
@ -324,9 +391,7 @@ nsHTMLFormElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
nsCOMPtr<nsIDOMNode> kungFuDeathGrip(it);
nsresult rv = it->Init(mNodeInfo);
if (NS_FAILED(rv))
return rv;
NS_ENSURE_SUCCESS(rv, rv);
CopyInnerTo(this, it, aDeep);
@ -520,7 +585,8 @@ nsHTMLFormElement::HandleDOMEvent(nsIPresContext* aPresContext,
nsresult
nsHTMLFormElement::DoSubmitOrReset(nsIPresContext* aPresContext,
nsEvent* aEvent,
PRInt32 aMessage) {
PRInt32 aMessage)
{
NS_ENSURE_ARG_POINTER(aPresContext);
// Make sure the presentation is up-to-date
@ -535,27 +601,16 @@ nsHTMLFormElement::DoSubmitOrReset(nsIPresContext* aPresContext,
// Submit or Reset the form
nsresult rv = NS_OK;
if (NS_FORM_RESET == aMessage) {
rv = OnReset(aPresContext);
rv = DoReset();
}
else if (NS_FORM_SUBMIT == aMessage) {
nsIContent *originatingElement = nsnull;
// Get the originating frame (failure is non-fatal)
if (aEvent) {
if (NS_FORM_EVENT == aEvent->eventStructType) {
originatingElement = ((nsFormEvent *)aEvent)->originator;
}
}
// Pass the form originator
rv = nsFormSubmitter::OnSubmit(this, aPresContext, originatingElement);
rv = DoSubmit(aPresContext, aEvent);
}
return rv;
}
// JBK moved from nsFormFrame - bug 34297
NS_IMETHODIMP
nsHTMLFormElement::OnReset(nsIPresContext* aPresContext)
nsresult
nsHTMLFormElement::DoReset()
{
// JBK walk the elements[] array instead of form frame controls - bug 34297
PRUint32 numElements;
@ -571,6 +626,326 @@ nsHTMLFormElement::OnReset(nsIPresContext* aPresContext)
return NS_OK;
}
nsresult
nsHTMLFormElement::DoSubmit(nsIPresContext* aPresContext, nsEvent* aEvent)
{
nsIContent *originatingElement = nsnull;
// Get the originating frame (failure is non-fatal)
if (aEvent) {
if (NS_FORM_EVENT == aEvent->eventStructType) {
originatingElement = ((nsFormEvent *)aEvent)->originator;
}
}
//
// Get the submission object
//
nsCOMPtr<nsIFormSubmission> submission;
nsresult rv = GetSubmissionFromForm(this, aPresContext,
getter_AddRefs(submission));
NS_ENSURE_SUCCESS(rv, rv);
//
// Dump the data into the submission object
//
rv = WalkFormElements(submission, originatingElement);
NS_ENSURE_SUCCESS(rv, rv);
//
// Get the action and target
//
nsCOMPtr<nsIURI> actionURI;
rv = GetActionURL(getter_AddRefs(actionURI));
NS_ENSURE_SUCCESS(rv, rv);
if (actionURI) {
nsAutoString target;
rv = GetTarget(target);
NS_ENSURE_SUCCESS(rv, rv);
//
// Notify observers of submit
//
PRBool aCancelSubmit = PR_FALSE;
rv = NotifySubmitObservers(actionURI, &aCancelSubmit);
NS_ENSURE_SUCCESS(rv, rv);
if (!aCancelSubmit) {
//
// Submit
//
rv = submission->SubmitTo(actionURI, target, this, aPresContext);
}
}
return rv;
}
nsresult
nsHTMLFormElement::NotifySubmitObservers(nsIURI* aActionURL,
PRBool* aCancelSubmit)
{
// If this is the first form, bring alive the first form submit
// category observers
if (!gFirstFormSubmitted) {
gFirstFormSubmitted = PR_TRUE;
NS_CreateServicesFromCategory(NS_FIRST_FORMSUBMIT_CATEGORY,
nsnull,
NS_FIRST_FORMSUBMIT_CATEGORY);
}
// Notify observers that the form is being submitted.
nsresult rv = NS_OK;
nsCOMPtr<nsIObserverService> service =
do_GetService("@mozilla.org/observer-service;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISimpleEnumerator> theEnum;
rv = service->EnumerateObservers(NS_FORMSUBMIT_SUBJECT,
getter_AddRefs(theEnum));
NS_ENSURE_SUCCESS(rv, rv);
if (theEnum) {
nsCOMPtr<nsISupports> inst;
*aCancelSubmit = PR_FALSE;
nsCOMPtr<nsIScriptGlobalObject> globalObject;
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
nsCOMPtr<nsIDOMWindowInternal> window = do_QueryInterface(globalObject);
PRBool loop = PR_TRUE;
while (NS_SUCCEEDED(theEnum->HasMoreElements(&loop)) && loop) {
theEnum->GetNext(getter_AddRefs(inst));
nsCOMPtr<nsIFormSubmitObserver> formSubmitObserver(
do_QueryInterface(inst));
if (formSubmitObserver) {
rv = formSubmitObserver->Notify(this,
window,
aActionURL,
aCancelSubmit);
NS_ENSURE_SUCCESS(rv, rv);
}
if (*aCancelSubmit) {
return NS_OK;
}
}
}
return rv;
}
// static
nsresult
nsHTMLFormElement::CompareNodes(nsIDOMNode* a, nsIDOMNode* b, PRInt32* retval)
{
nsresult rv;
nsCOMPtr<nsIDOMNode> parentA;
PRInt32 indexA;
rv = a->GetParentNode(getter_AddRefs(parentA));
NS_ENSURE_SUCCESS(rv, rv);
if (!parentA) {
return NS_ERROR_UNEXPECTED;
}
{
// To get the index, we must turn them both into contents
// and do IndexOf(). Ick.
nsCOMPtr<nsIContent> parentA(do_QueryInterface(parentA));
nsCOMPtr<nsIContent> contentA(do_QueryInterface(a));
if (!parentA && !contentA) {
return NS_ERROR_UNEXPECTED;
}
rv = parentA->IndexOf(contentA, indexA);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMPtr<nsIDOMNode> parentB;
PRInt32 indexB;
rv = b->GetParentNode(getter_AddRefs(parentB));
NS_ENSURE_SUCCESS(rv, rv);
if (!parentB) {
return NS_ERROR_UNEXPECTED;
}
{
// To get the index, we must turn them both into contents
// and do IndexOf(). Ick.
nsCOMPtr<nsIContent> parentB(do_QueryInterface(parentB));
nsCOMPtr<nsIContent> bContent(do_QueryInterface(b));
if (!parentB && !bContent) {
return NS_ERROR_UNEXPECTED;
}
rv = parentB->IndexOf(bContent, indexB);
NS_ENSURE_SUCCESS(rv, rv);
}
*retval = ComparePoints(parentA, indexA, parentB, indexB);
return NS_OK;
}
nsresult
nsHTMLFormElement::WalkFormElements(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
//
// If the submitter is an input type=image element, it is not in the
// form.elements[] array. So we get the DOMNode pointer to it here so that
// later we can determine its proper position in the submit order.
//
nsCOMPtr<nsIDOMNode> imageElementNode;
{
nsCOMPtr<nsIFormControl> submitControl = do_QueryInterface(aSubmitElement);
if (submitControl) {
PRInt32 type;
submitControl->GetType(&type);
if (type == NS_FORM_INPUT_IMAGE) {
imageElementNode = do_QueryInterface(aSubmitElement);
}
}
}
//
// Walk the list of nodes and call SubmitNamesValues() on the controls
//
PRUint32 numElements;
GetElementCount(&numElements);
PRUint32 elementX;
for (elementX = 0; elementX < numElements; elementX++) {
nsCOMPtr<nsIFormControl> control;
GetElementAt(elementX, getter_AddRefs(control));
// Determine whether/when to submit the image element, which is not in
// the list of form.elements[]
if (imageElementNode) {
// If the input type=image element is before this element, submit it
// instead
nsCOMPtr<nsIDOMNode> controlNode(do_QueryInterface(control));
PRInt32 comparison;
CompareNodes(imageElementNode, controlNode, &comparison);
if (comparison < 0) {
nsCOMPtr<nsIFormControl> image = do_QueryInterface(imageElementNode);
image->SubmitNamesValues(aFormSubmission, aSubmitElement);
imageElementNode = nsnull;
}
}
// Tell the control to submit its name/value pairs to the submission
control->SubmitNamesValues(aFormSubmission, aSubmitElement);
}
// The image appeared after all other controls
if (imageElementNode) {
nsCOMPtr<nsIFormControl> image = do_QueryInterface(imageElementNode);
image->SubmitNamesValues(aFormSubmission, aSubmitElement);
}
return NS_OK;
}
nsresult
nsHTMLFormElement::GetActionURL(nsIURI** aActionURL)
{
nsresult rv = NS_OK;
*aActionURL = nsnull;
//
// Grab the URL string
//
nsAutoString action;
GetAction(action);
//
// Form the full action URL
//
// Get the document to form the URL.
// We'll also need it later to get the DOM window when notifying form submit
// observers (bug 33203)
if (!mDocument) {
return NS_OK; // No doc means don't submit, see Bug 28988
}
// Get base URL
nsCOMPtr<nsIURI> docURL;
mDocument->GetBaseURL(*getter_AddRefs(docURL));
NS_ASSERTION(docURL, "No Base URL found in Form Submit!\n");
if (!docURL) {
return NS_OK; // No base URL -> exit early, see Bug 30721
}
// If an action is not specified and we are inside
// a HTML document then reload the URL. This makes us
// compatible with 4.x browsers.
// If we are in some other type of document such as XML or
// XUL, do nothing. This prevents undesirable reloading of
// a document inside XUL.
nsCOMPtr<nsIURI> actionURL;
if (action.IsEmpty()) {
nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
if (!htmlDoc) {
// Must be a XML, XUL or other non-HTML document type
// so do nothing.
return NS_OK;
}
rv = docURL->Clone(getter_AddRefs(actionURL));
NS_ENSURE_SUCCESS(rv, rv);
} else {
rv = NS_NewURI(getter_AddRefs(actionURL), action, docURL);
NS_ENSURE_SUCCESS(rv, rv);
}
//
// Verify the URL should be reached
//
// Get security manager, check to see if access to action URI is allowed.
//
// XXX This code has not been tested. mailto: does not work in forms.
//
nsCOMPtr<nsIScriptSecurityManager> securityManager =
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = securityManager->CheckLoadURI(docURL, actionURL,
nsIScriptSecurityManager::STANDARD);
NS_ENSURE_SUCCESS(rv, rv);
nsXPIDLCString scheme;
PRBool isMailto = PR_FALSE;
if (actionURL && NS_FAILED(rv = actionURL->SchemeIs("mailto", &isMailto))) {
return rv;
}
if (isMailto) {
PRBool enabled;
rv = securityManager->IsCapabilityEnabled("UniversalSendMail", &enabled);
NS_ENSURE_SUCCESS(rv, rv);
if (!enabled) {
// Form submit to a mailto: URI requires UniversalSendMail privilege
return NS_ERROR_DOM_SECURITY_ERR;
}
}
//
// Assign to the output
//
*aActionURL = actionURL;
NS_ADDREF(*aActionURL);
return rv;
}
// nsIForm
NS_IMETHODIMP

Просмотреть файл

@ -59,6 +59,7 @@
#include "nsIHTMLAttributes.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIFormSubmission.h"
#include "nsIGfxTextControlFrame.h"
#include "nsIDocument.h"
#include "nsIPresShell.h"
@ -91,6 +92,14 @@
#include "nsRuleNode.h"
// input type=file
#include "nsIMIMEService.h"
#include "nsCExternalHandlerService.h"
#include "nsIFile.h"
#include "nsILocalFile.h"
#include "nsIFileStreams.h"
// XXX align=left, hspace, vspace, border? other nav4 attrs
static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
@ -142,12 +151,8 @@ public:
// Overriden nsIFormControl methods
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD Reset();
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval);
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval);
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames);
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
@ -218,8 +223,7 @@ public:
protected:
// Helper method
void SetPresStateChecked(nsIHTMLContent * aHTMLContent,
PRBool aValue);
void SetPresStateChecked(nsIHTMLContent * aHTMLContent, PRBool aValue);
NS_IMETHOD SetValueSecure(const nsAReadableString& aValue,
nsIGfxTextControlFrame2* aFrame,
PRBool aCheckSecurity);
@ -244,6 +248,8 @@ protected:
void FireOnChange();
static nsresult GetContentType(const char* aPathName, char** aContentType);
nsCOMPtr<nsIControllers> mControllers;
PRInt8 mType;
@ -1848,208 +1854,216 @@ nsHTMLInputElement::Reset()
return rv;
}
nsresult
nsHTMLInputElement::IsSuccessful(nsIContent* aSubmitElement,
PRBool *_retval)
NS_IMETHODIMP
nsHTMLInputElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
*_retval = PR_FALSE;
nsresult rv = NS_OK;
// if it's disabled, it won't submit
//
// Disabled elements don't submit
//
PRBool disabled;
nsresult rv = GetDisabled(&disabled);
if (disabled) {
return NS_OK;
rv = GetDisabled(&disabled);
if (NS_FAILED(rv) || disabled) {
return rv;
}
//
// Get the type (many ops depend on the type)
//
PRInt32 type;
GetType(&type);
rv = GetType(&type);
if (NS_FAILED(rv)) {
return rv;
}
// if it dosn't have a name it we don't submit
if (type != NS_FORM_INPUT_IMAGE) {
nsAutoString val;
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, val);
if (rv == NS_CONTENT_ATTR_NOT_THERE) {
return NS_OK;
//
// For type=reset, and type=button, we just never submit, period.
//
if (type == NS_FORM_INPUT_RESET || type == NS_FORM_INPUT_BUTTON) {
return rv;
}
//
// For type=image and type=button, we only submit if we were the button
// pressed
//
if ((type == NS_FORM_INPUT_SUBMIT || type == NS_FORM_INPUT_IMAGE)
&& aSubmitElement != this) {
return rv;
}
//
// For type=radio and type=checkbox, we only submit if checked=true
//
if (type == NS_FORM_INPUT_RADIO || type == NS_FORM_INPUT_CHECKBOX) {
PRBool checked;
rv = GetChecked(&checked);
if (NS_FAILED(rv) || !checked) {
return rv;
}
}
switch (type) {
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
{
GetChecked(_retval);
break;
}
case NS_FORM_INPUT_HIDDEN:
case NS_FORM_INPUT_PASSWORD:
case NS_FORM_INPUT_TEXT:
case NS_FORM_INPUT_FILE:
{
*_retval = PR_TRUE;
break;
}
case NS_FORM_INPUT_RESET:
case NS_FORM_INPUT_BUTTON:
{
*_retval = PR_FALSE;
break;
}
case NS_FORM_INPUT_SUBMIT:
case NS_FORM_INPUT_IMAGE:
{
*_retval = (this == aSubmitElement);
}
//
// Get the name
//
nsAutoString name;
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, name);
if (NS_FAILED(rv)) {
return rv;
}
PRBool nameThere = (rv != NS_CONTENT_ATTR_NOT_THERE);
return NS_OK;
}
nsresult
nsHTMLInputElement::GetMaxNumValues(PRInt32 *_retval)
{
PRInt32 type;
GetType(&type);
//
// Submit .x, .y for input type=image
//
if (type == NS_FORM_INPUT_IMAGE) {
nsAutoString name;
nsAutoString value;
GetName(name);
GetValue(value);
if (name.IsEmpty() || value.IsEmpty()) {
*_retval = 2;
} else {
*_retval = 3;
}
} else {
*_retval = 1;
}
return NS_OK;
}
// Go to the frame to find out where it was clicked. This is the only
// case where I can actually see using the frame, because you're talking
// about a value--mouse click--that is rightfully the domain of the frame.
//
// If the frame isn't there or isn't an ImageControlFrame, then we're not
// submitting these values no matter *how* nicely you ask.
PRInt32 clickedX;
PRInt32 clickedY;
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
nsresult
nsHTMLInputElement::GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames)
{
nsresult rv;
nsCOMPtr<nsIImageControlFrame> imageControlFrame(
do_QueryInterface(formControlFrame));
if (imageControlFrame) {
imageControlFrame->GetClickedX(&clickedX);
imageControlFrame->GetClickedY(&clickedY);
PRInt32 type;
GetType(&type);
switch (type) {
case NS_FORM_INPUT_CHECKBOX:
case NS_FORM_INPUT_RADIO:
{
NS_ENSURE_TRUE(aMaxNumValues >= 1, NS_ERROR_UNEXPECTED);
GetName(aNames[0]);
GetValue(aValues[0]);
aNumValues = 1;
break;
}
case NS_FORM_INPUT_HIDDEN:
case NS_FORM_INPUT_PASSWORD:
case NS_FORM_INPUT_TEXT:
{
NS_ENSURE_TRUE(aMaxNumValues >= 1, NS_ERROR_UNEXPECTED);
GetName(aNames[0]);
GetValue(aValues[0]);
aNumValues = 1;
break;
}
case NS_FORM_INPUT_FILE:
{
NS_ENSURE_TRUE(aMaxNumValues >= 1, NS_ERROR_UNEXPECTED);
GetName(aNames[0]);
GetValue(aValues[0]);
aNumValues = 1;
break;
}
case NS_FORM_INPUT_IMAGE:
{
NS_ENSURE_TRUE(aMaxNumValues >= 2, NS_ERROR_UNEXPECTED);
// Go to the frame to find out where it was clicked. This is the only
// case where I can actually see using the frame, because you're talking
// about a value--mouse click--that is rightfully the domain of the frame.
//
// If the frame isn't there or isn't an ImageControlFrame, then we're not
// submitting these values no matter *how* nicely you ask.
PRInt32 clickedX;
PRInt32 clickedY;
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_TRUE);
nsCOMPtr<nsIImageControlFrame> imageControlFrame(
do_QueryInterface(formControlFrame));
if (imageControlFrame) {
imageControlFrame->GetClickedX(&clickedX);
imageControlFrame->GetClickedY(&clickedY);
} else {
aNumValues = 0;
return NS_OK;
}
// Convert the values to strings for submission
char buf[20];
sprintf(&buf[0], "%d", clickedX);
aValues[0].AssignWithConversion(&buf[0]);
nsAutoString xVal = NS_ConvertASCIItoUCS2(buf);
sprintf(&buf[0], "%d", clickedY);
aValues[1].AssignWithConversion(&buf[0]);
// Figure out the proper name of the x and y values
nsAutoString name;
rv = GetName(name);
nsAutoString yVal = NS_ConvertASCIItoUCS2(buf);
if (!name.IsEmpty()) {
aNames[0] = name;
aNames[0].Append(NS_LITERAL_STRING(".x"));
aNames[1] = name;
aNames[1].Append(NS_LITERAL_STRING(".y"));
nsAutoString value;
rv = GetValue(value);
if (!value.IsEmpty()) {
aNames[2] = name;
aValues[2] = value;
aNumValues = 3;
} else {
aNumValues = 2;
}
aFormSubmission->AddNameValuePair(this,
name + NS_LITERAL_STRING(".x"), xVal);
aFormSubmission->AddNameValuePair(this,
name + NS_LITERAL_STRING(".y"), yVal);
} else {
// If the Image Element has no name, simply return x and y
// to Nav and IE compatability.
aNames[0] = NS_LITERAL_STRING("x");
aNames[1] = NS_LITERAL_STRING("y");
aNumValues = 2;
aFormSubmission->AddNameValuePair(this, NS_LITERAL_STRING("x"), xVal);
aFormSubmission->AddNameValuePair(this, NS_LITERAL_STRING("y"), yVal);
}
break;
}
case NS_FORM_INPUT_RESET:
case NS_FORM_INPUT_BUTTON:
{
aNumValues = 0;
break;
}
case NS_FORM_INPUT_SUBMIT:
{
NS_ENSURE_TRUE(aMaxNumValues >= 1, NS_ERROR_UNEXPECTED);
GetName(aNames[0]);
GetValue(aValues[0]);
aNumValues = 1;
break;
}
}
return NS_OK;
//
// Submit name=value
//
// If name not there, don't submit
if (!nameThere) {
return rv;
}
// Get the value
nsAutoString value;
rv = GetValue(value);
if (NS_FAILED(rv)) {
return rv;
}
//
// Submit file if it's input type=file and this encoding method accepts files
//
PRBool submittedValue = PR_FALSE;
if (type == NS_FORM_INPUT_FILE) {
//
// Open the file
//
nsCOMPtr<nsILocalFile> file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID,
&rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = file->InitWithUnicodePath(value.get());
if (NS_SUCCEEDED(rv)) {
//
// Get the leaf path name (to be submitted as the value)
//
PRUnichar* leafNameChars = nsnull;
rv = file->GetUnicodeLeafName(&leafNameChars);
NS_ENSURE_SUCCESS(rv, rv);
if (leafNameChars) {
nsAutoString filename;
filename.Adopt(leafNameChars);
PRBool acceptsFiles = PR_FALSE;
aFormSubmission->AcceptsFiles(&acceptsFiles);
if (acceptsFiles) {
//
// Get content type
//
nsCOMPtr<nsIMIMEService> MIMEService =
do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
char * contentTypeChars = nsnull;
rv = MIMEService->GetTypeFromFile(file, &contentTypeChars);
nsCAutoString contentType;
if (contentTypeChars) {
contentType.Adopt(contentTypeChars);
} else {
contentType = NS_LITERAL_CSTRING("application/octet-stream");
}
//
// Get input stream
//
nsCOMPtr<nsIInputStream> rawStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(rawStream), file);
if (rawStream) {
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
rawStream, 8192);
NS_ENSURE_SUCCESS(rv, rv);
//
// Submit
//
aFormSubmission->AddNameFilePair(this, name, filename,
bufferedStream, contentType,
PR_FALSE);
submittedValue = PR_TRUE;
}
}
//
// If we don't submit as a file, at least submit the truncated filename.
//
if (!submittedValue) {
aFormSubmission->AddNameValuePair(this, name, filename);
submittedValue = PR_TRUE;
}
}
}
}
if (!submittedValue) {
// Submit
// (for type=image, only submit if value is non-null)
if (type != NS_FORM_INPUT_IMAGE || !value.IsEmpty()) {
rv = aFormSubmission->AddNameValuePair(this, name, value);
}
}
return rv;
}
NS_IMETHODIMP
nsHTMLInputElement::SaveState(nsIPresContext* aPresContext,
nsIPresState** aState)
@ -2109,4 +2123,3 @@ nsHTMLInputElement::RestoreState(nsIPresContext* aPresContext,
return rv;
}

Просмотреть файл

@ -172,12 +172,8 @@ public:
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD Reset();
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval);
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval);
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames);
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
// nsIContent
NS_IMETHOD HandleDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent,
@ -420,27 +416,9 @@ nsHTMLLabelElement::Reset()
return NS_OK;
}
nsresult
nsHTMLLabelElement::IsSuccessful(nsIContent* aSubmitElement,
PRBool *_retval)
NS_IMETHODIMP
nsHTMLLabelElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
*_retval = PR_FALSE;
return NS_OK;
}
nsresult
nsHTMLLabelElement::GetMaxNumValues(PRInt32 *_retval)
{
*_retval = 0;
return NS_OK;
}
nsresult
nsHTMLLabelElement::GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames)
{
aNumValues = 0;
return NS_OK;
}

Просмотреть файл

@ -75,12 +75,8 @@ public:
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD Reset();
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval);
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval);
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames);
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
// nsIContent
NS_IMETHOD StringToAttribute(nsIAtom* aAttribute,
@ -253,27 +249,9 @@ nsHTMLLegendElement::Reset()
return NS_OK;
}
nsresult
nsHTMLLegendElement::IsSuccessful(nsIContent* aSubmitElement,
PRBool *_retval)
NS_IMETHODIMP
nsHTMLLegendElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
*_retval = PR_FALSE;
return NS_OK;
}
nsresult
nsHTMLLegendElement::GetMaxNumValues(PRInt32 *_retval)
{
*_retval = 0;
return NS_OK;
}
nsresult
nsHTMLLegendElement::GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames)
{
aNumValues = 0;
return NS_OK;
}

Просмотреть файл

@ -52,6 +52,7 @@
#include "nsIPresContext.h"
#include "nsIHTMLAttributes.h"
#include "nsIForm.h"
#include "nsIFormSubmission.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLOptGroupElement.h"
@ -175,12 +176,8 @@ public:
// Overriden nsIFormControl methods
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD Reset();
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval);
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval);
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames);
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
// nsISelectElement
NS_DECL_NSISELECTELEMENT
@ -1977,59 +1974,36 @@ nsHTMLSelectElement::InitializeOption(nsIDOMHTMLOptionElement * aOption,
return NS_OK;
}
// Since this is multivalued, IsSuccessful here only really says whether
// we're *allowed* to submit options here. There still may be no successful
// options and nothing will submit.
nsresult
nsHTMLSelectElement::IsSuccessful(nsIContent* aSubmitElement,
PRBool *_retval)
NS_IMETHODIMP
nsHTMLSelectElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
// if it's disabled, it won't submit
PRBool disabled;
nsresult rv = GetDisabled(&disabled);
NS_ENSURE_SUCCESS(rv, rv);
nsresult rv = NS_OK;
if (disabled) {
*_retval = PR_FALSE;
return NS_OK;
//
// Disabled elements don't submit
//
PRBool disabled;
rv = GetDisabled(&disabled);
if (NS_FAILED(rv) || disabled) {
return rv;
}
// If there is no name, it won't submit
nsAutoString val;
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, val);
*_retval = rv != NS_CONTENT_ATTR_NOT_THERE;
return NS_OK;
}
nsresult
nsHTMLSelectElement::GetMaxNumValues(PRInt32 *_retval)
{
PRUint32 length;
nsresult rv = GetLength(&length);
NS_ENSURE_SUCCESS(rv, rv);
*_retval = length;
return NS_OK;
}
nsresult
nsHTMLSelectElement::GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames)
{
//
// Get the name (if no name, no submit)
//
nsAutoString name;
nsresult rv = GetName(name);
PRInt32 sentOptions = 0;
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, name);
if (NS_FAILED(rv) || rv == NS_CONTENT_ATTR_NOT_THERE) {
return rv;
}
//
// Submit
//
PRUint32 len;
GetLength(&len);
// We loop through the cached list of selected items because it's
// hella faster than looping through all options
for (PRUint32 optIndex = 0; optIndex < len; optIndex++) {
// Don't send disabled options
PRBool disabled;
@ -2040,30 +2014,24 @@ nsHTMLSelectElement::GetNamesValues(PRInt32 aMaxNumValues,
nsCOMPtr<nsIDOMHTMLOptionElement> option;
mOptions->ItemAsOption(optIndex, getter_AddRefs(option));
if (option) {
PRBool isSelected;
rv = option->GetSelected(&isSelected);
if (NS_FAILED(rv) || !isSelected) {
continue;
}
NS_ENSURE_TRUE(option, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIOptionElement> optionElement = do_QueryInterface(option);
if (optionElement) {
nsAutoString value;
rv = optionElement->GetValueOrText(value);
NS_ENSURE_SUCCESS(rv, rv);
// If the value is not there
if (sentOptions < aMaxNumValues) {
aNames[sentOptions] = name;
aValues[sentOptions] = value;
sentOptions++;
}
}
PRBool isSelected;
rv = option->GetSelected(&isSelected);
NS_ENSURE_SUCCESS(rv, rv);
if (!isSelected) {
continue;
}
}
aNumValues = sentOptions;
nsCOMPtr<nsIOptionElement> optionElement = do_QueryInterface(option);
NS_ENSURE_TRUE(optionElement, NS_ERROR_UNEXPECTED);
nsAutoString value;
rv = optionElement->GetValueOrText(value);
NS_ENSURE_SUCCESS(rv, rv);
rv = aFormSubmission->AddNameValuePair(this, name, value);
}
return NS_OK;
}

Просмотреть файл

@ -47,6 +47,7 @@
#include "nsIDOMHTMLFormElement.h"
#include "nsIFormControl.h"
#include "nsIForm.h"
#include "nsIFormSubmission.h"
#include "nsIDOMEventReceiver.h"
#include "nsIHTMLContent.h"
#include "nsGenericHTMLElement.h"
@ -106,12 +107,8 @@ public:
// nsIFormControl
NS_IMETHOD GetType(PRInt32* aType);
NS_IMETHOD Reset();
NS_IMETHOD IsSuccessful(nsIContent* aSubmitElement, PRBool *_retval);
NS_IMETHOD GetMaxNumValues(PRInt32 *_retval);
NS_IMETHOD GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames);
NS_IMETHOD SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement);
NS_IMETHOD SaveState(nsIPresContext* aPresContext, nsIPresState** aState);
NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState);
@ -874,55 +871,48 @@ nsHTMLTextAreaElement::Reset()
return NS_OK;
}
nsresult
nsHTMLTextAreaElement::IsSuccessful(nsIContent* aSubmitElement,
PRBool *_retval)
NS_IMETHODIMP
nsHTMLTextAreaElement::SubmitNamesValues(nsIFormSubmission* aFormSubmission,
nsIContent* aSubmitElement)
{
// if it's disabled, it won't submit
nsresult rv = NS_OK;
//
// Disabled elements don't submit
//
PRBool disabled;
nsresult rv = GetDisabled(&disabled);
if (disabled) {
*_retval = PR_FALSE;
return NS_OK;
rv = GetDisabled(&disabled);
if (NS_FAILED(rv) || disabled) {
return rv;
}
// if it dosn't have a name it we don't submit
nsAutoString val;
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, val);
*_retval = rv != NS_CONTENT_ATTR_NOT_THERE;
return NS_OK;
}
nsresult
nsHTMLTextAreaElement::GetMaxNumValues(PRInt32 *_retval)
{
*_retval = 1;
return NS_OK;
}
nsresult
nsHTMLTextAreaElement::GetNamesValues(PRInt32 aMaxNumValues,
PRInt32& aNumValues,
nsString* aValues,
nsString* aNames)
{
NS_ENSURE_TRUE(aMaxNumValues >= 1, NS_ERROR_UNEXPECTED);
// We'll of course use the name of the control for the submit
//
// Get the name (if no name, no submit)
//
nsAutoString name;
nsresult rv = GetName(name);
NS_ENSURE_SUCCESS(rv, rv);
rv = GetAttr(kNameSpaceID_None, nsHTMLAtoms::name, name);
if (NS_FAILED(rv) || rv == NS_CONTENT_ATTR_NOT_THERE) {
return rv;
}
//
// Get the value
//
nsAutoString value;
rv = GetValue(value);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv)) {
return rv;
}
aNames[0] = name;
aValues[0] = value;
aNumValues = 1;
return NS_OK;
//
// Submit
//
rv = aFormSubmission->AddNameValuePair(this, name, value);
return rv;
}
NS_IMETHODIMP
nsHTMLTextAreaElement::SaveState(nsIPresContext* aPresContext,
nsIPresState** aState)

Просмотреть файл

@ -8,6 +8,7 @@ nsIChannel.idl
nsIFileChannel.idl
nsIDownloader.idl
nsIFileTransportService.idl
nsIMIMEInputStream.idl
nsIPasswordManager.idl
nsIPrompt.idl
nsIProtocolProxyService.idl

Просмотреть файл

@ -38,6 +38,7 @@ XPIDLSRCS = \
nsIFileTransportService.idl \
nsIIOService.idl \
nsILoadGroup.idl \
nsIMIMEInputStream.idl \
nsINetModRegEntry.idl \
nsINetModuleMgr.idl \
nsINetNotify.idl \

Просмотреть файл

@ -40,6 +40,7 @@ XPIDLSRCS = \
.\nsIFileTransportService.idl \
.\nsIIOService.idl \
.\nsILoadGroup.idl \
.\nsIMIMEInputStream.idl \
.\nsINetModRegEntry.idl \
.\nsINetModuleMgr.idl \
.\nsINetNotify.idl \

Просмотреть файл

@ -0,0 +1,75 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is frightening to behold.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIInputStream.idl"
/**
* The MIME stream separates headers and a datastream. It also allows
* automatic creation of the content-length header.
*/
[scriptable, uuid(dcbce63c-1dd1-11b2-b94d-91f6d49a3161)]
interface nsIMIMEInputStream : nsIInputStream
{
/**
* When true a "Content-Length" header is automatically added to the
* stream. The value of the content-length is automatically calculated
* using the available() method on the data stream. The value is
* recalculated every time the stream is rewinded to the start.
* Not allowed to be changed once the stream has been started to be read.
*/
attribute boolean addContentLength;
/**
* Adds an additional header to the stream on the form "name: value". May
* not be called once the stream has been started to be read.
* @param name name of the header
* @param value value of the header
*/
void addHeader([const] in string name, [const] in string value);
/**
* Sets data-stream. May not be called once the stream has been started
* to be read.
* The cursor of the new stream should be located at the beginning of the
* stream if the implementation of the nsIMIMEInputStream also is used as
* an nsISeekableStream.
* @param stream stream containing the data for the stream
*/
void setData(in nsIInputStream stream);
};

Просмотреть файл

@ -49,6 +49,7 @@ CPPSRCS = \
nsInputStreamChannel.cpp \
nsIOService.cpp \
nsLoadGroup.cpp \
nsMIMEInputStream.cpp \
nsNetModRegEntry.cpp \
nsNetModuleMgr.cpp \
nsProtocolProxyService.cpp \

Просмотреть файл

@ -54,6 +54,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsURLParsers.obj \
.\$(OBJDIR)\nsStandardURL.obj \
.\$(OBJDIR)\nsSimpleURI.obj \
.\$(OBJDIR)\nsMIMEInputStream.obj \
.\$(OBJDIR)\nsNetModuleMgr.obj \
.\$(OBJDIR)\nsNetModRegEntry.obj \
.\$(OBJDIR)\nsLoadGroup.obj \

Просмотреть файл

@ -251,8 +251,13 @@ nsBufferedInputStream::Close()
NS_IMETHODIMP
nsBufferedInputStream::Available(PRUint32 *result)
{
*result = mFillPoint - mCursor;
return NS_OK;
nsresult rv = NS_OK;
*result = 0;
if (mStream) {
rv = Source()->Available(result);
}
*result += (mFillPoint - mCursor);
return rv;
}
NS_IMETHODIMP

Просмотреть файл

@ -0,0 +1,314 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is frightening to behold.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* The MIME stream separates headers and a datastream. It also allows
* automatic creation of the content-length header.
*/
#include "nsCOMPtr.h"
#include "nsComponentManagerUtils.h"
#include "nsIMultiplexInputStream.h"
#include "nsIMIMEInputStream.h"
#include "nsISeekableStream.h"
#include "nsIStringStream.h"
class nsMIMEInputStream : public nsIMIMEInputStream,
public nsISeekableStream
{
public:
nsMIMEInputStream();
virtual ~nsMIMEInputStream();
NS_DECL_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIMIMEINPUTSTREAM
NS_DECL_NSISEEKABLESTREAM
NS_METHOD Init();
private:
void InitStreams();
struct ReadSegmentsState {
nsIInputStream* mThisStream;
nsWriteSegmentFun mWriter;
void* mClosure;
};
static NS_METHOD ReadSegCb(nsIInputStream* aIn, void* aClosure,
const char* aFromRawSegment, PRUint32 aToOffset,
PRUint32 aCount, PRUint32 *aWriteCount);
nsCString mHeaders;
nsCOMPtr<nsIStringInputStream> mHeaderStream;
nsCString mContentLength;
nsCOMPtr<nsIStringInputStream> mCLStream;
nsCOMPtr<nsIInputStream> mData;
nsCOMPtr<nsIMultiplexInputStream> mStream;
PRPackedBool mAddContentLength;
PRPackedBool mStartedReading;
};
NS_IMPL_THREADSAFE_ISUPPORTS3(nsMIMEInputStream,
nsIMIMEInputStream,
nsIInputStream,
nsISeekableStream);
nsMIMEInputStream::nsMIMEInputStream() : mAddContentLength(PR_FALSE),
mStartedReading(PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
nsMIMEInputStream::~nsMIMEInputStream()
{
}
NS_METHOD nsMIMEInputStream::Init()
{
nsresult rv = NS_OK;
mStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1",
&rv);
NS_ENSURE_SUCCESS(rv, rv);
mHeaderStream = do_CreateInstance("@mozilla.org/io/string-input-stream;1",
&rv);
NS_ENSURE_SUCCESS(rv, rv);
mCLStream = do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> headerStream = do_QueryInterface(mHeaderStream);
nsCOMPtr<nsIInputStream> clStream = do_QueryInterface(mCLStream);
rv = mStream->AppendStream(headerStream);
NS_ENSURE_SUCCESS(rv, rv);
rv = mStream->AppendStream(clStream);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
/* attribute boolean addContentLength; */
NS_IMETHODIMP
nsMIMEInputStream::GetAddContentLength(PRBool *aAddContentLength)
{
*aAddContentLength = mAddContentLength;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInputStream::SetAddContentLength(PRBool aAddContentLength)
{
NS_ENSURE_FALSE(mStartedReading, NS_ERROR_FAILURE);
mAddContentLength = aAddContentLength;
return NS_OK;
}
/* void addHeader ([const] in string name, [const] in string value); */
NS_IMETHODIMP
nsMIMEInputStream::AddHeader(const char *aName, const char *aValue)
{
NS_ENSURE_FALSE(mStartedReading, NS_ERROR_FAILURE);
mHeaders.Append(aName);
mHeaders.Append(": ");
mHeaders.Append(aValue);
mHeaders.Append("\r\n");
// Just in case someone somehow uses our stream, lets at least
// let the stream have a valid pointer. The stream will be properly
// initialized in nsMIMEInputStream::InitStreams
mHeaderStream->ShareData(mHeaders.get(), 0);
return NS_OK;
}
/* void setData (in nsIInputStream stream); */
NS_IMETHODIMP
nsMIMEInputStream::SetData(nsIInputStream *aStream)
{
NS_ENSURE_FALSE(mStartedReading, NS_ERROR_FAILURE);
// Remove the old stream if there is one
if (mData)
mStream->RemoveStream(2);
mData = aStream;
if (aStream)
mStream->AppendStream(mData);
return NS_OK;
}
// set up the internal streams
void nsMIMEInputStream::InitStreams()
{
NS_ASSERTION(!mStartedReading,
"Don't call initStreams twice without rewinding");
mStartedReading = PR_TRUE;
// We'll use the content-length stream to add the final \r\n
if (mAddContentLength && mData) {
PRUint32 cl;
mData->Available(&cl);
if (!cl) {
mContentLength = "\r\n";
}
else {
mContentLength = "Content-Length: ";
mContentLength.AppendInt((PRInt32)cl);
mContentLength.Append("\r\n\r\n");
}
}
else {
mContentLength = "\r\n";
}
mCLStream->ShareData(mContentLength.get(), -1);
mHeaderStream->ShareData(mHeaders.get(), -1);
}
#define INITSTREAMS \
if (!mStartedReading) { \
InitStreams(); \
}
// Reset mStartedReading when Seek-ing to start
NS_IMETHODIMP
nsMIMEInputStream::Seek(PRInt32 whence, PRInt32 offset)
{
nsresult rv;
nsCOMPtr<nsISeekableStream> stream = do_QueryInterface(mStream);
if (whence == NS_SEEK_SET && offset == 0) {
rv = stream->Seek(whence, offset);
if (NS_SUCCEEDED(rv))
mStartedReading = PR_FALSE;
}
else {
INITSTREAMS;
rv = stream->Seek(whence, offset);
}
return rv;
}
// Proxy ReadSegments since we need to be a good little nsIInputStream
NS_IMETHODIMP nsMIMEInputStream::ReadSegments(nsWriteSegmentFun aWriter,
void *aClosure, PRUint32 aCount,
PRUint32 *_retval)
{
INITSTREAMS;
ReadSegmentsState state;
state.mThisStream = this;
state.mWriter = aWriter;
state.mClosure = aClosure;
return mStream->ReadSegments(ReadSegCb, &state, aCount, _retval);
}
NS_METHOD
nsMIMEInputStream::ReadSegCb(nsIInputStream* aIn, void* aClosure,
const char* aFromRawSegment,
PRUint32 aToOffset, PRUint32 aCount,
PRUint32 *aWriteCount)
{
ReadSegmentsState* state = (ReadSegmentsState*)aClosure;
return (state->mWriter)(state->mThisStream,
state->mClosure,
aFromRawSegment,
aToOffset,
aCount,
aWriteCount);
}
/**
* Forward everything else to the mStream after calling InitStreams()
*/
// nsIInputStream
NS_IMETHODIMP nsMIMEInputStream::Close(void) { INITSTREAMS; return mStream->Close(); }
NS_IMETHODIMP nsMIMEInputStream::Available(PRUint32 *_retval) { INITSTREAMS; return mStream->Available(_retval); }
NS_IMETHODIMP nsMIMEInputStream::Read(char * buf, PRUint32 count, PRUint32 *_retval) { INITSTREAMS; return mStream->Read(buf, count, _retval); }
NS_IMETHODIMP nsMIMEInputStream::GetNonBlocking(PRBool *aNonBlocking) { INITSTREAMS; return mStream->GetNonBlocking(aNonBlocking); }
NS_IMETHODIMP nsMIMEInputStream::GetObserver(nsIInputStreamObserver * *aObserver) { INITSTREAMS; return mStream->GetObserver(aObserver); }
NS_IMETHODIMP nsMIMEInputStream::SetObserver(nsIInputStreamObserver * aObserver) { INITSTREAMS; return mStream->SetObserver(aObserver); }
// nsISeekableStream
NS_IMETHODIMP nsMIMEInputStream::Tell(PRUint32 *_retval)
{
INITSTREAMS;
nsCOMPtr<nsISeekableStream> stream = do_QueryInterface(mStream);
return stream->Tell(_retval);
}
NS_IMETHODIMP nsMIMEInputStream::SetEOF(void) {
INITSTREAMS;
nsCOMPtr<nsISeekableStream> stream = do_QueryInterface(mStream);
return stream->SetEOF();
}
/**
* Factory method used by do_CreateInstance
*/
NS_METHOD
nsMIMEInputStreamConstructor(nsISupports *outer, REFNSIID iid, void **result)
{
*result = nsnull;
if (outer)
return NS_ERROR_NO_AGGREGATION;
nsMIMEInputStream *inst;
NS_NEWXPCOM(inst, nsMIMEInputStream);
if (!inst)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(inst);
nsresult rv = inst->Init();
if (NS_FAILED(rv)) {
NS_RELEASE(inst);
return rv;
}
rv = inst->QueryInterface(iid, result);
NS_RELEASE(inst);
return rv;
}

Просмотреть файл

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is frightening to behold.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* The MIME stream separates headers and a datastream. It also allows
* automatic creation of the content-length header.
*/
#ifndef _nsMIMEInputStream_h_
#define _nsMIMEInputStream_h_
#include "nsIMIMEInputStream.h"
#define NS_MIMEINPUTSTREAM_CLASSNAME "nsMIMEInputStream"
#define NS_MIMEINPUTSTREAM_CONTRACTID "@mozilla.org/network/mime-input-stream;1"
#define NS_MIMEINPUTSTREAM_CID \
{ /* 58a1c31c-1dd2-11b2-a3f6-d36949d48268 */ \
0x58a1c31c, \
0x1dd2, \
0x11b2, \
{0xa3, 0xf6, 0xd3, 0x69, 0x49, 0xd4, 0x82, 0x68} \
}
extern NS_METHOD nsMIMEInputStreamConstructor(nsISupports *outer,
REFNSIID iid,
void **result);
#endif // _nsMIMEInputStream_h_

Просмотреть файл

@ -56,6 +56,7 @@
#include "nsAsyncStreamListener.h"
#include "nsFileStreams.h"
#include "nsBufferedStreams.h"
#include "nsMIMEInputStream.h"
#include "nsProtocolProxyService.h"
#include "nsSOCKSSocketProvider.h"
#include "nsSOCKS4SocketProvider.h"
@ -724,6 +725,10 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
NS_BUFFEREDOUTPUTSTREAM_CID,
NS_BUFFEREDOUTPUTSTREAM_CONTRACTID,
nsBufferedOutputStream::Create },
{ NS_MIMEINPUTSTREAM_CLASSNAME,
NS_MIMEINPUTSTREAM_CID,
NS_MIMEINPUTSTREAM_CONTRACTID,
nsMIMEInputStreamConstructor },
{ "Protocol Proxy Service",
NS_PROTOCOLPROXYSERVICE_CID,
"@mozilla.org/network/protocol-proxy-service;1",

Просмотреть файл

@ -1058,6 +1058,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -1664,6 +1671,11 @@
<PATH>nsLoadGroup.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -3056,6 +3068,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -3662,6 +3681,11 @@
<PATH>nsLoadGroup.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -5054,6 +5078,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -5646,6 +5677,11 @@
<PATH>nsLoadGroup.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -7028,6 +7064,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -7620,6 +7663,11 @@
<PATH>nsLoadGroup.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInputStreamChannel.cpp</PATH>
@ -8080,6 +8128,12 @@
<PATH>nsLoadGroup.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMIMEInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>Necko.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

Просмотреть файл

@ -1414,6 +1414,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMIMEInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIResumableChannel.idl</PATH>
@ -1840,6 +1847,11 @@
<PATH>nsIFileProtocolHandler.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMIMEInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIResumableChannel.idl</PATH>
@ -3206,6 +3218,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMIMEInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIResumableChannel.idl</PATH>
@ -3627,6 +3646,11 @@
<PATH>nsIFileProtocolHandler.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMIMEInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIResumableChannel.idl</PATH>
@ -4004,6 +4028,12 @@
<PATH>nsIUploadChannel.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMIMEInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</GROUP>
<GROUP><NAME>mimetype</NAME>
<FILEREF>

Просмотреть файл

@ -87,6 +87,7 @@
#include "nsDirectoryServiceDefs.h"
#include "nsICategoryManager.h"
#include "nsStringStream.h"
#include "nsMultiplexInputStream.h"
#include "nsFastLoadService.h"
@ -278,6 +279,7 @@ static const nsModuleComponentInfo components[] = {
COMPONENT(DIRECTORYITERATOR, nsDirectoryIteratorImpl::Create),
COMPONENT(STRINGINPUTSTREAM, nsStringInputStreamConstructor),
COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor),
COMPONENT(FASTLOADSERVICE, nsFastLoadService::Create),
COMPONENT(VARIANT, nsVariantConstructor),

Просмотреть файл

@ -10,6 +10,7 @@ nsIInputStream.idl
nsIInputStreamTee.idl
nsILineInputStream.idl
nsILocalFile.idl
nsIMultiplexInputStream.idl
nsIObjectInputStream.idl
nsIObjectOutputStream.idl
nsIOutputStream.idl

Просмотреть файл

@ -50,6 +50,7 @@ CPPSRCS = \
nsLinebreakConverter.cpp \
nsLocalFileCommon.cpp \
nsLocalFileUnicode.cpp \
nsMultiplexInputStream.cpp \
nsPipe2.cpp \
nsScriptableInputStream.cpp \
nsSegmentedBuffer.cpp \
@ -119,6 +120,7 @@ XPIDLSRCS = \
nsIInputStreamTee.idl \
nsILineInputStream.idl \
nsILocalFile.idl \
nsIMultiplexInputStream.idl \
nsIObjectInputStream.idl \
nsIObjectOutputStream.idl \
nsIOutputStream.idl \

Просмотреть файл

@ -62,6 +62,7 @@ XPIDLSRCS = \
.\nsIInputStreamTee.idl \
.\nsILineInputStream.idl \
.\nsILocalFile.idl \
.\nsIMultiplexInputStream.idl \
.\nsIObjectInputStream.idl \
.\nsIObjectOutputStream.idl \
.\nsIOutputStream.idl \
@ -97,6 +98,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsLinebreakConverter.obj \
.\$(OBJDIR)\nsLocalFileCommon.obj \
.\$(OBJDIR)\nsLocalFileWin.obj \
.\$(OBJDIR)\nsMultiplexInputStream.obj \
.\$(OBJDIR)\nsPipe2.obj \
.\$(OBJDIR)\nsScriptableInputStream.obj \
.\$(OBJDIR)\nsSegmentedBuffer.obj \

Просмотреть файл

@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is frightening to behold.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsIInputStream.idl"
/**
* The multiplex stream concatinates a list of input streams into a single
* stream.
*/
[scriptable, uuid(a076fd12-1dd1-11b2-b19a-d53b5dffaade)]
interface nsIMultiplexInputStream : nsIInputStream
{
/**
* Number of streams in this multiplex-stream
*/
readonly attribute unsigned long count;
/**
* Appends a stream to the end of the streams. The cursor of the stream
* should be located at the beginning of the stream if the implementation
* of this nsIMultiplexInputStream also is used as an nsISeekableStream.
* @param stream stream to append
*/
void appendStream(in nsIInputStream stream);
/**
* Insert a stream at specified index. If the cursor of this stream is at
* the beginning of the stream at index, the cursor will be placed at the
* beginning of the inserted stream instead.
* The cursor of the new stream should be located at the beginning of the
* stream if the implementation of this nsIMultiplexInputStream also is
* used as an nsISeekableStream.
* @param stream stream to insert
* @param index index to insert stream at, must be <= count
*/
void insertStream(in nsIInputStream stream, in unsigned long index);
/**
* Remove stream at specified index. If this stream is the one currently
* being read the readcursor is moved to the beginning of the next
* stream
* @param index remove stream at this index, must be < count
*/
void removeStream(in unsigned long index);
/**
* Get stream at specified index.
* @param index return stream at this index, must be < count
* @return stream at specified index
*/
nsIInputStream getStream(in unsigned long index);
};

Просмотреть файл

@ -0,0 +1,393 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is frightening to behold.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* The multiplex stream concatenates a list of input streams into a single
* stream.
*/
#include "nsMultiplexInputStream.h"
#include "nsIMultiplexInputStream.h"
#include "nsISeekableStream.h"
#include "nsSupportsArray.h"
class nsMultiplexInputStream : public nsIMultiplexInputStream,
public nsISeekableStream
{
public:
nsMultiplexInputStream();
virtual ~nsMultiplexInputStream();
NS_DECL_ISUPPORTS
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIMULTIPLEXINPUTSTREAM
NS_DECL_NSISEEKABLESTREAM
static NS_METHOD Create(nsISupports *outer, REFNSIID iid, void **result);
private:
struct ReadSegmentsState {
nsIInputStream* mThisStream;
PRUint32 mOffset;
nsWriteSegmentFun mWriter;
void* mClosure;
PRBool mDone;
};
static NS_METHOD ReadSegCb(nsIInputStream* aIn, void* aClosure,
const char* aFromRawSegment, PRUint32 aToOffset,
PRUint32 aCount, PRUint32 *aWriteCount);
nsSupportsArray mStreams;
PRUint32 mCurrentStream;
PRBool mStartedReadingCurrent;
};
NS_IMPL_THREADSAFE_ISUPPORTS3(nsMultiplexInputStream,
nsIMultiplexInputStream,
nsIInputStream,
nsISeekableStream);
nsMultiplexInputStream::nsMultiplexInputStream()
: mCurrentStream(0),
mStartedReadingCurrent(PR_FALSE)
{
NS_INIT_ISUPPORTS();
}
nsMultiplexInputStream::~nsMultiplexInputStream()
{
}
/* readonly attribute unsigned long count; */
NS_IMETHODIMP
nsMultiplexInputStream::GetCount(PRUint32 *aCount)
{
mStreams.Count(aCount);
return NS_OK;
}
/* void appendStream (in nsIInputStream stream); */
NS_IMETHODIMP
nsMultiplexInputStream::AppendStream(nsIInputStream *aStream)
{
return mStreams.AppendElement(aStream);
}
/* void insertStream (in nsIInputStream stream, in unsigned long index); */
NS_IMETHODIMP
nsMultiplexInputStream::InsertStream(nsIInputStream *aStream, PRUint32 aIndex)
{
nsresult rv = mStreams.InsertElementAt(aStream, aIndex);
NS_ENSURE_SUCCESS(rv, rv);
if (mCurrentStream > aIndex ||
(mCurrentStream == aIndex && mStartedReadingCurrent))
++mCurrentStream;
return rv;
}
/* void removeStream (in unsigned long index); */
NS_IMETHODIMP
nsMultiplexInputStream::RemoveStream(PRUint32 aIndex)
{
nsresult rv = mStreams.RemoveElementAt(aIndex);
NS_ENSURE_SUCCESS(rv, rv);
if (mCurrentStream > aIndex)
--mCurrentStream;
else if (mCurrentStream == aIndex)
mStartedReadingCurrent = PR_FALSE;
return rv;
}
/* nsIInputStream getStream (in unsigned long index); */
NS_IMETHODIMP
nsMultiplexInputStream::GetStream(PRUint32 aIndex, nsIInputStream **_retval)
{
return mStreams.QueryElementAt(aIndex,
NS_GET_IID(nsIInputStream),
(void**)_retval);
}
/* void close (); */
NS_IMETHODIMP
nsMultiplexInputStream::Close()
{
PRUint32 len, i;
nsresult rv = NS_OK;
mStreams.Count(&len);
for (i = 0; i < len; ++i) {
nsCOMPtr<nsIInputStream> stream(do_QueryElementAt(&mStreams, i));
nsresult rv2 = stream->Close();
// We still want to close all streams, but we should return an error
if (NS_FAILED(rv2))
rv = rv2;
}
return rv;
}
/* unsigned long available (); */
NS_IMETHODIMP
nsMultiplexInputStream::Available(PRUint32 *_retval)
{
nsresult rv;
PRUint32 i, len, avail = 0;
mStreams.Count(&len);
for (i = mCurrentStream; i < len; i++) {
nsCOMPtr<nsIInputStream> stream(do_QueryElementAt(&mStreams, i));
PRUint32 streamAvail;
rv = stream->Available(&streamAvail);
NS_ENSURE_SUCCESS(rv, rv);
avail += streamAvail;
}
*_retval = avail;
return NS_OK;
}
/* [noscript] unsigned long read (in charPtr buf, in unsigned long count); */
NS_IMETHODIMP
nsMultiplexInputStream::Read(char * aBuf, PRUint32 aCount, PRUint32 *_retval)
{
nsresult rv;
PRUint32 len;
mStreams.Count(&len);
PRUint32 read = 0;
while (mCurrentStream < len && aCount > 0) {
nsCOMPtr<nsIInputStream> stream(do_QueryElementAt(&mStreams,
mCurrentStream));
rv = stream->Read(aBuf, aCount, _retval);
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
*_retval = read;
return read == 0 ? NS_BASE_STREAM_WOULD_BLOCK : NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
if (!*_retval) {
// we're done with this stream, proceed to next
++mCurrentStream;
mStartedReadingCurrent = PR_FALSE;
}
else {
read += *_retval;
aBuf += *_retval;
aCount -= *_retval;
mStartedReadingCurrent = PR_TRUE;
}
}
*_retval = read;
return NS_OK;
}
/* [noscript] unsigned long readSegments (in nsWriteSegmentFun writer,
* in voidPtr closure,
* in unsigned long count); */
NS_IMETHODIMP
nsMultiplexInputStream::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
PRUint32 aCount, PRUint32 *_retval)
{
NS_ASSERTION(aWriter, "missing aWriter");
nsresult rv;
ReadSegmentsState state;
state.mThisStream = this;
state.mOffset = 0;
state.mWriter = aWriter;
state.mClosure = aClosure;
state.mDone = PR_FALSE;
PRUint32 len;
mStreams.Count(&len);
while (mCurrentStream < len) {
nsCOMPtr<nsIInputStream> stream(do_QueryElementAt(&mStreams,
mCurrentStream));
PRUint32 read;
rv = stream->ReadSegments(ReadSegCb, &state, aCount, &read);
// If we got an NS_BASE_STREAM_WOULD_BLOCK error since the reader
// didn't want any more data. This might not be an error for us if
// data was read from a previous stream in this run
if (state.mDone && rv == NS_BASE_STREAM_WOULD_BLOCK &&
!read && state.mOffset)
break;
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(aCount >= read, "Read more then requested");
mStartedReadingCurrent = PR_TRUE;
state.mOffset += read;
aCount -= read;
if (state.mDone || !aCount)
break;
++mCurrentStream;
mStartedReadingCurrent = PR_FALSE;
}
*_retval = state.mOffset;
return NS_OK;
}
NS_METHOD
nsMultiplexInputStream::ReadSegCb(nsIInputStream* aIn, void* aClosure,
const char* aFromRawSegment,
PRUint32 aToOffset, PRUint32 aCount,
PRUint32 *aWriteCount)
{
nsresult rv;
ReadSegmentsState* state = (ReadSegmentsState*)aClosure;
rv = (state->mWriter)(state->mThisStream,
state->mClosure,
aFromRawSegment,
aToOffset + state->mOffset,
aCount,
aWriteCount);
if (rv == NS_BASE_STREAM_WOULD_BLOCK ||
(NS_SUCCEEDED(rv) && *aWriteCount == 0 && aCount != 0))
state->mDone = PR_TRUE;
return rv;
}
/* readonly attribute boolean nonBlocking; */
NS_IMETHODIMP
nsMultiplexInputStream::GetNonBlocking(PRBool *aNonBlocking)
{
nsresult rv;
PRUint32 i, len;
mStreams.Count(&len);
for (i = 0; i < len; ++i) {
nsCOMPtr<nsIInputStream> stream(do_QueryElementAt(&mStreams, i));
rv = stream->GetNonBlocking(aNonBlocking);
NS_ENSURE_SUCCESS(rv, rv);
// If one is non-blocking the entire stream becomes non-blocking
if (*aNonBlocking)
return NS_OK;
}
return NS_OK;
}
/* attribute nsIInputStreamObserver observer; */
NS_IMETHODIMP
nsMultiplexInputStream::GetObserver(nsIInputStreamObserver * *aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMultiplexInputStream::SetObserver(nsIInputStreamObserver * aObserver)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void seek (in PRInt32 whence, in PRInt32 offset); */
NS_IMETHODIMP
nsMultiplexInputStream::Seek(PRInt32 aWhence, PRInt32 aOffset)
{
nsresult rv;
// rewinding to start is easy, and should be the most common case
if (aWhence == NS_SEEK_SET && aOffset == 0)
{
PRUint32 i, last;
last = mStartedReadingCurrent ? mCurrentStream+1 : mCurrentStream;
for (i = 0; i < last; ++i) {
nsCOMPtr<nsISeekableStream> stream(do_QueryElementAt(&mStreams, i));
NS_ENSURE_TRUE(stream, NS_ERROR_NO_INTERFACE);
rv = stream->Seek(NS_SEEK_SET, 0);
NS_ENSURE_SUCCESS(rv, rv);
}
mCurrentStream = 0;
mStartedReadingCurrent = PR_FALSE;
return NS_OK;
}
// other Seeks not implemented yet
return NS_ERROR_NOT_IMPLEMENTED;
}
/* PRUint32 tell (); */
NS_IMETHODIMP
nsMultiplexInputStream::Tell(PRUint32 *_retval)
{
nsresult rv;
*_retval = 0;
PRUint32 i, last;
last = mStartedReadingCurrent ? mCurrentStream+1 : mCurrentStream;
for (i = 0; i < last; ++i) {
nsCOMPtr<nsISeekableStream> stream(do_QueryElementAt(&mStreams, i));
NS_ENSURE_TRUE(stream, NS_ERROR_NO_INTERFACE);
PRUint32 pos;
rv = stream->Tell(&pos);
NS_ENSURE_SUCCESS(rv, rv);
*_retval += pos;
}
return NS_OK;
}
/* void setEOF (); */
NS_IMETHODIMP
nsMultiplexInputStream::SetEOF()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_METHOD
nsMultiplexInputStreamConstructor(nsISupports *outer,
REFNSIID iid,
void **result)
{
*result = nsnull;
if (outer)
return NS_ERROR_NO_AGGREGATION;
nsMultiplexInputStream *inst;
NS_NEWXPCOM(inst, nsMultiplexInputStream);
if (!inst)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(inst);
nsresult rv = inst->QueryInterface(iid, result);
NS_RELEASE(inst);
return rv;
}

Просмотреть файл

@ -0,0 +1,63 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is frightening to behold.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <sicking@bigfoot.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* The multiplex stream concatinates a list of input streams into a single
* stream.
*/
#ifndef _nsMultiplexInputStream_h_
#define _nsMultiplexInputStream_h_
#include "nsIMultiplexInputStream.h"
#define NS_MULTIPLEXINPUTSTREAM_CLASSNAME "nsMultiplexInputStream"
#define NS_MULTIPLEXINPUTSTREAM_CONTRACTID "@mozilla.org/io/multiplex-input-stream;1"
#define NS_MULTIPLEXINPUTSTREAM_CID \
{ /* 565e3a2c-1dd2-11b2-8da1-b4cef17e568d */ \
0x565e3a2c, \
0x1dd2, \
0x11b2, \
{0x8d, 0xa1, 0xb4, 0xce, 0xf1, 0x7e, 0x56, 0x8d} \
}
extern NS_METHOD nsMultiplexInputStreamConstructor(nsISupports *outer,
REFNSIID iid,
void **result);
#endif // _nsMultiplexInputStream_h_

Просмотреть файл

@ -1277,6 +1277,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMultiplexInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@ -1634,6 +1641,11 @@
<PATH>nsIStringStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMultiplexInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
<TARGET>
@ -2860,6 +2872,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMultiplexInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@ -3217,6 +3236,11 @@
<PATH>nsIStringStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMultiplexInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
</TARGETLIST>
@ -3653,6 +3677,12 @@
<PATH>nsIStringStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMultiplexInputStream.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</GROUPLIST>
</PROJECT>

Просмотреть файл

@ -1709,6 +1709,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMultiplexInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMemoryImpl.cpp</PATH>
@ -2371,6 +2378,11 @@
<PATH>nsLocalFileCommon.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMultiplexInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMemoryImpl.cpp</PATH>
@ -4161,6 +4173,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMultiplexInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMemoryImpl.cpp</PATH>
@ -4828,6 +4847,11 @@
<PATH>nsLocalFileCommon.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMultiplexInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMemoryImpl.cpp</PATH>
@ -5466,6 +5490,12 @@
<PATH>nsLocalFileCommon.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>xpcom.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsMultiplexInputStream.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>xpcom.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>