diff options
author | Rafael Reilova <rafael7@users.noreply.github.com> | 2014-11-16 21:52:24 -0500 |
---|---|---|
committer | Craig Robbins <kde.psych@gmail.com> | 2014-11-21 22:33:48 +1000 |
commit | f7d65091f83abe1cb1a70d6823291df8accbe6ab (patch) | |
tree | 6955cb513a7d92e9db775e33e18389dfc2738667 /src | |
parent | d406ac994b8092c5bd2dc32eda1a2eafbf95a30c (diff) | |
download | minetest-f7d65091f83abe1cb1a70d6823291df8accbe6ab.tar.gz minetest-f7d65091f83abe1cb1a70d6823291df8accbe6ab.tar.bz2 minetest-f7d65091f83abe1cb1a70d6823291df8accbe6ab.zip |
serialize.h: use machine native byte swapping if available, fall-back to previous generic method if not (supported for GCC using endian.h, detection done in cmake) write/readARGB8() - just write 32-bit color in one op, instead of 4 1-byte ops cleanup: removed unneeded buffer init for some serialize-out functions use a #define for the fixed point factor in read/writeF1000()
nodemetadata.cpp, nodetimer.cpp
optimzation: simpler deserialize node position method
staticobject.cpp:
cleanup: use util/serialize.h inlines instead of its own de/serialization
serialize.cpp:
minor optimization/cleanup: avoid generation of unneeded string temporary
CMakeLists.txt, cmake_config.h.in: detection of endian.h
config.h: added HAVE_ENDIAN_H
Commits due to feedback squashed
Signed-off-by: Craig Robbins <kde.psych@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/cmake_config.h.in | 1 | ||||
-rw-r--r-- | src/config.h | 4 | ||||
-rw-r--r-- | src/nodemetadata.cpp | 12 | ||||
-rw-r--r-- | src/nodetimer.cpp | 12 | ||||
-rw-r--r-- | src/staticobject.cpp | 32 | ||||
-rw-r--r-- | src/util/serialize.cpp | 12 | ||||
-rw-r--r-- | src/util/serialize.h | 124 |
8 files changed, 115 insertions, 85 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b1fd26247..ec6c7fbac 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,6 +2,7 @@ project(minetest) cmake_minimum_required( VERSION 2.6 ) INCLUDE(CheckCSourceRuns) +INCLUDE(CheckIncludeFiles) # Set some random things default to not being visible in the GUI mark_as_advanced(EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH) @@ -313,6 +314,8 @@ if(ENABLE_REDIS) endif(REDIS_LIBRARY AND REDIS_INCLUDE_DIR) endif(ENABLE_REDIS) +CHECK_INCLUDE_FILES(endian.h HAVE_ENDIAN_H) + configure_file( "${PROJECT_SOURCE_DIR}/cmake_config.h.in" "${PROJECT_BINARY_DIR}/cmake_config.h" diff --git a/src/cmake_config.h.in b/src/cmake_config.h.in index 64a4c002b..e111a650d 100644 --- a/src/cmake_config.h.in +++ b/src/cmake_config.h.in @@ -20,6 +20,7 @@ #define CMAKE_VERSION_PATCH @VERSION_PATCH@ #define CMAKE_VERSION_PATCH_ORIG @VERSION_PATCH_ORIG@ #define CMAKE_VERSION_EXTRA_STRING "@VERSION_EXTRA@" +#define CMAKE_HAVE_ENDIAN_H @HAVE_ENDIAN_H@ #ifdef NDEBUG #define CMAKE_BUILD_TYPE "Release" diff --git a/src/config.h b/src/config.h index f1aef03aa..b07aa5d22 100644 --- a/src/config.h +++ b/src/config.h @@ -36,6 +36,8 @@ #define USE_REDIS 0 #endif +#define HAVE_ENDIAN_H 0 + #ifdef USE_CMAKE_CONFIG_H #include "cmake_config.h" #undef PROJECT_NAME @@ -72,6 +74,8 @@ #define PRODUCT_VERSION_STRING CMAKE_PRODUCT_VERSION_STRING #undef VERSION_EXTRA_STRING #define VERSION_EXTRA_STRING CMAKE_VERSION_EXTRA_STRING + #undef HAVE_ENDIAN_H + #define HAVE_ENDIAN_H CMAKE_HAVE_ENDIAN_H #endif #ifdef __ANDROID__ diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp index 4cdd61767..0631d974a 100644 --- a/src/nodemetadata.cpp +++ b/src/nodemetadata.cpp @@ -130,12 +130,12 @@ void NodeMetadataList::deSerialize(std::istream &is, IGameDef *gamedef) { u16 p16 = readU16(is); - v3s16 p(0,0,0); - p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; - p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE; - p.Y += p16 / MAP_BLOCKSIZE; - p16 -= p.Y * MAP_BLOCKSIZE; - p.X += p16; + v3s16 p; + p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1; + p.Y = p16 / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE - 1; + p.X = p16; if(m_data.find(p) != m_data.end()) { diff --git a/src/nodetimer.cpp b/src/nodetimer.cpp index 5fc652bb7..d4971c873 100644 --- a/src/nodetimer.cpp +++ b/src/nodetimer.cpp @@ -96,12 +96,12 @@ void NodeTimerList::deSerialize(std::istream &is, u8 map_format_version) { u16 p16 = readU16(is); - v3s16 p(0,0,0); - p.Z += p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; - p16 -= p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE; - p.Y += p16 / MAP_BLOCKSIZE; - p16 -= p.Y * MAP_BLOCKSIZE; - p.X += p16; + v3s16 p; + p.Z = p16 / MAP_BLOCKSIZE / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE * MAP_BLOCKSIZE - 1; + p.Y = p16 / MAP_BLOCKSIZE; + p16 &= MAP_BLOCKSIZE - 1; + p.X = p16; NodeTimer t; t.deSerialize(is); diff --git a/src/staticobject.cpp b/src/staticobject.cpp index 973257fcf..16d98605b 100644 --- a/src/staticobject.cpp +++ b/src/staticobject.cpp @@ -22,42 +22,31 @@ with this program; if not, write to the Free Software Foundation, Inc., void StaticObject::serialize(std::ostream &os) { - char buf[12]; // type - buf[0] = type; - os.write(buf, 1); + writeU8(os, type); // pos - writeV3S32((u8*)buf, v3s32(pos.X*1000,pos.Y*1000,pos.Z*1000)); - os.write(buf, 12); + writeV3F1000(os, pos); // data os<<serializeString(data); } void StaticObject::deSerialize(std::istream &is, u8 version) { - char buf[12]; // type - is.read(buf, 1); - type = buf[0]; + type = readU8(is); // pos - is.read(buf, 12); - v3s32 intp = readV3S32((u8*)buf); - pos.X = (f32)intp.X/1000; - pos.Y = (f32)intp.Y/1000; - pos.Z = (f32)intp.Z/1000; + pos = readV3F1000(is); // data data = deSerializeString(is); } void StaticObjectList::serialize(std::ostream &os) { - char buf[12]; // version - buf[0] = 0; - os.write(buf, 1); + u8 version = 0; + writeU8(os, version); // count u16 count = m_stored.size() + m_active.size(); - writeU16((u8*)buf, count); - os.write(buf, 2); + writeU16(os, count); for(std::list<StaticObject>::iterator i = m_stored.begin(); i != m_stored.end(); ++i) @@ -75,13 +64,10 @@ void StaticObjectList::serialize(std::ostream &os) } void StaticObjectList::deSerialize(std::istream &is) { - char buf[12]; // version - is.read(buf, 1); - u8 version = buf[0]; + u8 version = readU8(is); // count - is.read(buf, 2); - u16 count = readU16((u8*)buf); + u16 count = readU16(is); for(u16 i=0; i<count; i++) { StaticObject s_obj; diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index 8779ee634..8a108a0ff 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -68,11 +68,11 @@ std::string deSerializeString(std::istream &is) if(is.gcount() != 2) throw SerializationError("deSerializeString: size not read"); u16 s_size = readU16((u8*)buf); + std::string s; if(s_size == 0) - return ""; + return s; Buffer<char> buf2(s_size); is.read(&buf2[0], s_size); - std::string s; s.reserve(s_size); s.append(&buf2[0], s_size); return s; @@ -86,9 +86,9 @@ std::wstring deSerializeWideString(std::istream &is) if(is.gcount() != 2) throw SerializationError("deSerializeString: size not read"); u16 s_size = readU16((u8*)buf); - if(s_size == 0) - return L""; std::wstring s; + if(s_size == 0) + return s; s.reserve(s_size); for(u32 i=0; i<s_size; i++) { @@ -118,11 +118,11 @@ std::string deSerializeLongString(std::istream &is) if(is.gcount() != 4) throw SerializationError("deSerializeLongString: size not read"); u32 s_size = readU32((u8*)buf); + std::string s; if(s_size == 0) - return ""; + return s; Buffer<char> buf2(s_size); is.read(&buf2[0], s_size); - std::string s; s.reserve(s_size); s.append(&buf2[0], s_size); return s; diff --git a/src/util/serialize.h b/src/util/serialize.h index 3f9925287..79907799f 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -21,9 +21,63 @@ with this program; if not, write to the Free Software Foundation, Inc., #define UTIL_SERIALIZE_HEADER #include "../irrlichttypes_bloated.h" +#include "config.h" +#if HAVE_ENDIAN_H +#include <endian.h> +#include <string.h> // for memcpy +#endif #include <iostream> #include <string> +#define FIXEDPOINT_FACTOR 1000.0f +#define FIXEDPOINT_INVFACTOR (1.0f/FIXEDPOINT_FACTOR) + +#if HAVE_ENDIAN_H +// use machine native byte swapping routines +// Note: memcpy below is optimized out by modern compilers + +inline void writeU64(u8* data, u64 i) +{ + u64 val = htobe64(i); + memcpy(data, &val, 8); +} + +inline void writeU32(u8* data, u32 i) +{ + u32 val = htobe32(i); + memcpy(data, &val, 4); +} + +inline void writeU16(u8* data, u16 i) +{ + u16 val = htobe16(i); + memcpy(data, &val, 2); +} + +inline u64 readU64(const u8* data) +{ + u64 val; + memcpy(&val, data, 8); + return be64toh(val); +} + +inline u32 readU32(const u8* data) +{ + u32 val; + memcpy(&val, data, 4); + return be32toh(val); +} + +inline u16 readU16(const u8* data) +{ + u16 val; + memcpy(&val, data, 2); + return be16toh(val); +} + +#else +// generic byte-swapping implementation + inline void writeU64(u8 *data, u64 i) { data[0] = ((i>>56)&0xff); @@ -50,11 +104,6 @@ inline void writeU16(u8 *data, u16 i) data[1] = ((i>> 0)&0xff); } -inline void writeU8(u8 *data, u8 i) -{ - data[0] = ((i>> 0)&0xff); -} - inline u64 readU64(const u8 *data) { return ((u64)data[0]<<56) | ((u64)data[1]<<48) @@ -73,6 +122,13 @@ inline u16 readU16(const u8 *data) return (data[0]<<8) | (data[1]<<0); } +#endif + +inline void writeU8(u8 *data, u8 i) +{ + data[0] = ((i>> 0)&0xff); +} + inline u8 readU8(const u8 *data) { return (data[0]<<0); @@ -100,10 +156,10 @@ inline s8 readS8(const u8 *data){ } inline void writeF1000(u8 *data, f32 i){ - writeS32(data, i*1000); + writeS32(data, i*FIXEDPOINT_FACTOR); } inline f32 readF1000(const u8 *data){ - return (f32)readS32(data)/1000.; + return (f32)readS32(data)*FIXEDPOINT_INVFACTOR; } inline void writeV3S32(u8 *data, v3s32 p) @@ -195,20 +251,12 @@ inline v3s16 readV3S16(const u8 *data) inline void writeARGB8(u8 *data, video::SColor p) { - writeU8(&data[0], p.getAlpha()); - writeU8(&data[1], p.getRed()); - writeU8(&data[2], p.getGreen()); - writeU8(&data[3], p.getBlue()); + writeU32(data, p.color); } inline video::SColor readARGB8(const u8 *data) { - video::SColor p( - readU8(&data[0]), - readU8(&data[1]), - readU8(&data[2]), - readU8(&data[3]) - ); + video::SColor p(readU32(data)); return p; } @@ -218,7 +266,7 @@ inline video::SColor readARGB8(const u8 *data) inline void writeU8(std::ostream &os, u8 p) { - char buf[1] = {0}; + char buf[1]; writeU8((u8*)buf, p); os.write(buf, 1); } @@ -231,7 +279,7 @@ inline u8 readU8(std::istream &is) inline void writeU16(std::ostream &os, u16 p) { - char buf[2] = {0}; + char buf[2]; writeU16((u8*)buf, p); os.write(buf, 2); } @@ -244,7 +292,7 @@ inline u16 readU16(std::istream &is) inline void writeU32(std::ostream &os, u32 p) { - char buf[4] = {0}; + char buf[4]; writeU32((u8*)buf, p); os.write(buf, 4); } @@ -257,46 +305,34 @@ inline u32 readU32(std::istream &is) inline void writeS32(std::ostream &os, s32 p) { - char buf[4] = {0}; - writeS32((u8*)buf, p); - os.write(buf, 4); + writeU32(os, (u32) p); } inline s32 readS32(std::istream &is) { - char buf[4] = {0}; - is.read(buf, 4); - return readS32((u8*)buf); + return (s32)readU32(is); } inline void writeS16(std::ostream &os, s16 p) { - char buf[2] = {0}; - writeS16((u8*)buf, p); - os.write(buf, 2); + writeU16(os, (u16) p); } inline s16 readS16(std::istream &is) { - char buf[2] = {0}; - is.read(buf, 2); - return readS16((u8*)buf); + return (s16)readU16(is); } inline void writeS8(std::ostream &os, s8 p) { - char buf[1] = {0}; - writeS8((u8*)buf, p); - os.write(buf, 1); + writeU8(os, (u8) p); } inline s8 readS8(std::istream &is) { - char buf[1] = {0}; - is.read(buf, 1); - return readS8((u8*)buf); + return (s8)readU8(is); } inline void writeF1000(std::ostream &os, f32 p) { - char buf[4] = {0}; + char buf[4]; writeF1000((u8*)buf, p); os.write(buf, 4); } @@ -322,7 +358,7 @@ inline v3f readV3F1000(std::istream &is) inline void writeV2F1000(std::ostream &os, v2f p) { - char buf[8] = {0}; + char buf[8]; writeV2F1000((u8*)buf, p); os.write(buf, 8); } @@ -335,7 +371,7 @@ inline v2f readV2F1000(std::istream &is) inline void writeV2S16(std::ostream &os, v2s16 p) { - char buf[4] = {0}; + char buf[4]; writeV2S16((u8*)buf, p); os.write(buf, 4); } @@ -348,7 +384,7 @@ inline v2s16 readV2S16(std::istream &is) inline void writeV2S32(std::ostream &os, v2s32 p) { - char buf[8] = {0}; + char buf[8]; writeV2S32((u8*)buf, p); os.write(buf, 8); } @@ -361,7 +397,7 @@ inline v2s32 readV2S32(std::istream &is) inline void writeV3S16(std::ostream &os, v3s16 p) { - char buf[6] = {0}; + char buf[6]; writeV3S16((u8*)buf, p); os.write(buf, 6); } @@ -374,7 +410,7 @@ inline v3s16 readV3S16(std::istream &is) inline void writeARGB8(std::ostream &os, video::SColor p) { - char buf[4] = {0}; + char buf[4]; writeARGB8((u8*)buf, p); os.write(buf, 4); } |