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     const char *getData() const { return data; }
     59     size_t getSize() const { return size; }
     60     size_t getPos() const { return pos; }
     61     size_t getRoom() const { return size - pos; }
     62     uint8_t readU8() {
     63         if (pos == size) {
     64             return 0;
     65         }
     66         return data[pos++];
     67     }
     68     void writeU8(uint8_t val) {
     69         if (pos == size || readOnly)
     70             return;
     71         data[pos++] = val;
     72     }
     73     uint16_t readU16() {
     74         if (pos > (size - sizeof(uint16_t))) {
     75             return 0;
     76         }
     77         uint16_t val;
     78         memcpy(&val, &data[pos], sizeof(val));
     79         pos += sizeof(val);
     80         return le16toh(val);
     81     }
     82     void writeU16(uint16_t val) {
     83         if (pos > (size - sizeof(uint16_t)) || readOnly) {
     84             return;
     85         }
     86         uint16_t tmp = htole16(val);
     87         memcpy(&data[pos], &tmp, sizeof(tmp));
     88         pos += sizeof(tmp);
     89     }
     90     uint32_t readU32() {
     91         if (pos > (size - sizeof(uint32_t))) {
     92             return 0;
     93         }
     94         uint32_t val;
     95         memcpy(&val, &data[pos], sizeof(val));
     96         pos += sizeof(val);
     97         return le32toh(val);
     98     }
     99     void writeU32(uint32_t val) {
    100         if (pos > (size - sizeof(uint32_t)) || readOnly) {
    101             return;
    102         }
    103         uint32_t tmp = htole32(val);
    104         memcpy(&data[pos], &tmp, sizeof(tmp));
    105         pos += sizeof(tmp);
    106     }
    107     uint64_t readU64() {
    108         if (pos > (size - sizeof(uint64_t))) {
    109             return 0;
    110         }
    111         uint64_t val;
    112         memcpy(&val, &data[pos], sizeof(val));
    113         pos += sizeof(val);
    114         return le32toh(val);
    115     }
    116     void writeU64(uint64_t val) {
    117         if (pos > (size - sizeof(uint64_t)) || readOnly) {
    118             return;
    119         }
    120         uint64_t tmp = htole64(val);
    121         memcpy(&data[pos], &tmp, sizeof(tmp));
    122         pos += sizeof(tmp);
    123     }
    124     const void *readRaw(size_t bufSize) {
    125         if (pos > (size - bufSize)) {
    126             return nullptr;
    127         }
    128         const void *buf = &data[pos];
    129         pos += bufSize;
    130         return buf;
    131     }
    132     void writeRaw(const void *buf, size_t bufSize) {
    133         if (pos > (size - bufSize) || readOnly) {
    134             return;
    135         }
    136         memcpy(&data[pos], buf, bufSize);
    137         pos += bufSize;
    138     }
    139 };
    140 
    141 }; // namespace nanohub
    142 
    143 }; // namespace android
    144 
    145 #endif
    146 
    147