LCOV - code coverage report
Current view: top level - src/util - serialize.h (source / functions) Hit Total Coverage
Test: report Lines: 95 177 53.7 %
Date: 2015-07-11 18:23:49 Functions: 26 47 55.3 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #ifndef UTIL_SERIALIZE_HEADER
      21             : #define UTIL_SERIALIZE_HEADER
      22             : 
      23             : #include "../irrlichttypes_bloated.h"
      24             : #include "config.h"
      25             : #if HAVE_ENDIAN_H
      26             : #include <endian.h>
      27             : #include <string.h> // for memcpy
      28             : #endif
      29             : #include <iostream>
      30             : #include <string>
      31             : 
      32             : #define FIXEDPOINT_FACTOR 1000.0f
      33             : #define FIXEDPOINT_INVFACTOR (1.0f/FIXEDPOINT_FACTOR)
      34             : 
      35             : #if HAVE_ENDIAN_H
      36             : // use machine native byte swapping routines
      37             : // Note: memcpy below is optimized out by modern compilers
      38             : 
      39           0 : inline void writeU64(u8* data, u64 i)
      40             : {
      41           0 :         u64 val = htobe64(i);
      42           0 :         memcpy(data, &val, 8);
      43           0 : }
      44             : 
      45       10213 : inline void writeU32(u8* data, u32 i)
      46             : {
      47       10213 :         u32 val = htobe32(i);
      48       10213 :         memcpy(data, &val, 4);
      49       10213 : }
      50             : 
      51       16151 : inline void writeU16(u8* data, u16 i)
      52             : {
      53       16151 :         u16 val = htobe16(i);
      54       16151 :         memcpy(data, &val, 2);
      55       16151 : }
      56             : 
      57           1 : inline u64 readU64(const u8* data)
      58             : {
      59             :         u64 val;
      60           1 :         memcpy(&val, data, 8);
      61           1 :         return be64toh(val);
      62             : }
      63             : 
      64      457097 : inline u32 readU32(const u8* data)
      65             : {
      66             :         u32 val;
      67      457097 :         memcpy(&val, data, 4);
      68      457097 :         return be32toh(val);
      69             : }
      70             : 
      71     3926637 : inline u16 readU16(const u8* data)
      72             : {
      73             :         u16 val;
      74     3926637 :         memcpy(&val, data, 2);
      75     3926637 :         return be16toh(val);
      76             : }
      77             : 
      78             : #else
      79             : // generic byte-swapping implementation
      80             : 
      81             : inline void writeU64(u8 *data, u64 i)
      82             : {
      83             :         data[0] = ((i>>56)&0xff);
      84             :         data[1] = ((i>>48)&0xff);
      85             :         data[2] = ((i>>40)&0xff);
      86             :         data[3] = ((i>>32)&0xff);
      87             :         data[4] = ((i>>24)&0xff);
      88             :         data[5] = ((i>>16)&0xff);
      89             :         data[6] = ((i>> 8)&0xff);
      90             :         data[7] = ((i>> 0)&0xff);
      91             : }
      92             : 
      93             : inline void writeU32(u8 *data, u32 i)
      94             : {
      95             :         data[0] = ((i>>24)&0xff);
      96             :         data[1] = ((i>>16)&0xff);
      97             :         data[2] = ((i>> 8)&0xff);
      98             :         data[3] = ((i>> 0)&0xff);
      99             : }
     100             : 
     101             : inline void writeU16(u8 *data, u16 i)
     102             : {
     103             :         data[0] = ((i>> 8)&0xff);
     104             :         data[1] = ((i>> 0)&0xff);
     105             : }
     106             : 
     107             : inline u64 readU64(const u8 *data)
     108             : {
     109             :         return ((u64)data[0]<<56) | ((u64)data[1]<<48)
     110             :                 | ((u64)data[2]<<40) | ((u64)data[3]<<32)
     111             :                 | ((u64)data[4]<<24) | ((u64)data[5]<<16)
     112             :                 | ((u64)data[6]<<8) | ((u64)data[7]<<0);
     113             : }
     114             : 
     115             : inline u32 readU32(const u8 *data)
     116             : {
     117             :         return (data[0]<<24) | (data[1]<<16) | (data[2]<<8) | (data[3]<<0);
     118             : }
     119             : 
     120             : inline u16 readU16(const u8 *data)
     121             : {
     122             :         return (data[0]<<8) | (data[1]<<0);
     123             : }
     124             : 
     125             : #endif
     126             : 
     127       18153 : inline void writeU8(u8 *data, u8 i)
     128             : {
     129       18153 :         data[0] = ((i>> 0)&0xff);
     130       18153 : }
     131             : 
     132     6862896 : inline u8 readU8(const u8 *data)
     133             : {
     134     6862896 :         return (data[0]<<0);
     135             : }
     136             : 
     137           0 : inline void writeS32(u8 *data, s32 i){
     138           0 :         writeU32(data, (u32)i);
     139           0 : }
     140      255107 : inline s32 readS32(const u8 *data){
     141      255107 :         return (s32)readU32(data);
     142             : }
     143             : 
     144           0 : inline void writeS16(u8 *data, s16 i){
     145           0 :         writeU16(data, (u16)i);
     146           0 : }
     147        2998 : inline s16 readS16(const u8 *data){
     148        2998 :         return (s16)readU16(data);
     149             : }
     150             : 
     151             : inline void writeS8(u8 *data, s8 i){
     152             :         writeU8(data, (u8)i);
     153             : }
     154             : inline s8 readS8(const u8 *data){
     155             :         return (s8)readU8(data);
     156             : }
     157             : 
     158           0 : inline void writeF1000(u8 *data, f32 i){
     159           0 :         writeS32(data, i*FIXEDPOINT_FACTOR);
     160           0 : }
     161      255093 : inline f32 readF1000(const u8 *data){
     162      255093 :         return (f32)readS32(data)*FIXEDPOINT_INVFACTOR;
     163             : }
     164             : 
     165             : inline void writeV3S32(u8 *data, v3s32 p)
     166             : {
     167             :         writeS32(&data[0], p.X);
     168             :         writeS32(&data[4], p.Y);
     169             :         writeS32(&data[8], p.Z);
     170             : }
     171           0 : inline v3s32 readV3S32(const u8 *data)
     172             : {
     173           0 :         v3s32 p;
     174           0 :         p.X = readS32(&data[0]);
     175           0 :         p.Y = readS32(&data[4]);
     176           0 :         p.Z = readS32(&data[8]);
     177           0 :         return p;
     178             : }
     179             : 
     180           0 : inline void writeV3F1000(u8 *data, v3f p)
     181             : {
     182           0 :         writeF1000(&data[0], p.X);
     183           0 :         writeF1000(&data[4], p.Y);
     184           0 :         writeF1000(&data[8], p.Z);
     185           0 : }
     186       51774 : inline v3f readV3F1000(const u8 *data)
     187             : {
     188       51774 :         v3f p;
     189       51774 :         p.X = (float)readF1000(&data[0]);
     190       51774 :         p.Y = (float)readF1000(&data[4]);
     191       51774 :         p.Z = (float)readF1000(&data[8]);
     192       51774 :         return p;
     193             : }
     194             : 
     195           0 : inline void writeV2F1000(u8 *data, v2f p)
     196             : {
     197           0 :         writeF1000(&data[0], p.X);
     198           0 :         writeF1000(&data[4], p.Y);
     199           0 : }
     200         322 : inline v2f readV2F1000(const u8 *data)
     201             : {
     202         322 :         v2f p;
     203         322 :         p.X = (float)readF1000(&data[0]);
     204         322 :         p.Y = (float)readF1000(&data[4]);
     205         322 :         return p;
     206             : }
     207             : 
     208           0 : inline void writeV2S16(u8 *data, v2s16 p)
     209             : {
     210           0 :         writeS16(&data[0], p.X);
     211           0 :         writeS16(&data[2], p.Y);
     212           0 : }
     213             : 
     214         236 : inline v2s16 readV2S16(const u8 *data)
     215             : {
     216         236 :         v2s16 p;
     217         236 :         p.X = readS16(&data[0]);
     218         236 :         p.Y = readS16(&data[2]);
     219         236 :         return p;
     220             : }
     221             : 
     222             : inline void writeV2S32(u8 *data, v2s32 p)
     223             : {
     224             :         writeS32(&data[0], p.X);
     225             :         writeS32(&data[4], p.Y);
     226             : }
     227             : 
     228           6 : inline v2s32 readV2S32(const u8 *data)
     229             : {
     230           6 :         v2s32 p;
     231           6 :         p.X = readS32(&data[0]);
     232           6 :         p.Y = readS32(&data[4]);
     233           6 :         return p;
     234             : }
     235             : 
     236           0 : inline void writeV3S16(u8 *data, v3s16 p)
     237             : {
     238           0 :         writeS16(&data[0], p.X);
     239           0 :         writeS16(&data[2], p.Y);
     240           0 :         writeS16(&data[4], p.Z);
     241           0 : }
     242             : 
     243         842 : inline v3s16 readV3S16(const u8 *data)
     244             : {
     245         842 :         v3s16 p;
     246         842 :         p.X = readS16(&data[0]);
     247         842 :         p.Y = readS16(&data[2]);
     248         842 :         p.Z = readS16(&data[4]);
     249         842 :         return p;
     250             : }
     251             : 
     252           0 : inline void writeARGB8(u8 *data, video::SColor p)
     253             : {
     254           0 :         writeU32(data, p.color);
     255           0 : }
     256             : 
     257         118 : inline video::SColor readARGB8(const u8 *data)
     258             : {
     259         118 :         video::SColor p(readU32(data));
     260         118 :         return p;
     261             : }
     262             : 
     263             : /*
     264             :         The above stuff directly interfaced to iostream
     265             : */
     266             : 
     267           0 : inline void writeU8(std::ostream &os, u8 p)
     268             : {
     269             :         char buf[1];
     270           0 :         writeU8((u8*)buf, p);
     271           0 :         os.write(buf, 1);
     272           0 : }
     273      404806 : inline u8 readU8(std::istream &is)
     274             : {
     275      404806 :         char buf[1] = {0};
     276      404806 :         is.read(buf, 1);
     277      404806 :         return readU8((u8*)buf);
     278             : }
     279             : 
     280           0 : inline void writeU16(std::ostream &os, u16 p)
     281             : {
     282             :         char buf[2];
     283           0 :         writeU16((u8*)buf, p);
     284           0 :         os.write(buf, 2);
     285           0 : }
     286      377391 : inline u16 readU16(std::istream &is)
     287             : {
     288      377391 :         char buf[2] = {0};
     289      377391 :         is.read(buf, 2);
     290      377391 :         return readU16((u8*)buf);
     291             : }
     292             : 
     293          23 : inline void writeU32(std::ostream &os, u32 p)
     294             : {
     295             :         char buf[4];
     296          23 :         writeU32((u8*)buf, p);
     297          23 :         os.write(buf, 4);
     298          23 : }
     299      192135 : inline u32 readU32(std::istream &is)
     300             : {
     301      192135 :         char buf[4] = {0};
     302      192135 :         is.read(buf, 4);
     303      192135 :         return readU32((u8*)buf);
     304             : }
     305             : 
     306           0 : inline void writeS32(std::ostream &os, s32 p)
     307             : {
     308           0 :         writeU32(os, (u32) p);
     309           0 : }
     310             : inline s32 readS32(std::istream &is)
     311             : {
     312             :         return (s32)readU32(is);
     313             : }
     314             : 
     315           0 : inline void writeS16(std::ostream &os, s16 p)
     316             : {
     317           0 :         writeU16(os, (u16) p);
     318           0 : }
     319       40453 : inline s16 readS16(std::istream &is)
     320             : {
     321       40453 :         return (s16)readU16(is);
     322             : }
     323             : 
     324             : inline void writeS8(std::ostream &os, s8 p)
     325             : {
     326             :         writeU8(os, (u8) p);
     327             : }
     328             : inline s8 readS8(std::istream &is)
     329             : {
     330             :         return (s8)readU8(is);
     331             : }
     332             : 
     333           0 : inline void writeF1000(std::ostream &os, f32 p)
     334             : {
     335             :         char buf[4];
     336           0 :         writeF1000((u8*)buf, p);
     337           0 :         os.write(buf, 4);
     338           0 : }
     339       99054 : inline f32 readF1000(std::istream &is)
     340             : {
     341       99054 :         char buf[4] = {0};
     342       99054 :         is.read(buf, 4);
     343       99054 :         return readF1000((u8*)buf);
     344             : }
     345             : 
     346           0 : inline void writeV3F1000(std::ostream &os, v3f p)
     347             : {
     348             :         char buf[12];
     349           0 :         writeV3F1000((u8*)buf, p);
     350           0 :         os.write(buf, 12);
     351           0 : }
     352       51715 : inline v3f readV3F1000(std::istream &is)
     353             : {
     354             :         char buf[12];
     355       51715 :         is.read(buf, 12);
     356       51715 :         return readV3F1000((u8*)buf);
     357             : }
     358             : 
     359           0 : inline void writeV2F1000(std::ostream &os, v2f p)
     360             : {
     361             :         char buf[8];
     362           0 :         writeV2F1000((u8*)buf, p);
     363           0 :         os.write(buf, 8);
     364           0 : }
     365         314 : inline v2f readV2F1000(std::istream &is)
     366             : {
     367         314 :         char buf[8] = {0};
     368         314 :         is.read(buf, 8);
     369         314 :         return readV2F1000((u8*)buf);
     370             : }
     371             : 
     372           0 : inline void writeV2S16(std::ostream &os, v2s16 p)
     373             : {
     374             :         char buf[4];
     375           0 :         writeV2S16((u8*)buf, p);
     376           0 :         os.write(buf, 4);
     377           0 : }
     378         236 : inline v2s16 readV2S16(std::istream &is)
     379             : {
     380         236 :         char buf[4] = {0};
     381         236 :         is.read(buf, 4);
     382         236 :         return readV2S16((u8*)buf);
     383             : }
     384             : 
     385             : inline void writeV2S32(std::ostream &os, v2s32 p)
     386             : {
     387             :         char buf[8];
     388             :         writeV2S32((u8*)buf, p);
     389             :         os.write(buf, 8);
     390             : }
     391             : inline v2s32 readV2S32(std::istream &is)
     392             : {
     393             :         char buf[8] = {0};
     394             :         is.read(buf, 8);
     395             :         return readV2S32((u8*)buf);
     396             : }
     397             : 
     398           0 : inline void writeV3S16(std::ostream &os, v3s16 p)
     399             : {
     400             :         char buf[6];
     401           0 :         writeV3S16((u8*)buf, p);
     402           0 :         os.write(buf, 6);
     403           0 : }
     404           0 : inline v3s16 readV3S16(std::istream &is)
     405             : {
     406           0 :         char buf[6] = {0};
     407           0 :         is.read(buf, 6);
     408           0 :         return readV3S16((u8*)buf);
     409             : }
     410             : 
     411           0 : inline void writeARGB8(std::ostream &os, video::SColor p)
     412             : {
     413             :         char buf[4];
     414           0 :         writeARGB8((u8*)buf, p);
     415           0 :         os.write(buf, 4);
     416           0 : }
     417             : 
     418         118 : inline video::SColor readARGB8(std::istream &is)
     419             : {
     420         118 :         char buf[4] = {0};
     421         118 :         is.read(buf, 4);
     422         118 :         return readARGB8((u8*)buf);
     423             : }
     424             : 
     425             : /*
     426             :         More serialization stuff
     427             : */
     428             : 
     429             : // Creates a string with the length as the first two bytes
     430             : std::string serializeString(const std::string &plain);
     431             : 
     432             : // Creates a string with the length as the first two bytes from wide string
     433             : std::string serializeWideString(const std::wstring &plain);
     434             : 
     435             : // Reads a string with the length as the first two bytes
     436             : std::string deSerializeString(std::istream &is);
     437             : 
     438             : // Reads a wide string with the length as the first two bytes
     439             : std::wstring deSerializeWideString(std::istream &is);
     440             : 
     441             : // Creates a string with the length as the first four bytes
     442             : std::string serializeLongString(const std::string &plain);
     443             : 
     444             : // Reads a string with the length as the first four bytes
     445             : std::string deSerializeLongString(std::istream &is);
     446             : 
     447             : // Creates a string encoded in JSON format (almost equivalent to a C string literal)
     448             : std::string serializeJsonString(const std::string &plain);
     449             : 
     450             : // Reads a string encoded in JSON format
     451             : std::string deSerializeJsonString(std::istream &is);
     452             : 
     453             : // Creates a string containing comma delimited values of a struct whose layout is
     454             : // described by the parameter format
     455             : bool serializeStructToString(std::string *out,
     456             :         std::string format, void *value);
     457             : 
     458             : // Reads a comma delimited string of values into a struct whose layout is
     459             : // decribed by the parameter format
     460             : bool deSerializeStringToStruct(std::string valstr,
     461             :         std::string format, void *out, size_t olen);
     462             : 
     463             : #endif
     464             : 

Generated by: LCOV version 1.11