/************************************************************************** * Copyright (C) 2015 Eff'Innov Technologies * * 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. * * Developped by Eff'Innov Technologies : contact@effinnov.com * **************************************************************************/ #include "TML/inc/framework_Parcel.h" #include "TML/inc/framework_Allocator.h" #include #include #define INC_COUNTER(p,x) \ { \ uint8_t seeSomewhereElseCompilator = 0; \ do \ { \ p->m_curPosition += x; \ if (p->m_curLength < p->m_curPosition) \ { \ p->m_curLength += x; \ } \ }while (seeSomewhereElseCompilator); \ } typedef struct _tParcel { uint8_t *m_data; uint32_t m_dataLength; uint32_t m_curLength; uint32_t m_curPosition; }tParcel; static void growData(tParcel *parcel,uint32_t len) { uint32_t newSize; uint8_t *newBuffer; if ((parcel->m_curPosition+len) < parcel->m_dataLength) return; newSize = parcel->m_dataLength + len; newBuffer = (uint8_t*)framework_AllocMem(newSize); memcpy(newBuffer,parcel->m_data, parcel->m_dataLength); framework_FreeMem(parcel->m_data); parcel->m_data = newBuffer; parcel->m_dataLength = newSize; } void framework_ParcelCreate(void** parcel) { tParcel *p = NULL; if (parcel == NULL) { return; } p = (tParcel*)framework_AllocMem(sizeof(tParcel)); p->m_data = (uint8_t*)framework_AllocMem(32); p->m_dataLength = 32; p->m_curPosition = 0; p->m_curLength = 0; memset(p->m_data, 0, 32); *parcel = p; } void framework_ParcelDelete(void* parcel) { tParcel *p = (tParcel*)parcel; if (parcel) { framework_FreeMem(p->m_data); framework_FreeMem(p); } } void framework_ParcelClear(void* parcel) { tParcel *p = (tParcel*)parcel; p->m_curPosition = 0; p->m_curLength = 0; memset(p->m_data, 0, p->m_dataLength); } const uint8_t* framework_ParcelDataAtCurrentPosition(void* parcel) { tParcel *p = (tParcel*)parcel; return (p->m_data+p->m_curPosition); } void framework_ParcelDeserialize(void* dstParcel, void* srcParcel) { tParcel *pDest = (tParcel*)dstParcel; tParcel *pSrc = (tParcel*)srcParcel; uint8_t *data = NULL; uint32_t size = framework_ParcelReadInt32(pSrc); if (size > 0) { data = (uint8_t*)framework_AllocMem(size); framework_ParcelReadRaw(pSrc,data,size); framework_ParcelSetData(pDest,data,size); framework_FreeMem(data); framework_ParcelRewind(pDest); }else { framework_ParcelClear(pDest); } } void framework_ParcelForward(void* parcel, uint32_t nbBytes) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition+nbBytes <= p->m_curLength) { p->m_curPosition+=nbBytes; } } const uint8_t* framework_ParcelGetData(void* parcel) { tParcel *p = (tParcel*)parcel; return p->m_data; } uint32_t framework_ParcelGetRemainingDataSize(void* parcel) { tParcel *p = (tParcel*)parcel; return p->m_curLength-p->m_curPosition; } uint32_t framework_ParcelGetSize(void* parcel) { tParcel *p = (tParcel*)parcel; return p->m_curLength; } uint8_t framework_ParcelReadByte(void* parcel) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition < p->m_curLength) { uint8_t result = p->m_data[p->m_curPosition]; p->m_curPosition += sizeof(uint8_t); return result; } return 0; } double framework_ParcelReadDouble(void* parcel) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition < p->m_curLength) { void* result = p->m_data+p->m_curPosition; p->m_curPosition += sizeof(double); return *((double*)result); } return 0; } float framework_ParcelReadFloat(void* parcel) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition < p->m_curLength) { void* result = p->m_data+p->m_curPosition; p->m_curPosition += sizeof(float); return *((float*)result); } return 0; } uint32_t framework_ParcelReadInt32(void* parcel) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition < p->m_curLength) { void* result = p->m_data+p->m_curPosition; p->m_curPosition += sizeof(uint32_t); return *((uint32_t*)result); } return 0; } uint64_t framework_ParcelReadInt64(void* parcel) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition < p->m_curLength) { void* result = p->m_data+p->m_curPosition; p->m_curPosition += sizeof(uint64_t); return *((uint64_t*)result); } return 0; } void framework_ParcelReadRaw(void* parcel, void* outBuffer, uint32_t len) { tParcel *p = (tParcel*)parcel; if (!outBuffer) { return; } if (p->m_curPosition < p->m_curLength) { uint8_t *start =p->m_data+p->m_curPosition; memcpy(outBuffer,start,len); p->m_curPosition += len; } } uint16_t framework_ParcelReadShort(void* parcel) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition < p->m_curLength) { void* result = p->m_data+p->m_curPosition; p->m_curPosition += sizeof(uint16_t); return *((uint16_t*)result); } return 0; } const char* framework_ParcelReadString(void* parcel) { tParcel *p = (tParcel*)parcel; if (p->m_curPosition < p->m_curLength) { char* result =(char*)(p->m_data+p->m_curPosition); p->m_curPosition += strlen(result)+1; return result; } return NULL; } void framework_ParcelRewind(void* parcel) { tParcel *p = (tParcel*)parcel; p->m_curPosition = 0; } void framework_ParcelSerialize(void* dstParcel, void* srcParcel) { tParcel *pDest = (tParcel*)dstParcel; tParcel *pSrc = (tParcel*)srcParcel; framework_ParcelWriteInt32(pDest,pSrc->m_curLength); if (pSrc->m_curLength>0) { framework_ParcelWriteRaw(dstParcel,pSrc->m_data,pSrc->m_curLength); } } void framework_ParcelSetData(void* parcel, const uint8_t* data, uint32_t size) { tParcel *p = (tParcel*)parcel; framework_FreeMem(p->m_data); if (size > 0) { p->m_data = (uint8_t*)framework_AllocMem(size); memcpy(p->m_data,data,size); p->m_dataLength = size; }else { p->m_data = (uint8_t*)framework_AllocMem(32); memset(p->m_data,0,32); p->m_dataLength = 32; } p->m_curLength = size; p->m_curPosition = 0; } void framework_ParcelWriteByte(void* parcel, uint8_t i) { tParcel *p = (tParcel*)parcel; growData(p,sizeof(uint8_t)); p->m_data[p->m_curPosition] = i; INC_COUNTER(p,sizeof(uint8_t)); } void framework_ParcelWriteDouble(void* parcel, double d) { tParcel *p = (tParcel*)parcel; growData(p,sizeof(double)); *((double*)(p->m_data+p->m_curPosition)) = d; INC_COUNTER(p,sizeof(double)); } void framework_ParcelWriteFloat(void* parcel, float f) { tParcel *p = (tParcel*)parcel; growData(p,sizeof(float)); *((float*)(p->m_data+p->m_curPosition)) = f; INC_COUNTER(p,sizeof(float)); } void framework_ParcelWriteInt32(void* parcel, uint32_t i) { tParcel *p = (tParcel*)parcel; growData(p,sizeof(uint32_t)); *((uint32_t*)(p->m_data+p->m_curPosition)) = i; INC_COUNTER(p,sizeof(uint32_t)); } void framework_ParcelWriteInt64(void* parcel, uint64_t i) { tParcel *p = (tParcel*)parcel; growData(p,sizeof(uint64_t)); *((uint64_t*)(p->m_data+p->m_curPosition)) = i; INC_COUNTER(p,sizeof(uint64_t)); } void framework_ParcelWriteRaw(void* parcel, const void* buffer, uint32_t len) { tParcel *p = (tParcel*)parcel; growData(p,len); memcpy((p->m_data+p->m_curPosition),buffer,len); INC_COUNTER(p,len); } void framework_ParcelWriteShort(void* parcel, uint16_t i) { tParcel *p = (tParcel*)parcel; growData(p,sizeof(uint16_t)); *((uint16_t*)(p->m_data+p->m_curPosition)) = i; INC_COUNTER(p,sizeof(uint16_t)); } void framework_ParcelWriteString(void* parcel, const char* s) { tParcel *p = (tParcel*)parcel; growData(p,strlen(s)+1); // Trailling 0 strcpy((char*)(p->m_data+p->m_curPosition),s); INC_COUNTER(p,strlen(s)+1); }