Bug 780048 - 'Some input stream types cannot be transferred via IPC'. r=khuey.

--HG--
extra : transplant_source : %C5m%04S%92%9F%E6%A7%02%0D%7E%CCz%8B%BBW%AA%C5%81%06
This commit is contained in:
Ben Turner 2012-08-03 13:37:58 -07:00
parent aacca1621e
commit 841001822a
4 changed files with 97 additions and 9 deletions

View File

@ -12,6 +12,7 @@
#include "nsDOMError.h"
#include "nsICharsetDetector.h"
#include "nsICharsetConverterManager.h"
#include "nsIClassInfo.h"
#include "nsIConverterInputStream.h"
#include "nsIDocument.h"
#include "nsIFileStreams.h"
@ -45,7 +46,9 @@ using namespace mozilla::dom;
// from NS_NewByteInputStream is held alive as long as the
// stream is. We do that by passing back this class instead.
class DataOwnerAdapter MOZ_FINAL : public nsIInputStream,
public nsISeekableStream
public nsISeekableStream,
public nsIIPCSerializable,
public nsIClassInfo
{
typedef nsDOMMemoryFile::DataOwner DataOwner;
public:
@ -56,15 +59,22 @@ public:
NS_DECL_ISUPPORTS
// These are mandatory.
NS_FORWARD_NSIINPUTSTREAM(mStream->)
NS_FORWARD_NSISEEKABLESTREAM(mSeekableStream->)
// These are optional. We use a conditional QI to keep them from being called
// if the underlying stream doesn't QI to either interface.
NS_FORWARD_NSIIPCSERIALIZABLE(mSerializable->)
NS_FORWARD_NSICLASSINFO(mClassInfo->)
private:
DataOwnerAdapter(DataOwner* aDataOwner,
nsIInputStream* aStream)
: mDataOwner(aDataOwner), mStream(aStream),
mSeekableStream(do_QueryInterface(aStream))
mSeekableStream(do_QueryInterface(aStream)),
mSerializable(do_QueryInterface(aStream)),
mClassInfo(do_QueryInterface(aStream))
{
NS_ASSERTION(mSeekableStream, "Somebody gave us the wrong stream!");
}
@ -72,11 +82,20 @@ private:
nsRefPtr<DataOwner> mDataOwner;
nsCOMPtr<nsIInputStream> mStream;
nsCOMPtr<nsISeekableStream> mSeekableStream;
nsCOMPtr<nsIIPCSerializable> mSerializable;
nsCOMPtr<nsIClassInfo> mClassInfo;
};
NS_IMPL_THREADSAFE_ISUPPORTS2(DataOwnerAdapter,
nsIInputStream,
nsISeekableStream)
NS_IMPL_THREADSAFE_ADDREF(DataOwnerAdapter)
NS_IMPL_THREADSAFE_RELEASE(DataOwnerAdapter)
NS_INTERFACE_MAP_BEGIN(DataOwnerAdapter)
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
NS_INTERFACE_MAP_ENTRY(nsISeekableStream)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializable, mSerializable)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIClassInfo, mClassInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
NS_INTERFACE_MAP_END
nsresult DataOwnerAdapter::Create(DataOwner* aDataOwner,
PRUint32 aStart,

View File

@ -508,13 +508,28 @@ nsFileInputStream::Write(IPC::Message *aMsg)
////////////////////////////////////////////////////////////////////////////////
// nsPartialFileInputStream
NS_IMPL_ADDREF_INHERITED(nsPartialFileInputStream, nsFileStreamBase)
NS_IMPL_RELEASE_INHERITED(nsPartialFileInputStream, nsFileStreamBase)
NS_IMPL_CLASSINFO(nsPartialFileInputStream, NULL, nsIClassInfo::THREADSAFE,
NS_PARTIALLOCALFILEINPUTSTREAM_CID)
// Don't forward to nsFileInputStream as we don't want to QI to
// nsIFileInputStream
NS_IMPL_ISUPPORTS_INHERITED3(nsPartialFileInputStream,
nsFileStreamBase,
NS_INTERFACE_MAP_BEGIN(nsPartialFileInputStream)
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
NS_INTERFACE_MAP_ENTRY(nsIPartialFileInputStream)
NS_INTERFACE_MAP_ENTRY(nsILineInputStream)
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializable)
NS_IMPL_QUERY_CLASSINFO(nsPartialFileInputStream)
NS_INTERFACE_MAP_END_INHERITING(nsFileStreamBase)
NS_IMPL_CI_INTERFACE_GETTER5(nsPartialFileInputStream,
nsIInputStream,
nsIPartialFileInputStream,
nsILineInputStream)
nsISeekableStream,
nsILineInputStream,
nsIIPCSerializable)
nsresult
nsPartialFileInputStream::Create(nsISupports *aOuter, REFNSIID aIID,
@ -614,6 +629,57 @@ nsPartialFileInputStream::Seek(PRInt32 aWhence, PRInt64 aOffset)
return rv;
}
bool
nsPartialFileInputStream::Read(const IPC::Message *aMsg, void **aIter)
{
using IPC::ReadParam;
// Grab our members first.
PRUint64 start;
PRUint64 length;
if (!ReadParam(aMsg, aIter, &start) ||
!ReadParam(aMsg, aIter, &length))
return false;
// Then run base class deserialization.
if (!nsFileInputStream::Read(aMsg, aIter))
return false;
// Set members.
mStart = start;
mLength = length;
// XXX This isn't really correct, we should probably set this to whatever
// the sender had. However, it doesn't look like nsFileInputStream deals
// with sending a partially-consumed stream either, so...
mPosition = 0;
// Mirror nsPartialFileInputStream::Init here. We can't call it directly
// because nsFileInputStream::Read() already calls the base class Init
// method.
return NS_SUCCEEDED(nsFileInputStream::Seek(NS_SEEK_SET, start));
}
void
nsPartialFileInputStream::Write(IPC::Message *aMsg)
{
using IPC::WriteParam;
// Write our members first.
WriteParam(aMsg, mStart);
WriteParam(aMsg, mLength);
// XXX This isn't really correct, we should probably send this too. However,
// it doesn't look like nsFileInputStream deals with sending a
// partially-consumed stream either, so...
if (mPosition) {
NS_WARNING("No support for sending a partially-consumed input stream!");
}
// Now run base class serialization.
nsFileInputStream::Write(aMsg);
}
////////////////////////////////////////////////////////////////////////////////
// nsFileOutputStream

View File

@ -178,6 +178,7 @@ class nsPartialFileInputStream : public nsFileInputStream,
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIPARTIALFILEINPUTSTREAM
NS_DECL_NSIIPCSERIALIZABLE
NS_IMETHOD Tell(PRInt64 *aResult);
NS_IMETHOD Available(PRUint32 *aResult);

View File

@ -191,6 +191,8 @@ struct ParamTraits<InputStream>
}
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(aParam.mStream);
NS_ASSERTION(classInfo, "Must QI to nsIClassInfo for this to work!");
char cidStr[NSID_LENGTH];
nsCID cid;
mozilla::DebugOnly<nsresult> rv = classInfo->GetClassIDNoAlloc(&cid);