#ifndef _TCUFORMATUTIL_HPP #define _TCUFORMATUTIL_HPP /*------------------------------------------------------------------------- * drawElements Quality Program Tester Core * ---------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief String format utilities. *//*--------------------------------------------------------------------*/ #include "tcuDefs.hpp" #include "deString.h" #include #include #include #include namespace tcu { namespace Format { // Hexadecimal value formatter. template class Hex { public: Hex (deUint64 value_) : value(value_) {} std::ostream& toStream (std::ostream& stream) const { DE_STATIC_ASSERT(0 < NumDigits && NumDigits <= 16); return stream << "0x" << std::right << std::setfill('0') << std::setw(NumDigits) << std::hex << value; } std::string toString (void) const { std::stringstream stream; toStream(stream); return stream.str(); } private: deUint64 value; }; template std::ostream& operator<< (std::ostream& stream, tcu::Format::Hex hex) { return hex.toStream(stream); } // Bitfield formatter. class BitDesc { public: deUint64 bit; const char* name; BitDesc (deUint64 bit_, const char* name_) : bit(bit_), name(name_) {} }; #define TCU_BIT_DESC(BIT) tcu::Format::BitDesc(BIT, #BIT) template class Bitfield { public: Bitfield (deUint64 value, const BitDesc* begin, const BitDesc* end) : m_value (value) , m_begin (begin) , m_end (end) { } std::ostream& toStream (std::ostream& stream) { deUint64 bitsLeft = m_value; for (const BitDesc* curDesc = m_begin; curDesc != m_end; curDesc++) { if (curDesc->bit & bitsLeft) { if (bitsLeft != m_value) stream << "|"; stream << curDesc->name; bitsLeft ^= curDesc->bit; } } if (bitsLeft != 0) { if (bitsLeft != m_value) stream << "|"; stream << Hex(bitsLeft); } return stream; } private: deUint64 m_value; const BitDesc* m_begin; const BitDesc* m_end; }; template inline std::ostream& operator<< (std::ostream& stream, Bitfield decoder) { return decoder.toStream(stream); } // Enum formatter. // \todo [2012-10-30 pyry] Use template for GetName. template class Enum { public: typedef const char* (*GetNameFunc) (T value); Enum (GetNameFunc getName, T value) : m_getName (getName) , m_value (value) { } std::ostream& toStream (std::ostream& stream) const { const char* name = m_getName(m_value); if (name) return stream << name; else return stream << Hex((deUint64)m_value); } std::string toString (void) const { const char* name = m_getName(m_value); if (name) return std::string(name); else return Hex((deUint64)m_value).toString(); } private: const GetNameFunc m_getName; const T m_value; }; template inline std::ostream& operator<< (std::ostream& stream, const Enum& fmt) { return fmt.toStream(stream); } // Array formatters. template class Array { public: Iterator begin; Iterator end; Array (const Iterator& begin_, const Iterator& end_) : begin(begin_), end(end_) {} }; template class ArrayPointer { public: const T* arr; int size; ArrayPointer (const T* arr_, int size_) : arr(arr_), size(size_) {} }; template std::ostream& operator<< (std::ostream& str, const Array& fmt) { str << "{ "; for (Iterator cur = fmt.begin; cur != fmt.end; ++cur) { if (cur != fmt.begin) str << ", "; str << *cur; } str << " }"; return str; } template std::ostream& operator<< (std::ostream& str, const ArrayPointer& fmt) { if (fmt.arr != DE_NULL) return str << Array(fmt.arr, fmt.arr+fmt.size); else return str << "(null)"; } // Hex format iterator (useful for combining with ArrayFormatter). // \todo [2012-10-30 pyry] Implement more generic format iterator. template class HexIterator { public: HexIterator (Iterator iter) : m_iter(iter) {} HexIterator& operator++ (void) { ++m_iter; return *this; } HexIterator operator++ (int) { return HexIterator(m_iter++); } bool operator== (const HexIterator& other) const { return m_iter == other.m_iter; } bool operator!= (const HexIterator& other) const { return m_iter != other.m_iter; } #if !defined(__INTELLISENSE__) // Intellisense in VS2013 crashes when parsing this. Hex operator* (void) const { return Hex(*m_iter); } #endif private: Iterator m_iter; }; } // Format template inline deUint64 makeMask64 (void) { return (1ull< inline deUint64 makeMask64<64> (void) { return ~0ull; } template inline deUint64 toUint64 (T value) { return (deUint64)value & makeMask64(); } /** Format value as hexadecimal number. */ template inline Format::Hex toHex (T value) { return Format::Hex(toUint64(value)); } /** Format value as hexadecimal number. */ template inline Format::Hex toHex (T value) { return Format::Hex(toUint64(value)); } /** Decode and format bitfield. */ template inline Format::Bitfield formatBitfield (T value, const Format::BitDesc (&desc)[Size]) { return Format::Bitfield((deUint64)value, &desc[0], &desc[Size]); } /** Format array contents. */ template inline Format::Array formatArray (const Iterator& begin, const Iterator& end) { return Format::Array(begin, end); } /** Format array contents. */ template inline Format::ArrayPointer formatArray (const T* arr, int size) { return Format::ArrayPointer(arr, size); } /** Format array contents. */ template inline Format::ArrayPointer formatArray (const T (&arr)[Size]) { return Format::ArrayPointer(arr, Size); } } // tcu #endif // _TCUFORMATUTIL_HPP