.. _program_listing_file_src_message.cpp: Program Listing for File message.cpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/message.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "ndef-lite/message.hpp" #include "ndef-lite/record-header.hpp" #include "ndef-lite/record-type.hpp" using namespace std; NDEFMessage::NDEFMessage(const vector& data, const NDEFRecordType& type, uint offset) { this->message_records.push_back(NDEFRecord{ data, type, offset }); } NDEFMessage::NDEFMessage(const NDEFRecord& record) { this->message_records.push_back(record); } NDEFMessage::NDEFMessage(const NDEFRecordList& records) { this->message_records = records; } void NDEFMessage::append_record(const NDEFRecord& record) { this->message_records.push_back(record); } void NDEFMessage::insert_record(const NDEFRecord& record, uint index) { // Have to provide bounds checking if (index > this->message_records.size()) { throw std::out_of_range{ "Unable to insert record. Index " + to_string(index) + " outside of range of message" }; } this->message_records.emplace(this->message_records.begin() + index, record); } void NDEFMessage::remove_record(uint index) { // Have to provide bounds checking if (index >= this->message_records.size()) { throw std::out_of_range{ "Unable to remove record. Index " + to_string(index) + " outside of range of message" }; } this->message_records.erase(this->message_records.begin() + index); } void NDEFMessage::set_record(const NDEFRecord& record, uint index) { // Have to provide bounds checking if (index >= this->message_records.size()) { throw std::out_of_range{ "Unable to set record. Index " + to_string(index) + " outside of range of message" }; } this->message_records.at(index) = record; } bool NDEFMessage::is_valid() const { // Messages must have at least 1 record if (this->message_records.empty()) { return false; } // Validate all individual records for (auto&& record : this->message_records) { if (!record.is_valid()) { return false; } } return true; } std::vector NDEFMessage::as_bytes() const { vector byte_sequence; // Can only generate a byte sequence if the message is valid if (!this->is_valid()) { return byte_sequence; } // Generate header for each record uint8_t header = 0x00; size_t num_records = this->message_records.size(); for (size_t i = 0; i < num_records; i++) { // Immutable reference to current record to allow us to retrieve data without changing anything auto&& record = this->message_records.at(i); // Retrieve individual record's header, then set ME/MB bit flags appropriately header = record.header(); // First record, set Message Begin flag header |= (i == 0) ? static_cast(RecordFlag::MB) : 0; // Last record, set Message End flag header |= (i == (num_records - 1)) ? static_cast(RecordFlag::ME) : 0; // Create byte sequence, setting MB/ME header flags for record, then add the bytes to the ouput bytes auto record_bytes = record.as_bytes(header); byte_sequence.insert(byte_sequence.end(), record_bytes.begin(), record_bytes.end()); } return byte_sequence; } NDEFMessage NDEFMessage::from_bytes(const std::vector& data, uint offset) { NDEFMessage msg; // NOTE: Potentially should be using a deque due to removal from front of vector // Get all bytes after offset position from input auto buffer = vector{ data.begin() + offset, data.end() }; // Read in all bytes into records while (!buffer.empty()) { // Number of bytes used by record during creation size_t bytes_used = 0; // Create record from current byte array (offset already handled) auto record = NDEFRecord::from_bytes(buffer, 0, bytes_used); // If the record was invalid, then quit now, ignoring all current/remaining bytes if (record.type().id() == NDEFRecordType::TypeID::Invalid) { break; } // Record is valid, add it to the message msg.append_record(record); // Remove bytes read by record creation buffer.erase(buffer.begin(), buffer.begin() + bytes_used); } return msg; }