Mozilla/mozilla/modules/plugin/src/nsPluginInputStream.cpp
dmose%mozilla.org 0efb7c174c updated xPL license boilerplate to v1.1, a=chofmann@netscape.com,r=endico@mozilla.org
git-svn-id: svn://10.0.0.236/trunk@52910 18797224-902f-48f8-a5cc-f745e15eee43
1999-11-06 03:43:54 +00:00

370 lines
9.4 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsPluginInputStream.h"
#include "plstr.h"
#include "npglue.h"
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
#ifdef NEW_PLUGIN_STREAM_API
static NS_DEFINE_IID(kIPluginInputStreamIID, NS_IPLUGININPUTSTREAM_IID);
static NS_DEFINE_IID(kIPluginInputStream2IID, NS_IPLUGININPUTSTREAM2_IID);
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
#else // !NEW_PLUGIN_STREAM_API
static NS_DEFINE_IID(kISeekablePluginStreamPeerIID, NS_ISEEKABLEPLUGINSTREAMPEER_IID);
static NS_DEFINE_IID(kIPluginStreamPeerIID, NS_IPLUGINSTREAMPEER_IID);
static NS_DEFINE_IID(kIPluginStreamPeer2IID, NS_IPLUGINSTREAMPEER2_IID);
#endif // !NEW_PLUGIN_STREAM_API
#ifdef NEW_PLUGIN_STREAM_API
////////////////////////////////////////////////////////////////////////////////
// Plugin Input Stream Interface
nsPluginInputStream::nsPluginInputStream(nsIPluginStreamListener* listener,
nsPluginStreamType streamType)
: mListener(listener), mStreamType(streamType),
mUrls(NULL), mStream(NULL),
mBuffer(NULL), mClosed(PR_FALSE)
// mBuffer(NULL), mBufferLength(0), mAmountRead(0)
{
NS_INIT_REFCNT();
listener->AddRef();
}
nsPluginInputStream::~nsPluginInputStream(void)
{
Cleanup();
mListener->Release();
}
NS_IMPL_ADDREF(nsPluginInputStream);
NS_IMPL_RELEASE(nsPluginInputStream);
NS_METHOD
nsPluginInputStream::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(kIPluginInputStream2IID) ||
aIID.Equals(kIPluginInputStreamIID) ||
aIID.Equals(kISupportsIID)) {
*aInstancePtr = (nsIPluginInputStream2*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
void
nsPluginInputStream::Cleanup(void)
{
if (mBuffer) {
// free the buffered data
BufferElement* element = mBuffer;
while (element != NULL) {
BufferElement* next = element->next;
PL_strfree(element->segment);
delete element;
element = next;
}
mBuffer = NULL;
}
mClosed = PR_TRUE;
}
NS_METHOD
nsPluginInputStream::Close(void)
{
NPError err = NPERR_NO_ERROR;
Cleanup();
#if 0 /* According to the plugin documentation, this would seem to be the
* right thing to do here, but it's not (and calling NPN_DestroyStream
* in the 4.0 browser during an NPP_Write call will crash the browser).
*/
err = npn_destroystream(mStream->instance->npp, mStream->pstream,
nsPluginReason_UserBreak);
#endif
return fromNPError[err];
}
NS_METHOD
nsPluginInputStream::GetLength(PRInt32 *aLength)
{
*aLength = mStream->pstream->end;
return NS_OK;
#if 0
*aLength = mBufferLength;
return NS_OK;
#endif
}
nsresult
nsPluginInputStream::ReceiveData(const char* buffer, PRUint32 offset, PRUint32 len)
{
BufferElement* element = new BufferElement;
if (element == NULL)
return NS_ERROR_OUT_OF_MEMORY;
element->segment = PL_strdup(buffer);
element->offset = offset;
element->length = len;
element->next = mBuffer;
mBuffer = element;
return NS_OK;
}
NS_METHOD
nsPluginInputStream::Read(char* aBuf, PRInt32 aOffset, PRInt32 aCount,
PRInt32 *aReadCount)
{
BufferElement* element;
for (element = mBuffer; element != NULL; element = element->next) {
if ((PRInt32)element->offset <= aOffset
&& aOffset < (PRInt32)(element->offset + element->length)) {
// found our segment
PRUint32 segmentIndex = aOffset - element->offset;
PRUint32 segmentAmount = element->length - segmentIndex;
if (aCount > (PRInt32)segmentAmount) {
return NS_ERROR_FAILURE;
}
memcpy(aBuf, &element->segment[segmentIndex], aCount);
// mReadCursor = segmentIndex + aCount;
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
NS_METHOD
nsPluginInputStream::GetLastModified(PRUint32 *result)
{
*result = mStream->pstream->lastmodified;
return NS_OK;
}
NS_METHOD
nsPluginInputStream::RequestRead(nsByteRange* rangeList)
{
NPError err = npn_requestread(mStream->pstream,
(NPByteRange*)rangeList);
return fromNPError[err];
}
NS_METHOD
nsPluginInputStream::GetContentLength(PRUint32 *result)
{
*result = mUrls->content_length;
return NS_OK;
}
NS_METHOD
nsPluginInputStream::GetHeaderFields(PRUint16& n, const char*const*& names,
const char*const*& values)
{
n = (PRUint16)mUrls->all_headers.empty_index;
names = (const char*const*)mUrls->all_headers.key;
values = (const char*const*)mUrls->all_headers.value;
return NS_OK;
}
NS_METHOD
nsPluginInputStream::GetHeaderField(const char* name, const char* *result)
{
PRUint16 i;
for (i = 0; i < mUrls->all_headers.empty_index; i++) {
if (PL_strcmp(mUrls->all_headers.key[i], name) == 0) {
*result = mUrls->all_headers.value[i];
return NS_OK;
}
}
return NS_ERROR_FAILURE;
}
#else // !NEW_PLUGIN_STREAM_API
////////////////////////////////////////////////////////////////////////////////
// Plugin Stream Peer Interface
nsPluginStreamPeer::nsPluginStreamPeer(URL_Struct *urls, np_stream *stream)
: userStream(NULL), urls(urls), stream(stream),
reason(nsPluginReason_NoReason)
{
NS_INIT_REFCNT();
}
nsPluginStreamPeer::~nsPluginStreamPeer(void)
{
#if 0
NPError err = npn_destroystream(stream->instance->npp, stream->pstream, reason);
PR_ASSERT(err == nsPluginError_NoError);
#endif
}
NS_METHOD
nsPluginStreamPeer::GetURL(const char* *result)
{
*result = stream->pstream->url;
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetEnd(PRUint32 *result)
{
*result = stream->pstream->end;
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetLastModified(PRUint32 *result)
{
*result = stream->pstream->lastmodified;
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetNotifyData(void* *result)
{
*result = stream->pstream->notifyData;
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetReason(nsPluginReason *result)
{
*result = reason;
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetMIMEType(nsMIMEType *result)
{
*result = (nsMIMEType)urls->content_type;
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetContentLength(PRUint32 *result)
{
*result = urls->content_length;
return NS_OK;
}
#if 0
NS_METHOD_(const char*)
nsPluginStreamPeer::GetContentEncoding(void)
{
return urls->content_encoding;
}
NS_METHOD_(const char*)
nsPluginStreamPeer::GetCharSet(void)
{
return urls->charset;
}
NS_METHOD_(const char*)
nsPluginStreamPeer::GetBoundary(void)
{
return urls->boundary;
}
NS_METHOD_(const char*)
nsPluginStreamPeer::GetContentName(void)
{
return urls->content_name;
}
NS_METHOD_(time_t)
nsPluginStreamPeer::GetExpires(void)
{
return urls->expires;
}
NS_METHOD_(time_t)
nsPluginStreamPeer::GetLastModified(void)
{
return urls->last_modified;
}
NS_METHOD_(time_t)
nsPluginStreamPeer::GetServerDate(void)
{
return urls->server_date;
}
NS_METHOD_(NPServerStatus)
nsPluginStreamPeer::GetServerStatus(void)
{
return urls->server_status;
}
#endif
NS_METHOD
nsPluginStreamPeer::GetHeaderFieldCount(PRUint32 *result)
{
*result = urls->all_headers.empty_index;
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetHeaderFieldKey(PRUint32 index, const char* *result)
{
*result = urls->all_headers.key[index];
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::GetHeaderField(PRUint32 index, const char* *result)
{
*result = urls->all_headers.value[index];
return NS_OK;
}
NS_METHOD
nsPluginStreamPeer::RequestRead(nsByteRange* rangeList)
{
NPError err = npn_requestread(stream->pstream,
(NPByteRange*)rangeList);
return fromNPError[err];
}
NS_IMPL_ADDREF(nsPluginStreamPeer);
NS_IMPL_RELEASE(nsPluginStreamPeer);
NS_METHOD
nsPluginStreamPeer::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if ((stream->seekable && aIID.Equals(kISeekablePluginStreamPeerIID)) ||
aIID.Equals(kIPluginStreamPeer2IID) ||
aIID.Equals(kIPluginStreamPeerIID) ||
aIID.Equals(kISupportsIID)) {
*aInstancePtr = (void*)(nsISupports*)(nsIPluginStreamPeer2*)this;
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
#endif // !NEW_PLUGIN_STREAM_API
////////////////////////////////////////////////////////////////////////////////