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