michael@0: /* GRAPHITE2 LICENSING michael@0: michael@0: Copyright 2011, SIL International michael@0: All rights reserved. michael@0: michael@0: This library is free software; you can redistribute it and/or modify michael@0: it under the terms of the GNU Lesser General Public License as published michael@0: by the Free Software Foundation; either version 2.1 of License, or michael@0: (at your option) any later version. michael@0: michael@0: This program is distributed in the hope that it will be useful, michael@0: but WITHOUT ANY WARRANTY; without even the implied warranty of michael@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU michael@0: Lesser General Public License for more details. michael@0: michael@0: You should also have received a copy of the GNU Lesser General Public michael@0: License along with this library in the file named "LICENSE". michael@0: If not, write to the Free Software Foundation, 51 Franklin Street, michael@0: Suite 500, Boston, MA 02110-1335, USA or visit their web page on the michael@0: internet at http://www.fsf.org/licenses/lgpl.html. michael@0: michael@0: Alternatively, the contents of this file may be used under the terms of the michael@0: Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public michael@0: License, as published by the Free Software Foundation, either version 2 michael@0: of the License or (at your option) any later version. michael@0: */ michael@0: michael@0: /* michael@0: Description: michael@0: A set of fast template based decoders for decoding values of any C integer michael@0: type up to long int size laid out with most significant byte first or least michael@0: significant byte first (aka big endian or little endian). These are CPU michael@0: byte order agnostic and will function the same regardless of the CPUs native michael@0: byte order. michael@0: michael@0: Being template based means if the either le or be class is not used then michael@0: template code of unused functions will not be instantiated by the compiler michael@0: and thus shouldn't cause any overhead. michael@0: */ michael@0: michael@0: #include michael@0: michael@0: #pragma once michael@0: michael@0: michael@0: class be michael@0: { michael@0: template michael@0: inline static unsigned long int _peek(const unsigned char * p) { michael@0: return _peek(p) << (S/2)*8 | _peek(p+S/2); michael@0: } michael@0: public: michael@0: template michael@0: inline static T peek(const void * p) { michael@0: return T(_peek(static_cast(p))); michael@0: } michael@0: michael@0: template michael@0: inline static T read(const unsigned char * &p) { michael@0: const T r = T(_peek(p)); michael@0: p += sizeof r; michael@0: return r; michael@0: } michael@0: michael@0: template michael@0: inline static T swap(const T x) { michael@0: return T(_peek(reinterpret_cast(&x))); michael@0: } michael@0: michael@0: template michael@0: inline static void skip(const unsigned char * &p, size_t n=1) { michael@0: p += sizeof(T)*n; michael@0: } michael@0: }; michael@0: michael@0: template<> michael@0: inline unsigned long int be::_peek<1>(const unsigned char * p) { return *p; } michael@0: michael@0: michael@0: class le michael@0: { michael@0: template michael@0: inline static unsigned long int _peek(const unsigned char * p) { michael@0: return _peek(p) | _peek(p+S/2) << (S/2)*8; michael@0: } michael@0: public: michael@0: template michael@0: inline static T peek(const void * p) { michael@0: return T(_peek(static_cast(p))); michael@0: } michael@0: michael@0: template michael@0: inline static T read(const unsigned char * &p) { michael@0: const T r = T(_peek(p)); michael@0: p += sizeof r; michael@0: return r; michael@0: } michael@0: michael@0: template michael@0: inline static T swap(const T x) { michael@0: return T(_peek(reinterpret_cast(&x))); michael@0: } michael@0: michael@0: template michael@0: inline static void skip(const unsigned char * &p, size_t n=1) { michael@0: p += sizeof(T)*n; michael@0: } michael@0: }; michael@0: michael@0: template<> michael@0: inline unsigned long int le::_peek<1>(const unsigned char * p) { return *p; } michael@0: