1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #ifndef nvs_types_h
15 #define nvs_types_h
16
17 #include <cstdint>
18 #include <cstring>
19 #include <cassert>
20 #include <algorithm>
21 #include "nvs.h"
22 #include "nvs_handle.hpp"
23 #include "compressed_enum_table.hpp"
24 #include "string.h"
25
26 using namespace std;
27
28 namespace nvs
29 {
30
31 /**
32 * Used to recognize transient states of a blob. Once a blob is modified, new chunks with the new data are written
33 * with a new version. The version is saved in the highest bit of Item::chunkIndex as well as in
34 * Item::blobIndex::chunkStart.
35 * If a chunk is modified and hence re-written, the version swaps: 0x0 -> 0x80 or 0x80 -> 0x0.
36 */
37 enum class VerOffset: uint8_t {
38 VER_0_OFFSET = 0x0,
39 VER_1_OFFSET = 0x80,
40 VER_ANY = 0xff,
41 };
42
isVariableLengthType(ItemType type)43 inline bool isVariableLengthType(ItemType type)
44 {
45 return (type == ItemType::BLOB ||
46 type == ItemType::SZ ||
47 type == ItemType::BLOB_DATA);
48 }
49
50 class Item
51 {
52 public:
53 union {
54 struct {
55 uint8_t nsIndex;
56 ItemType datatype;
57 uint8_t span;
58 uint8_t chunkIndex;
59 uint32_t crc32;
60 char key[NVS_KEY_NAME_MAX_SIZE];
61 union {
62 struct {
63 uint16_t dataSize;
64 uint16_t reserved;
65 uint32_t dataCrc32;
66 } varLength;
67 struct {
68 uint32_t dataSize;
69 uint8_t chunkCount; // Number of children data blobs.
70 VerOffset chunkStart; // Offset from which the chunkIndex for children blobs starts
71 uint16_t reserved;
72 } blobIndex;
73 uint8_t data[8];
74 };
75 };
76 uint8_t rawData[32];
77 };
78
79 static const size_t MAX_KEY_LENGTH = sizeof(key) - 1;
80
81 // 0xff cannot be used as a valid chunkIndex for blob datatype.
82 static const uint8_t CHUNK_ANY = 0xff;
83
84
Item(uint8_t nsIndex,ItemType datatype,uint8_t span,const char * key_,uint8_t chunkIdx=CHUNK_ANY)85 Item(uint8_t nsIndex, ItemType datatype, uint8_t span, const char* key_, uint8_t chunkIdx = CHUNK_ANY)
86 : nsIndex(nsIndex), datatype(datatype), span(span), chunkIndex(chunkIdx)
87 {
88 std::fill_n(reinterpret_cast<uint32_t*>(key), sizeof(key) / 4, 0xffffffff);
89 std::fill_n(reinterpret_cast<uint32_t*>(data), sizeof(data) / 4, 0xffffffff);
90 if (key_) {
91 strncpy(key, key_, sizeof(key) - 1);
92 key[sizeof(key) - 1] = 0;
93 } else {
94 key[0] = 0;
95 }
96 }
97
Item()98 Item()
99 {
100 }
101
102 uint32_t calculateCrc32() const;
103 uint32_t calculateCrc32WithoutValue() const;
104 static uint32_t calculateCrc32(const uint8_t* data, size_t size);
105
getKey(char * dst,size_t dstSize)106 void getKey(char* dst, size_t dstSize)
107 {
108 strncpy(dst, key, min(dstSize, sizeof(key)));
109 dst[dstSize-1] = 0;
110 }
111
112 template<typename T>
getValue(T & dst)113 void getValue(T& dst)
114 {
115 assert(itemTypeOf(dst) == datatype);
116 dst = *reinterpret_cast<T*>(data);
117 }
118 };
119
120 } // namespace nvs
121
122 #endif /* nvs_types_h */
123