Kenji Arai / TYBLE16_mbedlized_os5_several_examples_1st

Dependencies:   nRF51_Vdd TextLCD BME280

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Text.cpp Source File

Text.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2018 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include <string.h>
00018 
00019 #include "nfc/ndef/common/Text.h"
00020 
00021 namespace {
00022 static const uint8_t utf16_encoding_bit = (1 << 7);
00023 static const uint8_t language_code_size_mask = 0x3F;
00024 static const uint8_t header_index = 0;
00025 static const uint8_t language_code_index = 1;
00026 static const uint8_t header_size = 1;
00027 static const uint8_t text_record_type_value[] = { 'T' };
00028 }
00029 
00030 namespace mbed {
00031 namespace nfc {
00032 namespace ndef {
00033 namespace common {
00034 
00035 Text::Text() :
00036     _text_record(NULL),
00037     _text_record_size(0)
00038 { }
00039 
00040 Text::Text(const Text &other) :
00041     _text_record(other._text_record ? new uint8_t[other._text_record_size] : NULL),
00042     _text_record_size(other._text_record_size)
00043 {
00044     memcpy(_text_record, other._text_record, _text_record_size);
00045 }
00046 
00047 Text::Text(
00048     encoding_t text_encoding,
00049     const Span<const uint8_t>  &language_code,
00050     const Span<const uint8_t>  &text
00051 ) : _text_record(NULL),
00052     _text_record_size(0)
00053 {
00054     set_text(text_encoding, language_code, text);
00055 }
00056 
00057 Text::~Text()
00058 {
00059     delete[] _text_record;
00060 }
00061 
00062 Text &Text::operator=(const Text &other)
00063 {
00064     if (this == &other) {
00065         return *this;
00066     }
00067 
00068     _text_record_size = other._text_record_size;
00069 
00070     delete[] _text_record;
00071     if (!other._text_record) {
00072         _text_record = NULL;
00073     } else {
00074         _text_record = new uint8_t[_text_record_size];
00075         memcpy(_text_record, other._text_record, _text_record_size);
00076     }
00077 
00078     return *this;
00079 }
00080 
00081 void Text::set_text(
00082     encoding_t text_encoding,
00083     const Span<const uint8_t>  &language_code,
00084     const Span<const uint8_t>  &text
00085 )
00086 {
00087     delete[] _text_record;
00088 
00089     _text_record_size = header_size + language_code.size() + text.size();
00090     _text_record = new uint8_t[_text_record_size];
00091 
00092     // build the header
00093     _text_record[header_index] = 0;
00094     if (text_encoding == UTF16) {
00095         _text_record[header_index] |= utf16_encoding_bit;
00096     }
00097     _text_record[header_index] |= language_code.size();
00098 
00099     // language code
00100     memcpy(_text_record + language_code_index, language_code.data(), language_code.size());
00101 
00102     // actual text
00103     memcpy(_text_record + language_code_index + language_code.size(), text.data(), text.size());
00104 }
00105 
00106 Text::encoding_t Text::get_encoding() const
00107 {
00108     return (_text_record[header_index] & utf16_encoding_bit) ? UTF16 : UTF8;
00109 }
00110 
00111 Span<const uint8_t>  Text::get_language_code() const
00112 {
00113     return make_const_Span(
00114                _text_record + language_code_index,
00115                _text_record[header_index] & language_code_size_mask
00116            );
00117 }
00118 
00119 Span<const uint8_t>  Text::get_text() const
00120 {
00121     if (!_text_record) {
00122         return Span<const uint8_t> ();
00123     }
00124 
00125     size_t language_code_size = get_language_code().size();
00126 
00127     return make_const_Span(
00128                _text_record + header_size + language_code_size,
00129                _text_record_size - header_size - language_code_size
00130            );
00131 }
00132 
00133 void Text::move_data(uint8_t *text, size_t size)
00134 {
00135     delete[] _text_record;
00136     _text_record = text;
00137     _text_record_size = size;
00138 }
00139 
00140 bool Text::append_as_record(
00141     MessageBuilder &message_builder,
00142     bool is_last_record
00143 ) const
00144 {
00145     if (!_text_record) {
00146         return false;
00147     }
00148 
00149     // Build the record type
00150     RecordType type(
00151         RecordType::well_known_type,
00152         text_record_type_value
00153     );
00154 
00155     // build the record payload
00156     RecordPayload  payload(_text_record, _text_record_size);
00157     return message_builder.append_record(type, payload, is_last_record);
00158 }
00159 
00160 size_t Text::get_record_size() const
00161 {
00162     if (!_text_record) {
00163         return 0;
00164     }
00165 
00166     return MessageBuilder::compute_record_size(
00167                Record(
00168                    RecordType(
00169                        RecordType::well_known_type,
00170                        text_record_type_value
00171                    ),
00172                    RecordPayload(_text_record, _text_record_size),
00173                    RecordID(),
00174                    /* chunk */ false,
00175                    /* last record */ false
00176                )
00177            );
00178 }
00179 
00180 bool TextParser::do_parse(const Record &record, Text &text)
00181 {
00182     if (record.type.tnf != RecordType::well_known_type) {
00183         return false;
00184     }
00185 
00186     // the record type value should be equal to `T`
00187     if (record.type.value != make_const_Span(text_record_type_value) ||
00188             record.payload.empty()
00189        ) {
00190         return false;
00191     }
00192 
00193     // create the buffer
00194     size_t text_record_size = record.payload.size();
00195     uint8_t *text_record = new uint8_t[text_record_size];
00196     memcpy(text_record, record.payload.data(), text_record_size);
00197 
00198     text.move_data(text_record, text_record_size);
00199 
00200     return true;
00201 }
00202 
00203 } // namespace common
00204 } // namespace ndef
00205 } // namespace nfc
00206 } // namespace mbed