/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"

namespace webrtc {

StreamDataCounters::StreamDataCounters() : first_packet_time_ms(-1) {}

constexpr size_t StreamId::kMaxSize;

// Check if passed character is a "token-char" from RFC 4566.
static bool IsTokenChar(char ch) {
  return ch == 0x21 || (ch >= 0x23 && ch <= 0x27) || ch == 0x2a || ch == 0x2b ||
         ch == 0x2d || ch == 0x2e || (ch >= 0x30 && ch <= 0x39) ||
         (ch >= 0x41 && ch <= 0x5a) || (ch >= 0x5e && ch <= 0x7e);
}

bool StreamId::IsLegalMidName(rtc::ArrayView<const char> name) {
  return (name.size() <= kMaxSize && name.size() > 0 &&
          std::all_of(name.data(), name.data() + name.size(), IsTokenChar));
}

bool StreamId::IsLegalRsidName(rtc::ArrayView<const char> name) {
  return (name.size() <= kMaxSize && name.size() > 0 &&
          std::all_of(name.data(), name.data() + name.size(), isalnum));
}

void StreamId::Set(const char* data, size_t size) {
  // If |data| contains \0, the stream id size might become less than |size|.
  RTC_CHECK_LE(size, kMaxSize);
  memcpy(value_, data, size);
  if (size < kMaxSize)
    value_[size] = 0;
}

// StreamId is used as member of RTPHeader that is sometimes copied with memcpy
// and thus assume trivial destructibility.
static_assert(std::is_trivially_destructible<StreamId>::value, "");

PayloadUnion::PayloadUnion(const AudioPayload& payload) : payload_(payload) {}
PayloadUnion::PayloadUnion(const VideoPayload& payload) : payload_(payload) {}
PayloadUnion::PayloadUnion(const PayloadUnion&) = default;
PayloadUnion::PayloadUnion(PayloadUnion&&) = default;
PayloadUnion::~PayloadUnion() = default;

PayloadUnion& PayloadUnion::operator=(const PayloadUnion&) = default;
PayloadUnion& PayloadUnion::operator=(PayloadUnion&&) = default;

PacketFeedback::PacketFeedback(int64_t arrival_time_ms,
                               uint16_t sequence_number)
    : PacketFeedback(-1,
                     arrival_time_ms,
                     kNoSendTime,
                     sequence_number,
                     0,
                     0,
                     0,
                     PacedPacketInfo()) {}

PacketFeedback::PacketFeedback(int64_t arrival_time_ms,
                               int64_t send_time_ms,
                               uint16_t sequence_number,
                               size_t payload_size,
                               const PacedPacketInfo& pacing_info)
    : PacketFeedback(-1,
                     arrival_time_ms,
                     send_time_ms,
                     sequence_number,
                     payload_size,
                     0,
                     0,
                     pacing_info) {}

PacketFeedback::PacketFeedback(int64_t creation_time_ms,
                               uint16_t sequence_number,
                               size_t payload_size,
                               uint16_t local_net_id,
                               uint16_t remote_net_id,
                               const PacedPacketInfo& pacing_info)
    : PacketFeedback(creation_time_ms,
                     kNotReceived,
                     kNoSendTime,
                     sequence_number,
                     payload_size,
                     local_net_id,
                     remote_net_id,
                     pacing_info) {}

PacketFeedback::PacketFeedback(int64_t creation_time_ms,
                               int64_t arrival_time_ms,
                               int64_t send_time_ms,
                               uint16_t sequence_number,
                               size_t payload_size,
                               uint16_t local_net_id,
                               uint16_t remote_net_id,
                               const PacedPacketInfo& pacing_info)
    : creation_time_ms(creation_time_ms),
      arrival_time_ms(arrival_time_ms),
      send_time_ms(send_time_ms),
      sequence_number(sequence_number),
      payload_size(payload_size),
      unacknowledged_data(0),
      local_net_id(local_net_id),
      remote_net_id(remote_net_id),
      pacing_info(pacing_info) {}

PacketFeedback::PacketFeedback(const PacketFeedback&) = default;
PacketFeedback& PacketFeedback::operator=(const PacketFeedback&) = default;
PacketFeedback::~PacketFeedback() = default;

bool PacketFeedback::operator==(const PacketFeedback& rhs) const {
  return arrival_time_ms == rhs.arrival_time_ms &&
         send_time_ms == rhs.send_time_ms &&
         sequence_number == rhs.sequence_number &&
         payload_size == rhs.payload_size && pacing_info == rhs.pacing_info;
}

}  // namespace webrtc
