• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2011 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 #pragma once
17 
18 #include "ErrorLog.h"
19 #include "base/Stream.h"
20 
21 #include <assert.h>
22 #include <inttypes.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 
26 class IOStream {
27 protected:
IOStream(size_t bufSize)28     explicit IOStream(size_t bufSize) : m_bufsize(bufSize) {}
29 
~IOStream()30     ~IOStream() {
31         // NOTE: m_buf was owned by the child class thus we expect it to be
32         // released before the object destruction.
33     }
34 
35 public:
36     virtual void *allocBuffer(size_t minSize) = 0;
37     virtual int commitBuffer(size_t size) = 0;
38     virtual int writeFully(const void* buf, size_t len) = 0;
39     virtual const unsigned char *readFully( void *buf, size_t len) = 0;
40 
read(void * buf,size_t bufLen)41     size_t read(void* buf, size_t bufLen) {
42         if (!readRaw(buf, &bufLen)) {
43             return 0;
44         }
45         return bufLen;
46     }
47 
alloc(size_t len)48     unsigned char* alloc(size_t len) {
49         if (m_buf && len > m_free) {
50             if (flush() < 0) {
51                 ERR("Failed to flush in alloc\n");
52                 return NULL; // we failed to flush so something is wrong
53             }
54         }
55 
56         if (!m_buf || len > m_bufsize) {
57             int allocLen = m_bufsize < len ? len : m_bufsize;
58             m_buf = (unsigned char *)allocBuffer(allocLen);
59             if (!m_buf) {
60                 ERR("Alloc (%u bytes) failed\n", allocLen);
61                 return NULL;
62             }
63             m_bufsize = m_free = allocLen;
64         }
65 
66         unsigned char* ptr = m_buf + (m_bufsize - m_free);
67         m_free -= len;
68 
69         return ptr;
70     }
71 
flush()72     int flush() {
73         if (!m_buf || m_free == m_bufsize) return 0;
74 
75         int stat = commitBuffer(m_bufsize - m_free);
76         m_buf = NULL;
77         m_free = 0;
78         return stat;
79     }
80 
readback(void * buf,size_t len)81     const unsigned char *readback(void *buf, size_t len) {
82         flush();
83         return readFully(buf, len);
84     }
85 
save(android::base::Stream * stream)86     void save(android::base::Stream* stream) {
87         stream->putBe32(m_bufsize);
88         stream->putBe32(m_free);
89         stream->putByte(m_buf != nullptr);
90         onSave(stream);
91     }
92 
load(android::base::Stream * stream)93     void load(android::base::Stream* stream) {
94         m_bufsize = stream->getBe32();
95         m_free = stream->getBe32();
96         const bool haveBuf = stream->getByte();
97         const auto buf = onLoad(stream);
98         m_buf = haveBuf ? buf : nullptr;
99     }
100 
101     virtual void* getDmaForReading(uint64_t guest_paddr) = 0;
102     virtual void unlockDma(uint64_t guest_paddr) = 0;
103 
104 protected:
105     virtual const unsigned char *readRaw(void *buf, size_t *inout_len) = 0;
106     virtual void onSave(android::base::Stream* stream) = 0;
107     virtual unsigned char* onLoad(android::base::Stream* stream) = 0;
108 
109     unsigned char* m_buf = nullptr;
110     size_t m_bufsize;
111     size_t m_free = 0;
112 };
113