1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is mozilla.org code.
16 * The Initial Developer of the Original Code is
17 * Christopher Blizzard.
18 * Portions created by the Initial Developer are Copyright (C) 2001
19 * the Initial Developer. All Rights Reserved.
22 * Christopher Blizzard <blizzard@mozilla.org>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
39 #include <nsIInputStream.h>
40 #include <nsIOutputStream.h>
41 #include <nsIContentViewerContainer.h>
42 #include <nsIDocumentLoaderFactory.h>
43 #include <nsNetUtil.h>
46 #include "nsXPCOMCID.h"
47 #include "nsICategoryManager.h"
49 #include "nsIContentViewer.h"
51 #include "nsEmbedStream.h"
52 #include "nsReadableUtils.h"
54 // nsIInputStream interface
56 NS_IMPL_ISUPPORTS1(nsEmbedStream
, nsIInputStream
)
58 nsEmbedStream::nsEmbedStream()
62 mDoingStream
= PR_FALSE
;
65 nsEmbedStream::~nsEmbedStream()
70 nsEmbedStream::InitOwner(nsIWebBrowser
*aOwner
)
76 nsEmbedStream::Init(void)
80 nsCOMPtr
<nsIInputStream
> bufInStream
;
81 nsCOMPtr
<nsIOutputStream
> bufOutStream
;
83 rv
= NS_NewPipe(getter_AddRefs(bufInStream
),
84 getter_AddRefs(bufOutStream
));
86 if (NS_FAILED(rv
)) return rv
;
88 mInputStream
= bufInStream
;
89 mOutputStream
= bufOutStream
;
95 nsEmbedStream::OpenStream(nsIURI
*aBaseURI
, const nsACString
& aContentType
)
97 NS_ENSURE_ARG_POINTER(aBaseURI
);
98 NS_ENSURE_TRUE(IsASCII(aContentType
), NS_ERROR_INVALID_ARG
);
100 // if we're already doing a stream, return an error
102 return NS_ERROR_IN_PROGRESS
;
105 mDoingStream
= PR_TRUE
;
107 // initialize our streams
108 nsresult rv
= Init();
112 // get the viewer container
113 nsCOMPtr
<nsIContentViewerContainer
> viewerContainer
;
114 viewerContainer
= do_GetInterface(mOwner
);
116 // create a new load group
117 rv
= NS_NewLoadGroup(getter_AddRefs(mLoadGroup
), nsnull
);
121 // create a new input stream channel
122 rv
= NS_NewInputStreamChannel(getter_AddRefs(mChannel
), aBaseURI
,
123 static_cast<nsIInputStream
*>(this),
128 // set the channel's load group
129 rv
= mChannel
->SetLoadGroup(mLoadGroup
);
133 // find a document loader for this content type
135 const nsCString
& flatContentType
= PromiseFlatCString(aContentType
);
137 nsXPIDLCString docLoaderContractID
;
138 nsCOMPtr
<nsICategoryManager
> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID
, &rv
));
141 rv
= catMan
->GetCategoryEntry("Gecko-Content-Viewers",
142 flatContentType
.get(),
143 getter_Copies(docLoaderContractID
));
144 // Note: When the category manager does not find an entry for the requested
145 // contract ID, it will return NS_ERROR_NOT_AVAILABLE. This conveniently
146 // matches what this method wants to return in that case.
150 nsCOMPtr
<nsIDocumentLoaderFactory
> docLoaderFactory
;
151 docLoaderFactory
= do_GetService(docLoaderContractID
.get(), &rv
);
155 // ok, create an instance of the content viewer for that command and
157 nsCOMPtr
<nsIContentViewer
> contentViewer
;
158 rv
= docLoaderFactory
->CreateInstance("view", mChannel
, mLoadGroup
,
159 flatContentType
.get(), viewerContainer
,
161 getter_AddRefs(mStreamListener
),
162 getter_AddRefs(contentViewer
));
166 // set the container viewer container for this content view
167 rv
= contentViewer
->SetContainer(viewerContainer
);
172 rv
= viewerContainer
->Embed(contentViewer
, "view", nsnull
);
177 rv
= mStreamListener
->OnStartRequest(mChannel
, NULL
);
185 nsEmbedStream::AppendToStream(const PRUint8
*aData
, PRUint32 aLen
)
190 rv
= Append(aData
, aLen
);
194 // notify our listeners
195 rv
= mStreamListener
->OnDataAvailable(mChannel
,
197 static_cast<nsIInputStream
*>(this),
198 mOffset
, /* offset */
209 nsEmbedStream::CloseStream(void)
213 // NS_ENSURE_STATE returns NS_ERROR_UNEXPECTED if the condition isn't
214 // satisfied; this is exactly what we want to return.
215 NS_ENSURE_STATE(mDoingStream
);
216 mDoingStream
= PR_FALSE
;
218 rv
= mStreamListener
->OnStopRequest(mChannel
, NULL
, NS_OK
);
224 mStreamListener
= nsnull
;
231 nsEmbedStream::Append(const PRUint8
*aData
, PRUint32 aLen
)
233 PRUint32 bytesWritten
= 0;
234 nsresult rv
= mOutputStream
->Write(reinterpret_cast<const char*>(aData
),
235 aLen
, &bytesWritten
);
239 NS_ASSERTION(bytesWritten
== aLen
,
240 "underlying byffer couldn't handle the write");
245 nsEmbedStream::Available(PRUint32
*_retval
)
247 return mInputStream
->Available(_retval
);
251 nsEmbedStream::Read(char * aBuf
, PRUint32 aCount
, PRUint32
*_retval
)
253 return mInputStream
->Read(aBuf
, aCount
, _retval
);
256 NS_IMETHODIMP
nsEmbedStream::Close(void)
258 return mInputStream
->Close();
262 nsEmbedStream::ReadSegments(nsWriteSegmentFun aWriter
, void * aClosure
,
263 PRUint32 aCount
, PRUint32
*_retval
)
265 return mInputStream
->ReadSegments(aWriter
, aClosure
, aCount
, _retval
);
269 nsEmbedStream::IsNonBlocking(PRBool
*aNonBlocking
)
271 return mInputStream
->IsNonBlocking(aNonBlocking
);