1b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines/* 2b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Copyright 2011, The Android Open Source Project 3b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 4b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * you may not use this file except in compliance with the License. 6b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * You may obtain a copy of the License at 7b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 8b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 10b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Unless required by applicable law or agreed to in writing, software 11b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * See the License for the specific language governing permissions and 14b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * limitations under the License. 15b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines */ 16b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 17b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#if !defined(SERIALIZE_H) 18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define SERIALIZE_H 19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "traits.h" 21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <algorithm> 23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <vector> 24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/rsl_assert.h" 26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <string.h> 27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stdint.h> 28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stddef.h> 29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesnamespace detail { 31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines inline bool is_host_little_endian() { 32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned long one = 0x1UL; 33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return *reinterpret_cast<unsigned char *>(&one); 34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines inline void swap_byte_order(unsigned char (&array)[1]) { 37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Nothing to do 38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines inline void swap_byte_order(unsigned char (&array)[2]) { 41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::swap(array[0], array[1]); 42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines inline void swap_byte_order(unsigned char (&array)[4]) { 45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::swap(array[0], array[3]); 46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::swap(array[1], array[2]); 47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines inline void swap_byte_order(unsigned char (&array)[8]) { 50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::swap(array[0], array[7]); 51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::swap(array[1], array[6]); 52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::swap(array[2], array[5]); 53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::swap(array[3], array[4]); 54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <bool isArchiveLittleEndian> 59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ArchiveReader { 60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate: 61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *buf_begin; 62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *buf_end; 63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *cursor; 64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char const *cursor_base; 65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines bool good; 67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic: 69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ArchiveReader(unsigned char const *buf = NULL, size_t size = 0) 70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines : buf_begin(buf), buf_end(buf + size), 71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines cursor(buf), cursor_base(NULL), good(buf != NULL) { 72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void prologue(size_t size) { 75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsl_assert(cursor_base == NULL); 76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines cursor_base = cursor; 77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void epilogue(size_t size) { 80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsl_assert(cursor_base != NULL); 81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsl_assert(cursor_base + size >= cursor); 82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines cursor = cursor_base + size; 83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines cursor_base = NULL; 84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void seek(off_t off, bool from_begin = false) { 87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (from_begin) { 88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines cursor = buf_begin + off; 89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } else { 90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines cursor += off; 91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void readBytes(void *array, size_t size) { 95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!good || cursor + size > buf_end) { 96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines good = false; 97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } else { 98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines memcpy(array, cursor, size); 99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines template <size_t size> 103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void operator&(char (&array)[size]) { 104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines readBytes(array, size); 105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines seek(size); 106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines template <size_t size> 109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void operator&(unsigned char (&array)[size]) { 110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines readBytes(array, size); 111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines seek(size); 112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines template <typename T> 115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void operator&(T &v) { 116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines seekAlignment<T>(); 117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines readBytes(&v, TypeTraits<T>::size); 118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines seek(TypeTraits<T>::size); 119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (isArchiveLittleEndian != detail::is_host_little_endian()) { 121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines detail::swap_byte_order( 122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines reinterpret_cast<unsigned char (&)[TypeTraits<T>::size]>(v)); 123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines operator void const *() const { 127b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return good ? this : 0; 128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines bool operator!() const { 131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return !good; 132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate: 135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines template <typename T> 136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void seekAlignment() { 137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t align = TypeTraits<T>::align; 138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t delta = static_cast<size_t>(cursor - buf_begin) % align; 139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (delta > 0) { 141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines seek(align - delta); 142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}; 146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestypedef ArchiveReader<true> ArchiveReaderLE; 148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestypedef ArchiveReader<false> ArchiveReaderBE; 149b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 150b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // SERIALIZE_H 151