Program Listing for File record.hpp

Return to documentation for file (include/ndef-lite/record.hpp)

#ifndef NDEF_H
#define NDEF_H

#include <string>
#include <vector>

#include "ndef-lite/record-type.hpp"
#include "ndef-lite/util.hpp"

// Default value for number of bytes argument during record creation
// - required due to inability to use temporary values to be bound to non-const reference
static size_t default_bytes_used = 0;

// NDEF Text record is encoded with either UTF8 or UTF16, this is part of a byte set in the first bits of the
// payload
enum class RecordTextCodec { UTF8 = 0x00, UTF16 = 0x80 };

class NDEFRecord {
public:
  NDEFRecord();
  NDEFRecord(const std::vector<uint8_t>& payload, const NDEFRecordType& type, size_t offset = 0, bool chunked = false);
  NDEFRecord(const std::vector<uint8_t>& payload, const NDEFRecordType& type, const std::string& id, size_t offset = 0,
             bool chunked = false);
  ~NDEFRecord() = default;

  void validate();

  // Conversion helpers

  std::vector<uint8_t> as_bytes(uint8_t flags = 0x00) const;

  static NDEFRecord from_bytes(uint8_t bytes[], size_t len, size_t offset = 0);

  static NDEFRecord from_bytes(std::vector<uint8_t> bytes, size_t offset = 0, size_t& bytes_used = default_bytes_used);

  // Accessors/Mutators
  void set_id(const std::string& new_id) { this->id_field = new_id; }
  std::string id() const { return this->id_field; }

  void set_type(const NDEFRecordType& type) { this->record_type = type; }
  NDEFRecordType type() const { return this->record_type; }

  void set_chunked(bool flag) { this->chunked = flag; }
  bool constexpr is_chunked() const { return this->chunked; }

  void set_payload(const std::vector<uint8_t>& data);
  std::vector<uint8_t> payload() const { return this->payload_data; }

  size_t payload_length() const { return this->payload_data.size(); }

  // General information
  uint8_t header() const;

  bool is_short() const { return (this->payload_length() < 256); }
  bool constexpr is_empty() const { return (this->record_type.id() == NDEFRecordType::TypeID::Empty); }
  bool constexpr is_valid() const { return (this->record_type.id() != NDEFRecordType::TypeID::Invalid); }

  // Record creation helpers

  // Text records

  static NDEFRecord create_text_record(const std::u16string& text, const std::string& locale);

  static NDEFRecord create_text_record(const std::string& text, const std::string& locale,
                                       RecordTextCodec codec = RecordTextCodec::UTF8);

  static std::string get_text_locale(const std::vector<uint8_t>& payload);

  std::string get_text_locale() const;

  static std::string get_text(const std::vector<uint8_t>& payload);

  std::string get_text() const;

  // URI Records

  static NDEFRecord create_uri_record(const std::string& uri);

  static std::string get_uri_protocol(const std::vector<uint8_t>& payload);

  std::string get_uri_protocol() const;

  static std::string get_uri(const std::vector<uint8_t>& payload);

  std::string get_uri() const;

private:
  // NDEF Record Fields

  NDEFRecordType record_type;

  std::string id_field;

  std::vector<uint8_t> payload_data;

  bool chunked;

  // Helper functionality

  static std::vector<uint8_t> init_text_record_payload(const std::vector<uint8_t>& textBytes, const std::string& locale,
                                                       RecordTextCodec codec);

  static std::vector<uint8_t> init_text_record_payload(const std::string& text, const std::string& locale,
                                                       RecordTextCodec codec);

  // RELEASE: Below kept for reference. Will be removed for release
  // NDEFRecordHeader::RecordHeader header;

  //   uint8_t typeLength;

  //   uint32_t payloadLength;

  //   uint8_t idLength;
};

#endif // NDEF_H