1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
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  */
15 
16 #ifndef SERIALBUFFER_H
17 #define SERIALBUFFER_H
18 
19 #include <vector>
20 #include <cstdint>
21 #include <utility>
22 #include "macro_utils.h"
23 
24 namespace DistributedDB {
25 class SerialBuffer {
26 public:
27     SerialBuffer() = default; // Default constructor must be explicitly provided due to DISABLE_COPY_ASSIGN_MOVE
28     ~SerialBuffer();
29 
30     DISABLE_COPY_ASSIGN_MOVE(SerialBuffer);
31 
32     // will call the func before alloc buff, calculate the head len which is used for data service
33     void SetExtendHeadLength(uint32_t extendHeaderLen);
34     uint32_t GetExtendHeadLength() const;
35     // May be directly send out, so padding is needed
36     int AllocBufferByPayloadLength(uint32_t inPayloadLen, uint32_t inHeaderLen);
37 
38     // In case assemble fragment to frame, so no padding is needed, using frameLen as inTotalLen
39     int AllocBufferByTotalLength(uint32_t inTotalLen, uint32_t inHeaderLen);
40 
41     // In case directly received, inTotalLen not include the padding, using frameLen as inTotalLen
42     int SetExternalBuff(const uint8_t *buff, uint32_t inTotalLen, uint32_t inHeaderLen);
43 
44     // Create a SerialBuffer that has a independent bytes_ and point to the same externalBytes_
45     SerialBuffer *Clone(int &outErrorNo);
46 
47     // After return E_OK, this SerialBuffer can cross thread. Do nothing indeed if it already able to cross thread.
48     int ConvertForCrossThread();
49 
50     uint32_t GetSize() const;
51 
52     uint8_t *GetOringinalAddr() const;
53 
54     std::pair<uint8_t *, uint32_t> GetWritableBytesForEntireBuffer();
55     std::pair<uint8_t *, uint32_t> GetWritableBytesForEntireFrame();
56     std::pair<uint8_t *, uint32_t> GetWritableBytesForHeader();
57     std::pair<uint8_t *, uint32_t> GetWritableBytesForPayload();
58 
59     std::pair<const uint8_t *, uint32_t> GetReadOnlyBytesForEntireBuffer() const;
60     std::pair<const uint8_t *, uint32_t> GetReadOnlyBytesForEntireFrame() const;
61     std::pair<const uint8_t *, uint32_t> GetReadOnlyBytesForHeader() const;
62     std::pair<const uint8_t *, uint32_t> GetReadOnlyBytesForPayload() const;
63 
64     static const uint32_t MAX_EXTEND_HEAD_LENGTH = 512;
65 private:
66     uint8_t *oringinalBytes_ = nullptr; // all beytes start addr
67     uint8_t *bytes_ = nullptr; // distributeddb start addr
68     const uint8_t *externalBytes_ = nullptr;
69     uint32_t totalLen_ = 0;
70     uint32_t headerLen_ = 0;
71     uint32_t payloadLen_ = 0;
72     uint32_t paddingLen_ = 0;
73     // only apply message will use extend header
74     uint32_t extendHeadLen_ = 0;
75     bool isExternalStackMemory_ = false;
76 };
77 } // namespace DistributedDB
78 
79 #endif // SERIALBUFFER_H
80