OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 * |
| 10 */ |
| 11 |
| 12 #ifndef WEBRTC_MODULES_RTP_RTCP_SOURCE_SAMPLE_RTCP_PARSER4_H_ |
| 13 #define WEBRTC_MODULES_RTP_RTCP_SOURCE_SAMPLE_RTCP_PARSER4_H_ |
| 14 |
| 15 #include <functional> |
| 16 #include <map> |
| 17 |
| 18 #include "webrtc/base/array_view.h" |
| 19 #include "webrtc/base/checks.h" |
| 20 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/common_header.h" |
| 21 |
| 22 namespace webrtc { |
| 23 namespace rtcp { |
| 24 // Parser that use functor as a callback. Has no knowledge about individual |
| 25 // packets, including how many are there. |
| 26 // std::function is not allowed though... too bad. |
| 27 |
| 28 class Parser4 { |
| 29 public: |
| 30 void Parse(rtc::ArrayView<const uint8_t> packet) { ParseInternal(packet); } |
| 31 |
| 32 template <typename Packet> |
| 33 Parser4& Handle(std::function<void(const Packet&)> handler) { |
| 34 RegisterHandler<Packet>(std::move(handler)); |
| 35 return *this; |
| 36 } |
| 37 |
| 38 private: |
| 39 using Handlers = std::map<uint8_t, std::function<void(const CommonHeader&)>>; |
| 40 template <typename Packet> |
| 41 struct IsFeedback { |
| 42 private: |
| 43 template <typename C> |
| 44 static std::true_type test(decltype(C::kFeedbackMessageType)); |
| 45 template <typename C> |
| 46 static std::false_type test(...); |
| 47 |
| 48 public: |
| 49 static constexpr bool value = decltype(test<Packet>(42))::value; |
| 50 }; |
| 51 |
| 52 template <typename Packet> |
| 53 static void AddHandler(Handlers* handlers, |
| 54 uint8_t key, |
| 55 std::function<void(const Packet&)> handler) { |
| 56 RTC_DCHECK(handlers->find(key) == handlers->end()) |
| 57 << "There is already " << static_cast<int>(key) << " in that map."; |
| 58 (*handlers)[key] = [handler](const CommonHeader& h) { |
| 59 Packet packet; |
| 60 if (packet.Parse(h)) |
| 61 handler(packet); |
| 62 }; |
| 63 } |
| 64 |
| 65 template < |
| 66 typename Packet, |
| 67 typename std::enable_if<!IsFeedback<Packet>::value>::type* = nullptr> |
| 68 void RegisterHandler(std::function<void(const Packet&)> handler) { |
| 69 AddHandler(&handlers_, Packet::kPacketType, std::move(handler)); |
| 70 } |
| 71 |
| 72 template <typename Packet, |
| 73 typename std::enable_if<IsFeedback<Packet>::value>::type* = nullptr> |
| 74 void RegisterHandler(std::function<void(const Packet&)> handler) { |
| 75 RTC_DCHECK_EQ(fb_handlers_.find(Packet::kPacketType) == fb_handlers_.end(), |
| 76 handlers_.find(Packet::kPacketType) == handlers_.end()); |
| 77 Handlers* fb_handlers = &fb_handlers_[Packet::kPacketType]; |
| 78 AddHandler(fb_handlers, Packet::kFeedbackMessageType, std::move(handler)); |
| 79 if (handlers_.find(Packet::kPacketType) == handlers_.end()) { |
| 80 handlers_[Packet::kPacketType] = |
| 81 [fb_handlers](const CommonHeader& header) { |
| 82 auto it = fb_handlers->find(header.fmt()); |
| 83 if (it != fb_handlers->end()) |
| 84 it->second(header); |
| 85 }; |
| 86 } |
| 87 } |
| 88 |
| 89 Handlers handlers_; |
| 90 std::map<uint8_t, Handlers> fb_handlers_; |
| 91 |
| 92 private: // Move to .cc |
| 93 void ParseInternal(rtc::ArrayView<const uint8_t> packet) { |
| 94 CommonHeader header; |
| 95 for (const uint8_t *next_packet = packet.begin(); |
| 96 RTC_DCHECK(next_packet <= packet.end()), next_packet != packet.end(); |
| 97 next_packet = header.NextPacket()) { |
| 98 if (!header.Parse(next_packet, packet.end() - next_packet)) |
| 99 break; |
| 100 auto it = handlers_.find(header.type()); |
| 101 if (it != handlers_.end()) |
| 102 it->second(header); |
| 103 } |
| 104 } |
| 105 }; |
| 106 } // namespace rtcp |
| 107 } // namespace webrtc |
| 108 #endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_SAMPLE_RTCP_PARSER4_H_ |
OLD | NEW |