1 /* 2 * Copyright (c) 2016, Google. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 31 #ifndef _MESSAGE_BUF_H_ 32 #define _MESSAGE_BUF_H_ 33 34 #include <endian.h> 35 #include <cstring> 36 37 namespace android { 38 39 namespace nanohub { 40 41 /* 42 * Marshaling helper; 43 * deals with alignment and endianness. 44 * Assumption is: 45 * read*() parse buffer from device in LE format; 46 * return host endianness, aligned data 47 * write*() primitives take host endinnness, aligned data, 48 * generate buffer to be passed to device in LE format 49 * 50 * Primitives do minimal error checking, only to ensure buffer read/write 51 * safety. Caller is responsible for making sure correct amount of data 52 * has been processed. 53 */ 54 class MessageBuf { 55 char *data; 56 size_t size; 57 size_t pos; 58 bool readOnly; 59 public: MessageBuf(char * buf,size_t bufSize)60 MessageBuf(char *buf, size_t bufSize) { 61 size = bufSize; 62 pos = 0; 63 data = buf; 64 readOnly = false; 65 } MessageBuf(const char * buf,size_t bufSize)66 MessageBuf(const char *buf, size_t bufSize) { 67 size = bufSize; 68 pos = 0; 69 data = const_cast<char *>(buf); 70 readOnly = true; 71 } getData()72 const char *getData() const { return data; } getSize()73 size_t getSize() const { return size; } getPos()74 size_t getPos() const { return pos; } getRoom()75 size_t getRoom() const { return size - pos; } readU8()76 uint8_t readU8() { 77 if (pos == size) { 78 return 0; 79 } 80 return data[pos++]; 81 } writeU8(uint8_t val)82 void writeU8(uint8_t val) { 83 if (pos == size || readOnly) 84 return; 85 data[pos++] = val; 86 } readU16()87 uint16_t readU16() { 88 if (pos > (size - sizeof(uint16_t))) { 89 return 0; 90 } 91 uint16_t val; 92 memcpy(&val, &data[pos], sizeof(val)); 93 pos += sizeof(val); 94 return le16toh(val); 95 } writeU16(uint16_t val)96 void writeU16(uint16_t val) { 97 if (pos > (size - sizeof(uint16_t)) || readOnly) { 98 return; 99 } 100 uint16_t tmp = htole16(val); 101 memcpy(&data[pos], &tmp, sizeof(tmp)); 102 pos += sizeof(tmp); 103 } readU32()104 uint32_t readU32() { 105 if (pos > (size - sizeof(uint32_t))) { 106 return 0; 107 } 108 uint32_t val; 109 memcpy(&val, &data[pos], sizeof(val)); 110 pos += sizeof(val); 111 return le32toh(val); 112 } writeU32(uint32_t val)113 void writeU32(uint32_t val) { 114 if (pos > (size - sizeof(uint32_t)) || readOnly) { 115 return; 116 } 117 uint32_t tmp = htole32(val); 118 memcpy(&data[pos], &tmp, sizeof(tmp)); 119 pos += sizeof(tmp); 120 } readU64()121 uint64_t readU64() { 122 if (pos > (size - sizeof(uint64_t))) { 123 return 0; 124 } 125 uint64_t val; 126 memcpy(&val, &data[pos], sizeof(val)); 127 pos += sizeof(val); 128 return le32toh(val); 129 } writeU64(uint64_t val)130 void writeU64(uint64_t val) { 131 if (pos > (size - sizeof(uint64_t)) || readOnly) { 132 return; 133 } 134 uint64_t tmp = htole64(val); 135 memcpy(&data[pos], &tmp, sizeof(tmp)); 136 pos += sizeof(tmp); 137 } readRaw(size_t bufSize)138 const void *readRaw(size_t bufSize) { 139 if (pos > (size - bufSize)) { 140 return nullptr; 141 } 142 const void *buf = &data[pos]; 143 pos += bufSize; 144 return buf; 145 } writeRaw(const void * buf,size_t bufSize)146 void writeRaw(const void *buf, size_t bufSize) { 147 if (pos > (size - bufSize) || readOnly) { 148 return; 149 } 150 memcpy(&data[pos], buf, bufSize); 151 pos += bufSize; 152 } 153 }; 154 155 }; // namespace nanohub 156 157 }; // namespace android 158 159 #endif 160 161