CapsuleParser.h (2878B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et tw=80 : */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_net_capsule_parser_h 8 #define mozilla_net_capsule_parser_h 9 10 #include "Capsule.h" 11 #include "mozilla/Maybe.h" 12 #include "mozilla/Result.h" 13 #include "mozilla/Span.h" 14 15 namespace mozilla::net { 16 17 class CapsuleDecoder; 18 19 class CapsuleParser final { 20 public: 21 class Listener { 22 public: 23 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING 24 25 virtual bool OnCapsule(Capsule&& aCapsule) = 0; 26 virtual void OnCapsuleParseFailure(nsresult aError) = 0; 27 28 protected: 29 virtual ~Listener() = default; 30 }; 31 32 explicit CapsuleParser(Listener* aListener); 33 ~CapsuleParser() = default; 34 // Processes incoming data and attempts to parse complete capsules. 35 // For each successfully parsed capsule, Listener::OnCapsule is invoked. 36 // If there is insufficient data to form a complete capsule, the remaining 37 // data is retained in mBuffer. In case a parsing error occurs, 38 // OnCapsuleParseFailure is called and any remaining data in mBuffer is 39 // discarded. 40 bool ProcessCapsuleData(const uint8_t* aData, uint32_t aCount); 41 42 bool IsBufferEmpty() const { return mBuffer.IsEmpty(); } 43 44 private: 45 // Indicates whether ProcessCapsuleData is already running. 46 bool mProcessing = false; 47 48 RefPtr<Listener> mListener; 49 // The buffer used to store data when we don't have enough to parse one 50 // capsule. 51 nsTArray<uint8_t> mBuffer; 52 // Parse one capsule from |aData|. 53 // Returns 0 if the complete capsule is not yet available, returns an error if 54 // parsing fails, or returns the number of bytes consumed for the successfully 55 // parsed capsule. 56 Result<size_t, nsresult> ParseCapsuleData(Span<const uint8_t> aData); 57 // Parse the payload part of the capsule. Returns the parsed capsule or an 58 // error. 59 Result<Capsule, nsresult> ParseCapsulePayload(CapsuleDecoder& aDecoder, 60 CapsuleType aType, 61 size_t aPayloadLength); 62 }; 63 64 // This is mainly used for testing. 65 class CapsuleParserListener : public CapsuleParser::Listener { 66 public: 67 NS_INLINE_DECL_REFCOUNTING(CapsuleParserListener, override) 68 69 CapsuleParserListener() = default; 70 bool OnCapsule(Capsule&& aCapsule) override; 71 void OnCapsuleParseFailure(nsresult aError) override; 72 73 nsTArray<Capsule> GetParsedCapsules() { return std::move(mParsedCapsules); } 74 75 Maybe<nsresult> GetErrorResult() { return mError; } 76 77 private: 78 virtual ~CapsuleParserListener() = default; 79 80 nsTArray<Capsule> mParsedCapsules; 81 Maybe<nsresult> mError = Nothing(); 82 }; 83 84 } // namespace mozilla::net 85 86 #endif