103f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao/* 203f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * Copyright 2011, The Android Open Source Project 303f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * 403f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License"); 503f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * you may not use this file except in compliance with the License. 603f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * You may obtain a copy of the License at 703f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * 803f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * http://www.apache.org/licenses/LICENSE-2.0 903f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * 1003f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * Unless required by applicable law or agreed to in writing, software 1103f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS, 1203f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1303f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * See the License for the specific language governing permissions and 1403f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao * limitations under the License. 1503f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao */ 1603f75e22ad9ea75dc536d199c3d11a98884be314Shih-wei Liao 17b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien#if !defined(SERIALIZE_H) 18b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien#define SERIALIZE_H 19b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 20c85473833f3b6f0dc951698e2481e3d3d98942eeLogan Chien#include "traits.h" 21c85473833f3b6f0dc951698e2481e3d3d98942eeLogan Chien 220f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien#include <algorithm> 230f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien#include <vector> 240f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 25c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa#include "utils/rsl_assert.h" 26b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien#include <string.h> 27b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien#include <stdint.h> 28203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien#include <stddef.h> 29b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 30b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chiennamespace detail { 31b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien inline bool is_host_little_endian() { 32b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien unsigned long one = 0x1UL; 33b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien return *reinterpret_cast<unsigned char *>(&one); 34b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien } 35b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 360f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien inline void swap_byte_order(unsigned char (&array)[1]) { 37b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien // Nothing to do 38b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien } 39b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 400f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien inline void swap_byte_order(unsigned char (&array)[2]) { 410f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien std::swap(array[0], array[1]); 42b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien } 43b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 440f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien inline void swap_byte_order(unsigned char (&array)[4]) { 450f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien std::swap(array[0], array[3]); 460f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien std::swap(array[1], array[2]); 47b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien } 48b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 490f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien inline void swap_byte_order(unsigned char (&array)[8]) { 500f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien std::swap(array[0], array[7]); 510f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien std::swap(array[1], array[6]); 520f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien std::swap(array[2], array[5]); 530f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien std::swap(array[3], array[4]); 54b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien } 550f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien} 56b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 57b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 5800e067ef50c860668ed67003309d5ae71aa02b32Logan Chientemplate <bool isArchiveLittleEndian> 5900e067ef50c860668ed67003309d5ae71aa02b32Logan Chienclass ArchiveReader { 600f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chienprivate: 610f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien unsigned char const *buf_begin; 620f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien unsigned char const *buf_end; 630f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien unsigned char const *cursor; 64203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien unsigned char const *cursor_base; 65b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 660f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien bool good; 67b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 68b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chienpublic: 6900e067ef50c860668ed67003309d5ae71aa02b32Logan Chien ArchiveReader(unsigned char const *buf = NULL, size_t size = 0) 70203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien : buf_begin(buf), buf_end(buf + size), 7100e067ef50c860668ed67003309d5ae71aa02b32Logan Chien cursor(buf), cursor_base(NULL), good(buf != NULL) { 720f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 730f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 7418a839ad774a15637f481ea6da561cef8dd9c309Logan Chien void prologue(size_t size) { 75c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa rsl_assert(cursor_base == NULL); 76203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien cursor_base = cursor; 770f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 780f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 7918a839ad774a15637f481ea6da561cef8dd9c309Logan Chien void epilogue(size_t size) { 80c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa rsl_assert(cursor_base != NULL); 81c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa rsl_assert(cursor_base + size >= cursor); 8218a839ad774a15637f481ea6da561cef8dd9c309Logan Chien cursor = cursor_base + size; 83203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien cursor_base = NULL; 840f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 850f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 860f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien void seek(off_t off, bool from_begin = false) { 870f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien if (from_begin) { 880f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien cursor = buf_begin + off; 890f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } else { 900f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien cursor += off; 910f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 920f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 930f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 9400e067ef50c860668ed67003309d5ae71aa02b32Logan Chien void readBytes(void *array, size_t size) { 95e04718485e859b865d14fad20df1f5ac602e9e58Logan Chien if (!good || cursor + size > buf_end) { 96e04718485e859b865d14fad20df1f5ac602e9e58Logan Chien good = false; 97e04718485e859b865d14fad20df1f5ac602e9e58Logan Chien } else { 98e04718485e859b865d14fad20df1f5ac602e9e58Logan Chien memcpy(array, cursor, size); 99e04718485e859b865d14fad20df1f5ac602e9e58Logan Chien } 100e04718485e859b865d14fad20df1f5ac602e9e58Logan Chien } 101e04718485e859b865d14fad20df1f5ac602e9e58Logan Chien 102203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien template <size_t size> 103203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien void operator&(char (&array)[size]) { 10400e067ef50c860668ed67003309d5ae71aa02b32Logan Chien readBytes(array, size); 105203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien seek(size); 1060f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 1070f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 108203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien template <size_t size> 109203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien void operator&(unsigned char (&array)[size]) { 11000e067ef50c860668ed67003309d5ae71aa02b32Logan Chien readBytes(array, size); 111203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien seek(size); 112203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien } 1130f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 11471e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien template <typename T> 11571e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien void operator&(T &v) { 11671e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien seekAlignment<T>(); 11771e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien readBytes(&v, TypeTraits<T>::size); 11871e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien seek(TypeTraits<T>::size); 11971e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien 12071e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien if (isArchiveLittleEndian != detail::is_host_little_endian()) { 12171e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien detail::swap_byte_order( 12271e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien reinterpret_cast<unsigned char (&)[TypeTraits<T>::size]>(v)); 12371e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien } 12471e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien } 1250f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 126fd1e42426bcaca4bae92e579dd8ec0f8fe36ad0fLogan Chien operator void const *() const { 1270f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien return good ? this : 0; 1280f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 1290f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 1300f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien bool operator!() const { 1310f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien return !good; 1320f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien } 133203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien 134203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chienprivate: 135203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien template <typename T> 13671e5a4a2fa18ff55b1e04e73b70b2938150a143cLogan Chien void seekAlignment() { 13700e067ef50c860668ed67003309d5ae71aa02b32Logan Chien size_t align = TypeTraits<T>::align; 138dd4ed54c02bb7abc16adcfcf78bf631aa26deb18Logan Chien size_t delta = static_cast<size_t>(cursor - buf_begin) % align; 13900e067ef50c860668ed67003309d5ae71aa02b32Logan Chien 14000e067ef50c860668ed67003309d5ae71aa02b32Logan Chien if (delta > 0) { 14100e067ef50c860668ed67003309d5ae71aa02b32Logan Chien seek(align - delta); 142203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien } 143203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien } 144203bf2d31f9e4f55bcee1899e14bade235f1f1eeLogan Chien 145b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien}; 146b10ad5844867c7a33bb0d994e3ba55c17e41d18dLogan Chien 14700e067ef50c860668ed67003309d5ae71aa02b32Logan Chientypedef ArchiveReader<true> ArchiveReaderLE; 14800e067ef50c860668ed67003309d5ae71aa02b32Logan Chientypedef ArchiveReader<false> ArchiveReaderBE; 1490f6173b8f0bb91772f29f701a55933bdf40f2ee4Logan Chien 150de9cff6dadefcdce43728f2bc54dd65675657e02Logan Chien#endif // SERIALIZE_H 151