// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
#define QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_

#include <cstddef>
#include <cstdint>

#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h"

namespace quic {

class QuicRandom;

// Maximum value that can be properly encoded using VarInt62 coding.
const uint64_t kVarInt62MaxValue = UINT64_C(0x3fffffffffffffff);

// VarInt62 encoding masks
// If a uint64_t anded with a mask is not 0 then the value is encoded
// using that length (or is too big, in the case of kVarInt62ErrorMask).
// Values must be checked in order (error, 8-, 4-, and then 2- bytes)
// and if none are non-0, the value is encoded in 1 byte.
const uint64_t kVarInt62ErrorMask = UINT64_C(0xc000000000000000);
const uint64_t kVarInt62Mask8Bytes = UINT64_C(0x3fffffffc0000000);
const uint64_t kVarInt62Mask4Bytes = UINT64_C(0x000000003fffc000);
const uint64_t kVarInt62Mask2Bytes = UINT64_C(0x0000000000003fc0);

// This class provides facilities for packing QUIC data.
//
// The QuicDataWriter supports appending primitive values (int, string, etc)
// to a frame instance.  The internal memory buffer is exposed as the "data"
// of the QuicDataWriter.
class QUIC_EXPORT_PRIVATE QuicDataWriter {
 public:
  // Creates a QuicDataWriter where |buffer| is not owned
  // using NETWORK_BYTE_ORDER endianness.
  QuicDataWriter(size_t size, char* buffer);
  // Creates a QuicDataWriter where |buffer| is not owned
  // using the specified endianness.
  QuicDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
  QuicDataWriter(const QuicDataWriter&) = delete;
  QuicDataWriter& operator=(const QuicDataWriter&) = delete;

  ~QuicDataWriter();

  // Returns the size of the QuicDataWriter's data.
  size_t length() const { return length_; }

  // Retrieves the buffer from the QuicDataWriter without changing ownership.
  char* data();

  // Methods for adding to the payload.  These values are appended to the end
  // of the QuicDataWriter payload.

  // Writes 8/16/32/64-bit unsigned integers.
  bool WriteUInt8(uint8_t value);
  bool WriteUInt16(uint16_t value);
  bool WriteUInt32(uint32_t value);
  bool WriteUInt64(uint64_t value);

  // Write an unsigned-integer value per the IETF QUIC/Variable Length
  // Integer encoding rules (see draft-ietf-quic-transport-08.txt).
  // IETF Variable Length Integers have 62 significant bits, so the
  // value to write must be in the range of 0...(2^62)-1. Returns
  // false if the value is out of range or if there is no room in the
  // buffer.
  bool WriteVarInt62(uint64_t value);

  // Same as WriteVarInt62(uint64_t), but forces an encoding size to write to.
  // This is not as optimized as WriteVarInt62(uint64_t).
  // Returns false if the value does not fit in the specified write_length or if
  // there is no room in the buffer.
  bool WriteVarInt62(uint64_t value,
                     QuicVariableLengthIntegerLength write_length);

  // Writes a string piece as a consecutive length/content pair. The
  // length is VarInt62 encoded.
  bool WriteStringPieceVarInt62(const QuicStringPiece& string_piece);

  // Utility function to return the number of bytes needed to encode
  // the given value using IETF VarInt62 encoding. Returns the number
  // of bytes required to encode the given integer or 0 if the value
  // is too large to encode.
  static QuicVariableLengthIntegerLength GetVarInt62Len(uint64_t value);

  // Writes least significant |num_bytes| of a 64-bit unsigned integer in the
  // correct byte order.
  bool WriteBytesToUInt64(size_t num_bytes, uint64_t value);

  // Write unsigned floating point corresponding to the value. Large values are
  // clamped to the maximum representable (kUFloat16MaxValue). Values that can
  // not be represented directly are rounded down.
  bool WriteUFloat16(uint64_t value);
  bool WriteStringPiece(QuicStringPiece val);
  bool WriteStringPiece16(QuicStringPiece val);
  bool WriteBytes(const void* data, size_t data_len);
  bool WriteRepeatedByte(uint8_t byte, size_t count);
  // Fills the remaining buffer with null characters.
  void WritePadding();
  // Write padding of |count| bytes.
  bool WritePaddingBytes(size_t count);

  // Write connection ID to the payload.
  bool WriteConnectionId(QuicConnectionId connection_id);

  // Write 8-bit length followed by connection ID to the payload.
  bool WriteLengthPrefixedConnectionId(QuicConnectionId connection_id);

  // Write tag as a 32-bit unsigned integer to the payload. As tags are already
  // converted to big endian (e.g., CHLO is 'C','H','L','O') in memory by TAG or
  // MakeQuicTag and tags are written in byte order, so tags on the wire are
  // in big endian.
  bool WriteTag(uint32_t tag);

  // Write |length| random bytes generated by |random|.
  bool WriteRandomBytes(QuicRandom* random, size_t length);

  // Advance the writer's position for writing by |length| bytes without writing
  // anything. This method only makes sense to be used on a buffer that has
  // already been written to (and is having certain parts rewritten).
  bool Seek(size_t length);

  size_t capacity() const { return capacity_; }

  size_t remaining() const { return capacity_ - length_; }

  std::string DebugString() const;

 private:
  // Returns the location that the data should be written at, or nullptr if
  // there is not enough room. Call EndWrite with the returned offset and the
  // given length to pad out for the next write.
  char* BeginWrite(size_t length);

  // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not
  // char.
  char* buffer_;
  size_t capacity_;  // Allocation size of payload (or -1 if buffer is const).
  size_t length_;    // Current length of the buffer.

  // The endianness to write integers and floating numbers.
  quiche::Endianness endianness_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_DATA_WRITER_H_
