diff options
-rw-r--r-- | cppuhelper/source/typedescriptionprovider.cxx | 149 | ||||
-rw-r--r-- | registry/tools/reg2bin.cxx | 46 |
2 files changed, 159 insertions, 36 deletions
diff --git a/cppuhelper/source/typedescriptionprovider.cxx b/cppuhelper/source/typedescriptionprovider.cxx index 2d195180b717..7e12c292e353 100644 --- a/cppuhelper/source/typedescriptionprovider.cxx +++ b/cppuhelper/source/typedescriptionprovider.cxx @@ -49,6 +49,7 @@ #include "com/sun/star/uno/XInterface.hpp" #include "cppuhelper/compbase2.hxx" #include "cppuhelper/implbase1.hxx" +#include "osl/endian.h" #include "osl/file.h" #include "osl/file.hxx" #include "osl/mutex.hxx" @@ -221,11 +222,11 @@ // *** 7: UNSIGNED HYPER // **** followed by UInt64 value // *** 8: FLOAT -// **** followed by UInt32 value, representing values in IEEE-754 single -// precision format +// **** followed by 4-byte value, representing values in ISO 60599 binary32 +// format, LSB first // *** 9: DOUBLE -// **** followed by UInt64 value, representing values in IEEE-754 double -// precision format +// **** followed by 8-byte value, representing values in ISO 60599 binary64 +// format, LSB first // // Memory layout: // @@ -236,33 +237,51 @@ namespace { -// sizeof (UInt16) == 2 -struct UInt16 { +// sizeof (Memory16) == 2 +struct Memory16 { unsigned char byte[2]; - sal_uInt16 get() const { + sal_uInt16 getUnsigned16() const { return static_cast< sal_uInt16 >(byte[0]) | (static_cast< sal_uInt16 >(byte[1]) << 8); } }; -// sizeof (UInt32) == 4 -struct UInt32 { +// sizeof (Memory32) == 4 +struct Memory32 { unsigned char byte[4]; - sal_uInt32 get() const { + sal_uInt32 getUnsigned32() const { return static_cast< sal_uInt32 >(byte[0]) | (static_cast< sal_uInt32 >(byte[1]) << 8) | (static_cast< sal_uInt32 >(byte[2]) << 16) | (static_cast< sal_uInt32 >(byte[3]) << 24); } + + float getIso60599Binary32() const { + // Create a copy in either case, for alingment: + unsigned char buf[4]; +#if defined OSL_LITENDIAN + buf[0] = byte[0]; + buf[1] = byte[1]; + buf[2] = byte[2]; + buf[3] = byte[3]; +#else + buf[0] = byte[3]; + buf[1] = byte[2]; + buf[2] = byte[1]; + buf[3] = byte[0]; +#endif + return *reinterpret_cast< float * >(buf); + // assuming float is ISO 60599 binary32 + } }; -// sizeof (UInt64) == 8 -struct UInt64 { +// sizeof (Memory64) == 8 +struct Memory64 { unsigned char byte[8]; - sal_uInt64 get() const { + sal_uInt64 getUnsigned64() const { return static_cast< sal_uInt64 >(byte[0]) | (static_cast< sal_uInt64 >(byte[1]) << 8) | (static_cast< sal_uInt64 >(byte[2]) << 16) @@ -272,6 +291,32 @@ struct UInt64 { | (static_cast< sal_uInt64 >(byte[6]) << 48) | (static_cast< sal_uInt64 >(byte[7]) << 56); } + + double getIso60599Binary64() const { + // Create a copy in either case, for alingment: + unsigned char buf[8]; +#if defined OSL_LITENDIAN + buf[0] = byte[0]; + buf[1] = byte[1]; + buf[2] = byte[2]; + buf[3] = byte[3]; + buf[4] = byte[4]; + buf[5] = byte[5]; + buf[6] = byte[6]; + buf[7] = byte[7]; +#else + buf[0] = byte[7]; + buf[1] = byte[6]; + buf[2] = byte[5]; + buf[3] = byte[4]; + buf[4] = byte[3]; + buf[5] = byte[2]; + buf[6] = byte[1]; + buf[7] = byte[0]; +#endif + return *reinterpret_cast< double * >(buf); + // assuming double is ISO 60599 binary64 + } }; struct MappedFile: @@ -287,6 +332,10 @@ struct MappedFile: sal_uInt64 read64(sal_uInt32 offset) const; + float readIso60599Binary32(sal_uInt32 offset) const; + + double readIso60599Binary64(sal_uInt32 offset) const; + rtl::OUString readNameNul(sal_uInt32 offset) const; rtl::OUString readNameLen(sal_uInt32 offset, sal_uInt32 * newOffset = 0) @@ -306,6 +355,10 @@ private: sal_uInt32 get32(sal_uInt32 offset) const; sal_uInt64 get64(sal_uInt32 offset) const; + + float getIso60599Binary32(sal_uInt32 offset) const; + + double getIso60599Binary64(sal_uInt32 offset) const; }; MappedFile::MappedFile(rtl::OUString const & fileUrl) { @@ -378,6 +431,26 @@ sal_uInt64 MappedFile::read64(sal_uInt32 offset) const { return get64(offset); } +float MappedFile::readIso60599Binary32(sal_uInt32 offset) const { + assert(size >= 8); + if (offset > size - 4) { + throw css::uno::DeploymentException( + "broken UNOIDL file: offset for 32-bit value too large", + css::uno::Reference< css::uno::XInterface >()); + } + return getIso60599Binary32(offset); +} + +double MappedFile::readIso60599Binary64(sal_uInt32 offset) const { + assert(size >= 8); + if (offset > size - 8) { + throw css::uno::DeploymentException( + "broken UNOIDL file: offset for 64-bit value too large", + css::uno::Reference< css::uno::XInterface >()); + } + return getIso60599Binary64(offset); +} + rtl::OUString MappedFile::readNameNul(sal_uInt32 offset) const { if (offset > size) { throw css::uno::DeploymentException( @@ -473,22 +546,36 @@ sal_uInt8 MappedFile::get8(sal_uInt32 offset) const { sal_uInt16 MappedFile::get16(sal_uInt32 offset) const { assert(size >= 8); assert(offset <= size - 2); - return reinterpret_cast< UInt16 const * >( - static_cast< char const * >(address) + offset)->get(); + return reinterpret_cast< Memory16 const * >( + static_cast< char const * >(address) + offset)->getUnsigned16(); } sal_uInt32 MappedFile::get32(sal_uInt32 offset) const { assert(size >= 8); assert(offset <= size - 4); - return reinterpret_cast< UInt32 const * >( - static_cast< char const * >(address) + offset)->get(); + return reinterpret_cast< Memory32 const * >( + static_cast< char const * >(address) + offset)->getUnsigned32(); } sal_uInt64 MappedFile::get64(sal_uInt32 offset) const { assert(size >= 8); assert(offset <= size - 8); - return reinterpret_cast< UInt64 const * >( - static_cast< char const * >(address) + offset)->get(); + return reinterpret_cast< Memory64 const * >( + static_cast< char const * >(address) + offset)->getUnsigned64(); +} + +float MappedFile::getIso60599Binary32(sal_uInt32 offset) const { + assert(size >= 8); + assert(offset <= size - 4); + return reinterpret_cast< Memory32 const * >( + static_cast< char const * >(address) + offset)->getIso60599Binary32(); +} + +double MappedFile::getIso60599Binary64(sal_uInt32 offset) const { + assert(size >= 8); + assert(offset <= size - 8); + return reinterpret_cast< Memory64 const * >( + static_cast< char const * >(address) + offset)->getIso60599Binary64(); } css::uno::Reference< css::reflection::XTypeDescription > resolve( @@ -2035,8 +2122,8 @@ private: // sizeof (MapEntry) == 8 struct MapEntry { - UInt32 name; - UInt32 data; + Memory32 name; + Memory32 data; }; class Enumeration: @@ -2139,7 +2226,7 @@ void Enumeration::proceed() { assert(!positions_.empty()); assert(positions_.top().position < positions_.top().end); if (deep_) { - sal_uInt32 off = positions_.top().position->data.get(); + sal_uInt32 off = positions_.top().position->data.getUnsigned32(); int v = file_->read8(off); bool recurse; bool cgroup = bool(); @@ -2155,7 +2242,8 @@ void Enumeration::proceed() { if (recurse) { rtl::OUString prefix( positions_.top().prefix - + file_->readNameNul(positions_.top().position->name.get()) + + file_->readNameNul( + positions_.top().position->name.getUnsigned32()) + "."); sal_uInt32 mapSize = file_->read32(off + 1); if (8 * mapSize > file_->size - off - 5) { //TODO: overflow @@ -2187,7 +2275,7 @@ void Enumeration::findMatch() { assert(matches(css::uno::TypeClass_CONSTANT)); match = true; } else { - sal_uInt32 off = positions_.top().position->data.get(); + sal_uInt32 off = positions_.top().position->data.getUnsigned32(); int v = file_->read8(off); css::uno::TypeClass tc; switch (v & 0x1F) { @@ -2232,7 +2320,8 @@ void Enumeration::findMatch() { } if (match) { current_ = positions_.top().prefix - + file_->readNameNul(positions_.top().position->name.get()); + + file_->readNameNul( + positions_.top().position->name.getUnsigned32()); return; } } @@ -2383,9 +2472,11 @@ css::uno::Any Provider::getByHierarchicalName(rtl::OUString const & aName) any <<= file_->read64(off + 1); break; case 8: // FLOAT - //TODO + any <<= file_->readIso60599Binary32(off + 1); + break; case 9: // DOUBLE - //TODO + any <<= file_->readIso60599Binary64(off + 1); + break; default: throw css::uno::DeploymentException( ("broken UNOIDL file: bad constant type byte " @@ -3036,7 +3127,7 @@ sal_uInt32 Provider::findInMap( default: // COMPARE_EQUAL break; } - sal_uInt32 off = mapBegin[n].data.get(); + sal_uInt32 off = mapBegin[n].data.getUnsigned32(); if (off == 0) { throw css::uno::DeploymentException( "broken UNOIDL file: map entry data offset is null", @@ -3050,7 +3141,7 @@ Provider::Compare Provider::compare( MapEntry const * entry) const { assert(entry != 0); - sal_uInt32 off = entry->name.get(); + sal_uInt32 off = entry->name.getUnsigned32(); if (off > file_->size - 1) { // at least a trailing NUL throw css::uno::DeploymentException( "broken UNOIDL file: string offset too large", diff --git a/registry/tools/reg2bin.cxx b/registry/tools/reg2bin.cxx index 5983b5629937..2a1ca05152c3 100644 --- a/registry/tools/reg2bin.cxx +++ b/registry/tools/reg2bin.cxx @@ -9,6 +9,7 @@ #include "sal/config.h" +#include <algorithm> #include <cassert> #include <cstdlib> #include <cstring> @@ -17,6 +18,7 @@ #include <utility> #include <vector> +#include "osl/endian.h" #include "osl/file.h" #include "osl/file.hxx" #include "osl/process.h" @@ -31,6 +33,7 @@ #include "rtl/textenc.h" #include "rtl/textcvt.h" #include "rtl/ustring.hxx" +#include "sal/macros.h" #include "sal/main.h" namespace { @@ -910,8 +913,9 @@ void write8(osl::File & file, sal_uInt64 value) { std::cerr << "Cannot write value >= 2^8; input is too large\n"; std::exit(EXIT_FAILURE); } - unsigned char buf = value & 0xFF; - write(file, &buf, 1); + unsigned char buf[1]; + buf[0] = value & 0xFF; + write(file, buf, SAL_N_ELEMENTS(buf)); } void write16(osl::File & file, sal_uInt64 value) { @@ -922,7 +926,7 @@ void write16(osl::File & file, sal_uInt64 value) { unsigned char buf[2]; buf[0] = value & 0xFF; buf[1] = (value >> 8) & 0xFF; - write(file, buf, 2); + write(file, buf, SAL_N_ELEMENTS(buf)); } void write32(osl::File & file, sal_uInt64 value) { @@ -935,7 +939,7 @@ void write32(osl::File & file, sal_uInt64 value) { buf[1] = (value >> 8) & 0xFF; buf[2] = (value >> 16) & 0xFF; buf[3] = (value >> 24) & 0xFF; - write(file, buf, 4); + write(file, buf, SAL_N_ELEMENTS(buf)); } void write64(osl::File & file, sal_uInt64 value) { @@ -948,7 +952,31 @@ void write64(osl::File & file, sal_uInt64 value) { buf[3] = (value >> 40) & 0xFF; buf[3] = (value >> 48) & 0xFF; buf[3] = (value >> 56) & 0xFF; - write(file, buf, 8); + write(file, buf, SAL_N_ELEMENTS(buf)); +} + +void writeIso60599Binary32(osl::File & file, float value) { + unsigned char buf[4]; + *reinterpret_cast< float * >(buf) = value; + // assuming float is ISO 60599 binary32 +#if defined OSL_BIGENDIAN + std::swap(buf[0], buf[3]); + std::swap(buf[1], buf[2]); +#endif + write(file, buf, SAL_N_ELEMENTS(buf)); +} + +void writeIso60599Binary64(osl::File & file, double value) { + unsigned char buf[8]; + *reinterpret_cast< double * >(buf) = value; + // assuming double is ISO 60599 binary64 +#if defined OSL_BIGENDIAN + std::swap(buf[0], buf[7]); + std::swap(buf[1], buf[6]); + std::swap(buf[2], buf[5]); + std::swap(buf[3], buf[4]); +#endif + write(file, buf, SAL_N_ELEMENTS(buf)); } rtl::OString toAscii(rtl::OUString const & name) { @@ -1196,7 +1224,6 @@ sal_uInt64 writeMap( static_cast< sal_uInt32 >(j->second.constantValue.l)); break; case CONSTANT_TYPE_UNSIGNED_LONG: - case CONSTANT_TYPE_FLOAT: //access through union for strict-aliasing write32(file, j->second.constantValue.ul); break; case CONSTANT_TYPE_HYPER: @@ -1205,9 +1232,14 @@ sal_uInt64 writeMap( static_cast< sal_uInt64 >(j->second.constantValue.h)); break; case CONSTANT_TYPE_UNSIGNED_HYPER: - case CONSTANT_TYPE_DOUBLE: //access through union for strict-aliasing write64(file, j->second.constantValue.uh); break; + case CONSTANT_TYPE_FLOAT: + writeIso60599Binary32(file, j->second.constantValue.f); + break; + case CONSTANT_TYPE_DOUBLE: + writeIso60599Binary64(file, j->second.constantValue.d); + break; default: std::abort(); // this cannot happen } |