Home | History | Annotate | Download | only in contexthubhal
      1 /*
      2  * Copyright (C) 2016 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 #ifndef _MESSAGE_BUF_H_
     18 #define _MESSAGE_BUF_H_
     19 
     20 #include <endian.h>
     21 #include <cstring>
     22 
     23 namespace android {
     24 
     25 namespace nanohub {
     26 
     27 /*
     28  * Marshaling helper;
     29  * deals with alignment and endianness.
     30  * Assumption is:
     31  * read*()  parse buffer from device in LE format;
     32  *          return host endianness, aligned data
     33  * write*() primitives take host endinnness, aligned data,
     34  *          generate buffer to be passed to device in LE format
     35  *
     36  * Primitives do minimal error checking, only to ensure buffer read/write
     37  * safety. Caller is responsible for making sure correct amount of data
     38  * has been processed.
     39  */
     40 class MessageBuf {
     41     char *data;
     42     size_t size;
     43     size_t pos;
     44     bool readOnly;
     45 public:
     46     MessageBuf(char *buf, size_t bufSize) {
     47         size = bufSize;
     48         pos = 0;
     49         data = buf;
     50         readOnly = false;
     51     }
     52     MessageBuf(const char *buf, size_t bufSize) {
     53         size = bufSize;
     54         pos = 0;
     55         data = const_cast<char *>(buf);
     56         readOnly = true;
     57     }
     58     void reset() { pos = 0; }
     59     const char *getData() const { return data; }
     60     size_t getSize() const { return size; }
     61     size_t getPos() const { return pos; }
     62     size_t getRoom() const { return size - pos; }
     63     uint8_t readU8() {
     64         if (pos == size) {
     65             return 0;
     66         }
     67         return data[pos++];
     68     }
     69     void writeU8(uint8_t val) {
     70         if (pos == size || readOnly)
     71             return;
     72         data[pos++] = val;
     73     }
     74     uint16_t readU16() {
     75         if (pos > (size - sizeof(uint16_t))) {
     76             return 0;
     77         }
     78         uint16_t val;
     79         memcpy(&val, &data[pos], sizeof(val));
     80         pos += sizeof(val);
     81         return le16toh(val);
     82     }
     83     void writeU16(uint16_t val) {
     84         if (pos > (size - sizeof(uint16_t)) || readOnly) {
     85             return;
     86         }
     87         uint16_t tmp = htole16(val);
     88         memcpy(&data[pos], &tmp, sizeof(tmp));
     89         pos += sizeof(tmp);
     90     }
     91     uint32_t readU32() {
     92         if (pos > (size - sizeof(uint32_t))) {
     93             return 0;
     94         }
     95         uint32_t val;
     96         memcpy(&val, &data[pos], sizeof(val));
     97         pos += sizeof(val);
     98         return le32toh(val);
     99     }
    100     void writeU32(uint32_t val) {
    101         if (pos > (size - sizeof(uint32_t)) || readOnly) {
    102             return;
    103         }
    104         uint32_t tmp = htole32(val);
    105         memcpy(&data[pos], &tmp, sizeof(tmp));
    106         pos += sizeof(tmp);
    107     }
    108     uint64_t readU64() {
    109         if (pos > (size - sizeof(uint64_t))) {
    110             return 0;
    111         }
    112         uint64_t val;
    113         memcpy(&val, &data[pos], sizeof(val));
    114         pos += sizeof(val);
    115         return le32toh(val);
    116     }
    117     void writeU64(uint64_t val) {
    118         if (pos > (size - sizeof(uint64_t)) || readOnly) {
    119             return;
    120         }
    121         uint64_t tmp = htole64(val);
    122         memcpy(&data[pos], &tmp, sizeof(tmp));
    123         pos += sizeof(tmp);
    124     }
    125     const void *readRaw(size_t bufSize) {
    126         if (pos > (size - bufSize)) {
    127             return nullptr;
    128         }
    129         const void *buf = &data[pos];
    130         pos += bufSize;
    131         return buf;
    132     }
    133     void writeRaw(const void *buf, size_t bufSize) {
    134         if (pos > (size - bufSize) || readOnly) {
    135             return;
    136         }
    137         memcpy(&data[pos], buf, bufSize);
    138         pos += bufSize;
    139     }
    140 };
    141 
    142 }; // namespace nanohub
    143 
    144 }; // namespace android
    145 
    146 #endif
    147 
    148