1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <snapuserd/snapuserd_buffer.h>
18 
19 #include <android-base/logging.h>
20 #include <snapuserd/snapuserd_kernel.h>
21 
22 namespace android {
23 namespace snapshot {
24 
Initialize(size_t size)25 void BufferSink::Initialize(size_t size) {
26     buffer_size_ = size + sizeof(struct dm_user_header);
27     buffer_offset_ = 0;
28     buffer_ = std::make_unique<uint8_t[]>(buffer_size_);
29 }
30 
AcquireBuffer(size_t size,size_t to_write)31 void* BufferSink::AcquireBuffer(size_t size, size_t to_write) {
32     CHECK(to_write <= size);
33 
34     void* ptr = GetPayloadBuffer(size);
35     if (!ptr) {
36         return nullptr;
37     }
38     UpdateBufferOffset(to_write);
39     return ptr;
40 }
41 
GetPayloadBuffer(size_t size)42 void* BufferSink::GetPayloadBuffer(size_t size) {
43     char* buffer = reinterpret_cast<char*>(GetBufPtr());
44     struct dm_user_message* msg = (struct dm_user_message*)(&(buffer[0]));
45     if ((buffer_size_ - buffer_offset_ - sizeof(msg->header)) < size) {
46         return nullptr;
47     }
48     return (char*)msg->payload.buf + buffer_offset_;
49 }
50 
GetBuffer(size_t requested,size_t * actual)51 void* BufferSink::GetBuffer(size_t requested, size_t* actual) {
52     void* buf = GetPayloadBuffer(requested);
53     if (!buf) {
54         *actual = 0;
55         return nullptr;
56     }
57     *actual = requested;
58     return buf;
59 }
60 
GetHeaderPtr()61 struct dm_user_header* BufferSink::GetHeaderPtr() {
62     if (!(sizeof(struct dm_user_header) <= buffer_size_)) {
63         return nullptr;
64     }
65     char* buf = reinterpret_cast<char*>(GetBufPtr());
66     struct dm_user_header* header = (struct dm_user_header*)(&(buf[0]));
67     return header;
68 }
69 
GetPayloadBufPtr()70 void* BufferSink::GetPayloadBufPtr() {
71     char* buffer = reinterpret_cast<char*>(GetBufPtr());
72     struct dm_user_message* msg = reinterpret_cast<struct dm_user_message*>(&(buffer[0]));
73     return msg->payload.buf;
74 }
75 
76 }  // namespace snapshot
77 }  // namespace android
78