Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

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     if (_text_record) {
00045         memcpy(_text_record, other._text_record, _text_record_size);
00046     }
00047 }
00048 
00049 Text::Text(
00050     encoding_t text_encoding,
00051     const Span<const uint8_t>  &language_code,
00052     const Span<const uint8_t>  &text
00053 ) : _text_record(NULL),
00054     _text_record_size(0)
00055 {
00056     set_text(text_encoding, language_code, text);
00057 }
00058 
00059 Text::~Text()
00060 {
00061     delete[] _text_record;
00062 }
00063 
00064 Text &Text::operator=(const Text &other)
00065 {
00066     if (this == &other) {
00067         return *this;
00068     }
00069 
00070     _text_record_size = other._text_record_size;
00071 
00072     delete[] _text_record;
00073     if (!other._text_record) {
00074         _text_record = NULL;
00075     } else {
00076         _text_record = new uint8_t[_text_record_size];
00077         memcpy(_text_record, other._text_record, _text_record_size);
00078     }
00079 
00080     return *this;
00081 }
00082 
00083 void Text::set_text(
00084     encoding_t text_encoding,
00085     const Span<const uint8_t>  &language_code,
00086     const Span<const uint8_t>  &text
00087 )
00088 {
00089     delete[] _text_record;
00090 
00091     _text_record_size = header_size + language_code.size() + text.size();
00092     _text_record = new uint8_t[_text_record_size];
00093 
00094     // build the header
00095     _text_record[header_index] = 0;
00096     if (text_encoding == UTF16) {
00097         _text_record[header_index] |= utf16_encoding_bit;
00098     }
00099     _text_record[header_index] |= language_code.size();
00100 
00101     // language code
00102     memcpy(_text_record + language_code_index, language_code.data(), language_code.size());
00103 
00104     // actual text
00105     memcpy(_text_record + language_code_index + language_code.size(), text.data(), text.size());
00106 }
00107 
00108 Text::encoding_t Text::get_encoding() const
00109 {
00110     return (_text_record[header_index] & utf16_encoding_bit) ? UTF16 : UTF8;
00111 }
00112 
00113 Span<const uint8_t>  Text::get_language_code() const
00114 {
00115     return make_const_Span(
00116                _text_record + language_code_index,
00117                _text_record[header_index] & language_code_size_mask
00118            );
00119 }
00120 
00121 Span<const uint8_t>  Text::get_text() const
00122 {
00123     if (!_text_record) {
00124         return Span<const uint8_t> ();
00125     }
00126 
00127     size_t language_code_size = get_language_code().size();
00128 
00129     return make_const_Span(
00130                _text_record + header_size + language_code_size,
00131                _text_record_size - header_size - language_code_size
00132            );
00133 }
00134 
00135 void Text::move_data(uint8_t *text, size_t size)
00136 {
00137     delete[] _text_record;
00138     _text_record = text;
00139     _text_record_size = size;
00140 }
00141 
00142 bool Text::append_as_record(
00143     MessageBuilder &message_builder,
00144     bool is_last_record
00145 ) const
00146 {
00147     if (!_text_record) {
00148         return false;
00149     }
00150 
00151     // Build the record type
00152     RecordType type(
00153         RecordType::well_known_type,
00154         text_record_type_value
00155     );
00156 
00157     // build the record payload
00158     RecordPayload  payload(_text_record, _text_record_size);
00159     return message_builder.append_record(type, payload, is_last_record);
00160 }
00161 
00162 size_t Text::get_record_size() const
00163 {
00164     if (!_text_record) {
00165         return 0;
00166     }
00167 
00168     return MessageBuilder::compute_record_size(
00169                Record(
00170                    RecordType(
00171                        RecordType::well_known_type,
00172                        text_record_type_value
00173                    ),
00174                    RecordPayload(_text_record, _text_record_size),
00175                    RecordID(),
00176                    /* chunk */ false,
00177                    /* last record */ false
00178                )
00179            );
00180 }
00181 
00182 bool TextParser::do_parse(const Record &record, Text &text)
00183 {
00184     if (record.type.tnf != RecordType::well_known_type) {
00185         return false;
00186     }
00187 
00188     // the record type value should be equal to `T`
00189     if (record.type.value != make_const_Span(text_record_type_value) ||
00190             record.payload.empty()
00191        ) {
00192         return false;
00193     }
00194 
00195     // create the buffer
00196     size_t text_record_size = record.payload.size();
00197     uint8_t *text_record = new uint8_t[text_record_size];
00198     memcpy(text_record, record.payload.data(), text_record_size);
00199 
00200     text.move_data(text_record, text_record_size);
00201 
00202     return true;
00203 }
00204 
00205 } // namespace common
00206 } // namespace ndef
00207 } // namespace nfc
00208 } // namespace mbed