1a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis/* 2a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** 3a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** Copyright 2017, The Android Open Source Project 4a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** 5a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** Licensed under the Apache License, Version 2.0 (the "License"); 6a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** you may not use this file except in compliance with the License. 7a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** You may obtain a copy of the License at 8a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** 9a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** http://www.apache.org/licenses/LICENSE-2.0 10a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** 11a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** Unless required by applicable law or agreed to in writing, software 12a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** distributed under the License is distributed on an "AS IS" BASIS, 13a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** See the License for the specific language governing permissions and 15a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis** limitations under the License. 16a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis*/ 17a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 18a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis#ifndef CONFIRMATIONUI_1_0_DEFAULT_CBOR_H_ 19a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis#define CONFIRMATIONUI_1_0_DEFAULT_CBOR_H_ 20a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 21a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis#include <stddef.h> 22a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis#include <stdint.h> 23a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis#include <type_traits> 24a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 25a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisnamespace android { 26a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisnamespace hardware { 27a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisnamespace confirmationui { 28a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisnamespace support { 29a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 30a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename In, typename Out> 31a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisOut copy(In begin, In end, Out out) { 32a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis while (begin != end) { 33a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis *out++ = *begin++; 34a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 35a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return out; 36a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 37a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 38a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisenum class Type : uint8_t { 39a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis NUMBER = 0, 40a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis NEGATIVE = 1, 41a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis BYTE_STRING = 2, 42a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis TEXT_STRING = 3, 43a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis ARRAY = 4, 44a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis MAP = 5, 45a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis TAG = 6, 46a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis FLOAT = 7, 47a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 48a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 49a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisenum class Error : uint32_t { 50a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis OK = 0, 51a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis OUT_OF_DATA = 1, 52a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis MALFORMED = 2, 53a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis MALFORMED_UTF8 = 3, 54a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 55a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 56a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename Key, typename Value> 57a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct MapElement { 58a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis const Key& key_; 59a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis const Value& value_; 60a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis MapElement(const Key& key, const Value& value) : key_(key), value_(value) {} 61a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 62a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 63a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename... Elems> 64a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct Array; 65a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 66a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename Head, typename... Tail> 67a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct Array<Head, Tail...> { 68a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis const Head& head_; 69a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis Array<Tail...> tail_; 70a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis Array(const Head& head, const Tail&... tail) : head_(head), tail_(tail...) {} 71a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis constexpr size_t size() const { return sizeof...(Tail) + 1; }; 72a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 73a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 74a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <> 75a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct Array<> {}; 76a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 77a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct TextStr {}; 78a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct ByteStr {}; 79a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 80a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T, typename Variant> 81a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct StringBuffer { 82a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis const T* data_; 83a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis size_t size_; 84a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis StringBuffer(const T* data, size_t size) : data_(data), size_(size) { 85a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis static_assert(sizeof(T) == 1, "elements too large"); 86a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 87a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis const T* data() const { return data_; } 88a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis size_t size() const { return size_; } 89a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 90a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 91a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis/** 92a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis * Takes a char array turns it into a StringBuffer of TextStr type. The length of the resulting 93a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis * StringBuffer is size - 1, effectively stripping the 0 character from the region being considered. 94a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis * If the terminating 0 shall not be stripped use text_keep_last. 95a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis */ 96a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <size_t size> 97a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisStringBuffer<char, TextStr> text(const char (&str)[size]) { 98a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (size > 0) return StringBuffer<char, TextStr>(str, size - 1); 99a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return StringBuffer<char, TextStr>(str, size); 100a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 101a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 102a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis/** 103a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis * As opposed to text(const char (&str)[size] this function does not strips the last character. 104a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis */ 105a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <size_t size> 106a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisStringBuffer<char, TextStr> text_keep_last(const char (&str)[size]) { 107a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return StringBuffer<char, TextStr>(str, size); 108a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 109a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 110a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 111a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisauto getData(const T& v) -> decltype(v.data()) { 112a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return v.data(); 113a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 114a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 115a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 116a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisauto getData(const T& v) -> decltype(v.c_str()) { 117a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return v.c_str(); 118a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 119a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 120a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 121a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisauto text(const T& str) -> StringBuffer<std::decay_t<decltype(*getData(str))>, TextStr> { 122a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return StringBuffer<std::decay_t<decltype(*getData(str))>, TextStr>(getData(str), str.size()); 123a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 124a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 125a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline StringBuffer<char, TextStr> text(const char* str, size_t size) { 126a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return StringBuffer<char, TextStr>(str, size); 127a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 128a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 129a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T, size_t size> 130a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisStringBuffer<T, ByteStr> bytes(const T (&str)[size]) { 131a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return StringBuffer<T, ByteStr>(str, size); 132a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 133a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 134a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 135a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisStringBuffer<T, ByteStr> bytes(const T* str, size_t size) { 136a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return StringBuffer<T, ByteStr>(str, size); 137a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 138a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 139a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 140a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisauto bytes(const T& str) -> StringBuffer<std::decay_t<decltype(*getData(str))>, ByteStr> { 141a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return StringBuffer<std::decay_t<decltype(*getData(str))>, ByteStr>(getData(str), str.size()); 142a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 143a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 144a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename... Elems> 145a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct Map; 146a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 147a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename HeadKey, typename HeadValue, typename... Tail> 148a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct Map<MapElement<HeadKey, HeadValue>, Tail...> { 149a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis const MapElement<HeadKey, HeadValue>& head_; 150a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis Map<Tail...> tail_; 151a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis Map(const MapElement<HeadKey, HeadValue>& head, const Tail&... tail) 152a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis : head_(head), tail_(tail...) {} 153a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis constexpr size_t size() const { return sizeof...(Tail) + 1; }; 154a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 155a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 156a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <> 157a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct Map<> {}; 158a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 159a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename... Keys, typename... Values> 160a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisMap<MapElement<Keys, Values>...> map(const MapElement<Keys, Values>&... elements) { 161a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return Map<MapElement<Keys, Values>...>(elements...); 162a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 163a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 164a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename... Elements> 165a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisArray<Elements...> arr(const Elements&... elements) { 166a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return Array<Elements...>(elements...); 167a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 168a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 169a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename Key, typename Value> 170a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisMapElement<Key, Value> pair(const Key& k, const Value& v) { 171a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return MapElement<Key, Value>(k, v); 172a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 173a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 174a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <size_t size> 175a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct getUnsignedType; 176a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 177a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <> 178a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct getUnsignedType<sizeof(uint8_t)> { 179a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis typedef uint8_t type; 180a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 181a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <> 182a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct getUnsignedType<sizeof(uint16_t)> { 183a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis typedef uint16_t type; 184a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 185a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <> 186a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct getUnsignedType<sizeof(uint32_t)> { 187a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis typedef uint32_t type; 188a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 189a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <> 190a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisstruct getUnsignedType<sizeof(uint64_t)> { 191a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis typedef uint64_t type; 192a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 193a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 194a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <size_t size> 195a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisusing Unsigned = typename getUnsignedType<size>::type; 196a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 197a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisclass WriteState { 198a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis public: 199a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis WriteState() : data_(nullptr), size_(0), error_(Error::OK) {} 200a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis WriteState(uint8_t* buffer, size_t size) : data_(buffer), size_(size), error_(Error::OK) {} 201a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis WriteState(uint8_t* buffer, size_t size, Error error) 202a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis : data_(buffer), size_(size), error_(error) {} 203a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis template <size_t size> 204a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis WriteState(uint8_t (&buffer)[size]) : data_(buffer), size_(size), error_(Error::OK) {} 205a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 206a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis WriteState& operator++() { 207a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (size_) { 208a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis ++data_; 209a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis --size_; 210a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } else { 211a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis error_ = Error::OUT_OF_DATA; 212a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 213a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return *this; 214a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 215a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis WriteState& operator+=(size_t offset) { 216a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (offset > size_) { 217a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis error_ = Error::OUT_OF_DATA; 218a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } else { 219a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis data_ += offset; 220a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis size_ -= offset; 221a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 222a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return *this; 223a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 224a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis operator bool() const { return error_ == Error::OK; } 225a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 226a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis uint8_t* data_; 227a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis size_t size_; 228a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis Error error_; 229a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis}; 230a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 231a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState writeHeader(WriteState wState, Type type, const uint64_t value); 232a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisbool checkUTF8Copy(const char* begin, const char* const end, uint8_t* out); 233a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 234a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 235a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState writeNumber(WriteState wState, const T& v) { 236a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (!wState) return wState; 237a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (v >= 0) { 238a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeHeader(wState, Type::NUMBER, v); 239a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } else { 240a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeHeader(wState, Type::NEGATIVE, UINT64_C(-1) - v); 241a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 242a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 243a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 244a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const uint8_t& v) { 245a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 246a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 247a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const int8_t& v) { 248a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 249a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 250a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const uint16_t& v) { 251a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 252a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 253a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const int16_t& v) { 254a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 255a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 256a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const uint32_t& v) { 257a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 258a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 259a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const int32_t& v) { 260a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 261a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 262a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const uint64_t& v) { 263a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 264a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 265a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskisinline WriteState write(const WriteState& wState, const int64_t& v) { 266a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeNumber(wState, v); 267a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 268a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 269a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 270a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState write(WriteState wState, const StringBuffer<T, TextStr>& v) { 271a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState = writeHeader(wState, Type::TEXT_STRING, v.size()); 272a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis uint8_t* buffer = wState.data_; 273a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState += v.size(); 274a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (!wState) return wState; 275a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (!checkUTF8Copy(v.data(), v.data() + v.size(), buffer)) { 276a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState.error_ = Error::MALFORMED_UTF8; 277a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis } 278a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return wState; 279a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 280a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 281a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename T> 282a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState write(WriteState wState, const StringBuffer<T, ByteStr>& v) { 283a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState = writeHeader(wState, Type::BYTE_STRING, v.size()); 284a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis uint8_t* buffer = wState.data_; 285a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState += v.size(); 286a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (!wState) return wState; 287a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis static_assert(sizeof(*v.data()) == 1, "elements too large"); 288a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis copy(v.data(), v.data() + v.size(), buffer); 289a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return wState; 290a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 291a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 292a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <template <typename...> class Arr> 293a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState writeArrayHelper(WriteState wState, const Arr<>&) { 294a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return wState; 295a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 296a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 297a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <template <typename...> class Arr, typename Head, typename... Tail> 298a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState writeArrayHelper(WriteState wState, const Arr<Head, Tail...>& arr) { 299a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState = write(wState, arr.head_); 300a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeArrayHelper(wState, arr.tail_); 301a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 302a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 303a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename... Elems> 304a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState write(WriteState wState, const Map<Elems...>& map) { 305a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (!wState) return wState; 306a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState = writeHeader(wState, Type::MAP, map.size()); 307a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeArrayHelper(wState, map); 308a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 309a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 310a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename... Elems> 311a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState write(WriteState wState, const Array<Elems...>& arr) { 312a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (!wState) return wState; 313a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState = writeHeader(wState, Type::ARRAY, arr.size()); 314a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return writeArrayHelper(wState, arr); 315a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 316a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 317a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename Key, typename Value> 318a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState write(WriteState wState, const MapElement<Key, Value>& element) { 319a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis if (!wState) return wState; 320a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState = write(wState, element.key_); 321a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return write(wState, element.value_); 322a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 323a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 324a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskistemplate <typename Head, typename... Tail> 325a9f0fb0db1e62168534c5a27e123e1413b818586Janis DanisevskisWriteState write(WriteState wState, const Head& head, const Tail&... tail) { 326a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis wState = write(wState, head); 327a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis return write(wState, tail...); 328a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} 329a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 330a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} // namespace support 331a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} // namespace confirmationui 332a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} // namespace hardware 333a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis} // namespace android 334a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis 335a9f0fb0db1e62168534c5a27e123e1413b818586Janis Danisevskis#endif // CONFIRMATIONUI_1_0_DEFAULT_CBOR_H_ 336