/************************************************************************************************ * Copyright/Copyleft: * * For this source the LGPL Lesser General Public License, * published by the Free Software Foundation is valid. * It means: * 1) You can use this source without any restriction for any desired purpose. * 2) You can redistribute copies of this source to everybody. * 3) Every user of this source, also the user of redistribute copies * with or without payment, must accept this license for further using. * 4) But the LPGL ist not appropriate for a whole software product, * if this source is only a part of them. It means, the user * must publish this part of source, * but don't need to publish the whole source of the own product. * 5) You can study and modify (improve) this source * for own using or for redistribution, but you have to license the * modified sources likewise under this LGPL Lesser General Public License. * You mustn't delete this Copyright/Copyleft inscription in this source file. * * This source may be used also with another licence, if the author * and all other here named co-authors have agreed to this contract. * Especially a company can use a copy of this sources in its products without publishing. * The user should have a underwritten contract therefore. * * @author Hartmut Schorrig, Germany, Pinzberg, www.vishia.org * **copyright*************************************************************************************** * * @version 0.92 * @content Implementation of access for network payload data for the Intel-type-Processor * list of changes: * 2011-11-08; Hartmut use notification int32_t instead int32 etc. It is the C99-standard. * 2009-11-24: JcHartmut created as new idea. * ****************************************************************************/ #include <os_endian.h> int64_t getInt64BigEndian(int64BigEndian* addr) { int32_t loBig,hiBig, lo, hi; int64_t ret; //NOTE: do only 1 access to memory. hiBig = addr->hiBigEndian__; loBig = addr->loBigEndian__; hi = ((hiBig <<24) & 0xff000000) | ((hiBig <<8) & 0x00ff0000) |((hiBig >>8) & 0x0000ff00) |((hiBig >>24) & 0x0000ff); lo = ((loBig <<24) & 0xff000000) | ((loBig <<8) & 0x00ff0000) |((loBig >>8) & 0x0000ff00) |((loBig >>24) & 0x0000ff); ret = ((int64_t)hi)<<32 | lo; return ret; } int32_t getInt32BigEndian(int32BigEndian* addr) { int32_t loBig; int32_t ret; //NOTE: do only 1 access to memory. loBig = addr->loBigEndian__; ret = ((loBig <<24) & 0xff000000) | ((loBig <<8) & 0x00ff0000) |((loBig >>8) & 0x0000ff00) |((loBig >>24) & 0x0000ff); return ret; } int16_t getInt16BigEndian(int16BigEndian* addr) { int16_t loBig; int16_t ret; //NOTE: do only 1 access to memory. loBig = addr->loBigEndian__; ret = (int16_t)(((loBig <<8) & 0xff00) |((loBig >>8) & 0x00ff)); return ret; } float getFloatBigEndian(floatBigEndian* addr) { int32_t loBig; int32_t lo; float ret; //NOTE: do only 1 access to memory. loBig = addr->floatBigEndian__; lo = ((loBig <<24) & 0xff000000) | ((loBig <<8) & 0x00ff0000) |((loBig >>8) & 0x0000ff00) |((loBig >>24) & 0x0000ff); ret = *(float*)&lo; return ret; } double getDoubleBigEndian(doubleBigEndian* addr) { int32_t loBig,hiBig, lo, hi; int64_t value; double ret; //NOTE: do only 1 access to memory. hiBig = addr->hiBigEndian__; loBig = addr->loBigEndian__; hi = ((hiBig <<24) & 0xff000000) | ((hiBig <<8) & 0x00ff0000) |((hiBig >>8) & 0x0000ff00) |((hiBig >>24) & 0x0000ff); lo = ((loBig <<24) & 0xff000000) | ((loBig <<8) & 0x00ff0000) |((loBig >>8) & 0x0000ff00) |((loBig >>24) & 0x0000ff); value = ((int64_t)hi)<<32 | lo; ret = *(double*)&value; return ret; } void* getPtrBigEndian(ptrBigEndian* addr) { int32_t loBig, hiBig; struct ptr_t{int32_t lo; int32_t hi; }imgPtr = {0, 0}; int sizePtr = sizeof(void*); //may be depending on several compiler options. int ix; void* ret; //NOTE: do only 1 access to memory. hiBig = ((int32_t*)addr)[0]; //reads 4 byte. if(sizePtr >4){ loBig = ((int32_t*)addr)[1]; //reads next 4 byte, part of them are for the pointer. } else { loBig = 0; } for(ix=0; ix<4 && ix<sizePtr; ix++){ imgPtr.lo <<=8; imgPtr.lo |= hiBig & 0xff; hiBig >>=8; } while(ix < sizePtr){ //continue with next bytes. imgPtr.hi <<=8; imgPtr.hi |= loBig & 0xff; loBig >>=8; } ret = *(void**)&imgPtr; //interprete it as pointer-image in stack. return ret; } int64_t setInt64BigEndian(int64BigEndian* addr, int64_t value) { int32_t loBig,hiBig, lo, hi; hi = (int32_t)(value >> 32); lo = (int32_t)value; hiBig = ((hi <<24) & 0xff000000) | ((hi <<8) & 0x00ff0000) |((hi >>8) & 0x0000ff00) |((hi >>24) & 0x0000ff); loBig = ((lo <<24) & 0xff000000) | ((lo <<8) & 0x00ff0000) |((lo >>8) & 0x0000ff00) |((lo >>24) & 0x0000ff); //NOTE: do only 1 access to memory. addr->hiBigEndian__ = hiBig; addr->loBigEndian__ = loBig; return value; } int32_t setInt32BigEndian(int32BigEndian* addr, int32_t value) { int32_t loBig; loBig = ((value <<24) & 0xff000000) | ((value <<8) & 0x00ff0000) |((value >>8) & 0x0000ff00) |((value >>24) & 0x0000ff); //NOTE: do only 1 access to memory. addr->loBigEndian__ = loBig; return value; } u_int32_t setUint32BigEndian(uint32BigEndian* addr, u_int32_t value) { int32_t loBig; loBig = ((value <<24) & 0xff000000) | ((value <<8) & 0x00ff0000) |((value >>8) & 0x0000ff00) |((value >>24) & 0x0000ff); //NOTE: do only 1 access to memory. addr->loBigEndian__ = loBig; return value; } int16_t setInt16BigEndian(int16BigEndian* addr, int16_t value) { int16_t loBig; loBig = (int16_t)(((value <<8) & 0xff00) |((value >>8) & 0x00ff)); //NOTE: do only 1 access to memory. addr->loBigEndian__ = loBig; return value; } float setFloatBigEndian(floatBigEndian* addr, float value) { int32_t img, imgBig; img = *(int32_t*)&value; imgBig = ((img <<24) & 0xff000000) | ((img <<8) & 0x00ff0000) |((img >>8) & 0x0000ff00) |((img >>24) & 0x0000ff); //NOTE: do only 1 access to memory. addr->floatBigEndian__ = imgBig; return value; } double setDoubleBigEndian(doubleBigEndian* addr, double value) { int32_t loBig,hiBig, lo, hi; int64_t img; img = *(int64_t*)&value; hi = (int32_t)(img >> 32); lo = (int32_t)img; hiBig = ((hi <<24) & 0xff000000) | ((hi <<8) & 0x00ff0000) |((hi >>8) & 0x0000ff00) |((hi >>24) & 0x0000ff); loBig = ((lo <<24) & 0xff000000) | ((lo <<8) & 0x00ff0000) |((lo >>8) & 0x0000ff00) |((lo >>24) & 0x0000ff); //NOTE: do only 1 access to memory. addr->hiBigEndian__ = hiBig; addr->loBigEndian__ = loBig; return value; } void* setPtrBigEndian(ptrBigEndian* addr, void const* value) { int sizePtr = sizeof(void*); //may be depending on several compiler options. switch(sizePtr){ case 2: //it may be a near ptr { int16_t ptrImg = *(int16_t*)&value; setInt16BigEndian((int16BigEndian*)addr, ptrImg); } break; case 4: //it may be a normal far ptr { int32_t ptrImg = *(int32_t*)&value; setInt32BigEndian((int32BigEndian*)addr, ptrImg); } break; case 6: //it may be a far ptr { int32_t ptrImgLo = *(int32_t*)&value; int16_t ptrImgHi = ((int16_t*)&value)[2]; setInt16BigEndian((int16BigEndian*)addr, ptrImgHi); setInt32BigEndian((int32BigEndian*)(((int16BigEndian*)addr)+1), ptrImgLo); //set to next 16 bit position, but set 32 bit. } break; case 8: //it may be a far ptr { int32_t ptrImgLo = *(int32_t*)&value; int32_t ptrImgHi = ((int32_t*)&value)[1]; setInt32BigEndian((int32BigEndian*)addr, ptrImgHi); setInt32BigEndian(((int32BigEndian*)addr)+1, ptrImgLo); //set to next 32 bit position, set 32 bit. } break; } return (void*) value; }