Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / netwerk / streamconv / converters / nsUnknownDecoder.h
blob3aed80639de36ef5f4661ecae26c52829c470110
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsUnknownDecoder_h__
7 #define nsUnknownDecoder_h__
9 #include "nsIStreamConverter.h"
10 #include "nsIThreadRetargetableStreamListener.h"
11 #include "nsIContentSniffer.h"
12 #include "mozilla/Mutex.h"
13 #include "mozilla/Atomics.h"
15 #include "nsCOMPtr.h"
16 #include "nsString.h"
18 #define NS_UNKNOWNDECODER_CID \
19 { /* 7d7008a0-c49a-11d3-9b22-0080c7cb1080 */ \
20 0x7d7008a0, 0xc49a, 0x11d3, { \
21 0x9b, 0x22, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x80 \
22 } \
25 class nsUnknownDecoder : public nsIStreamConverter, public nsIContentSniffer {
26 public:
27 // nsISupports methods
28 NS_DECL_ISUPPORTS
30 // nsIStreamConverter methods
31 NS_DECL_NSISTREAMCONVERTER
33 // nsIStreamListener methods
34 NS_DECL_NSISTREAMLISTENER
36 // nsIRequestObserver methods
37 NS_DECL_NSIREQUESTOBSERVER
39 // nsIContentSniffer methods
40 NS_DECL_NSICONTENTSNIFFER
42 // nsIThreadRetargetableStreamListener methods
43 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
45 explicit nsUnknownDecoder(nsIStreamListener* aListener = nullptr);
47 protected:
48 virtual ~nsUnknownDecoder();
50 virtual void DetermineContentType(nsIRequest* aRequest);
51 nsresult FireListenerNotifications(nsIRequest* request, nsISupports* aCtxt);
53 class ConvertedStreamListener : public nsIStreamListener {
54 public:
55 explicit ConvertedStreamListener(nsUnknownDecoder* aDecoder);
57 NS_DECL_ISUPPORTS
58 NS_DECL_NSIREQUESTOBSERVER
59 NS_DECL_NSISTREAMLISTENER
61 private:
62 virtual ~ConvertedStreamListener() = default;
63 static nsresult AppendDataToString(nsIInputStream* inputStream,
64 void* closure, const char* rawSegment,
65 uint32_t toOffset, uint32_t count,
66 uint32_t* writeCount);
67 nsUnknownDecoder* mDecoder;
70 protected:
71 nsCOMPtr<nsIStreamListener> mNextListener;
73 // Various sniffer functions. Returning true means that a type
74 // was determined; false means no luck.
75 bool SniffForHTML(nsIRequest* aRequest);
76 bool SniffForXML(nsIRequest* aRequest);
78 // SniffURI guesses at the content type based on the URI (typically
79 // using the extentsion)
80 bool SniffURI(nsIRequest* aRequest);
82 // LastDitchSniff guesses at text/plain vs. application/octet-stream
83 // by just looking at whether the data contains null bytes, and
84 // maybe at the fraction of chars with high bit set. Use this only
85 // as a last-ditch attempt to decide a content type!
86 bool LastDitchSniff(nsIRequest* aRequest);
88 /**
89 * An entry struct for our array of sniffers. Each entry has either
90 * a type associated with it (set these with the SNIFFER_ENTRY macro)
91 * or a function to be executed (set these with the
92 * SNIFFER_ENTRY_WITH_FUNC macro). The function should take a single
93 * nsIRequest* and returns bool -- true if it sets mContentType,
94 * false otherwise
96 struct nsSnifferEntry {
97 using TypeSniffFunc = bool (nsUnknownDecoder::*)(nsIRequest*);
99 const char* mBytes;
100 uint32_t mByteLen;
102 // Exactly one of mMimeType and mContentTypeSniffer should be set non-null
103 const char* mMimeType;
104 TypeSniffFunc mContentTypeSniffer;
107 #define SNIFFER_ENTRY(_bytes, _type) \
108 { _bytes, sizeof(_bytes) - 1, _type, nullptr }
110 #define SNIFFER_ENTRY_WITH_FUNC(_bytes, _func) \
111 { _bytes, sizeof(_bytes) - 1, nullptr, _func }
113 static nsSnifferEntry sSnifferEntries[];
114 static uint32_t sSnifferEntryNum;
116 // We guarantee in order delivery of OnStart, OnStop and OnData, therefore
117 // we do not need proper locking for mBuffer.
118 mozilla::Atomic<char*> mBuffer;
119 mozilla::Atomic<uint32_t> mBufferLen;
121 nsCString mContentType;
123 // This mutex syncs: mContentType, mDecodedData and mNextListener.
124 mutable mozilla::Mutex mMutex MOZ_UNANNOTATED;
126 protected:
127 nsresult ConvertEncodedData(nsIRequest* request, const char* data,
128 uint32_t length);
129 nsCString mDecodedData; // If data are encoded this will be uncompress data.
132 #define NS_BINARYDETECTOR_CID \
133 { /* a2027ec6-ba0d-4c72-805d-148233f5f33c */ \
134 0xa2027ec6, 0xba0d, 0x4c72, { \
135 0x80, 0x5d, 0x14, 0x82, 0x33, 0xf5, 0xf3, 0x3c \
140 * Class that detects whether a data stream is text or binary. This reuses
141 * most of nsUnknownDecoder except the actual content-type determination logic
142 * -- our overridden DetermineContentType simply calls LastDitchSniff and sets
143 * the type to APPLICATION_GUESS_FROM_EXT if the data is detected as binary.
145 class nsBinaryDetector : public nsUnknownDecoder {
146 protected:
147 virtual void DetermineContentType(nsIRequest* aRequest) override;
150 #endif /* nsUnknownDecoder_h__ */