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