/* * PVVMUD a 3D MUD * Copyright (C) 1998-1999 Programvareverkstedet (pvv@pvv.org) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "pvvmud.H" #include #include #include #include "message.H" #define WORD_MS_BYTE(w) (BYTE)( w >> 8 ) #define WORD_LS_BYTE(w) (BYTE)( w & 0xFF ) #define DWORD_MS_WORD(w) (WORD)( w >> 16 ) #define DWORD_LS_WORD(w) (WORD)( w & 0xFFFF ) #define WORD_FROM_BYTE(ms,ls) (WORD)( (WORD)ms << 8 | (WORD)ls) #define DWORD_FROM_WORD(ms,ls) (DWORD)( (DWORD)ms << 16 | (DWORD)ls) /****************************************************************************** * * CMessage * ******************************************************************************/ CMessage::CMessage(BYTE id, long length){ this->length = length+1; message = (BYTE*)malloc(this->length); msglength = this->length; writeByte(0,id); writeIndex = 0; readIndex = 0; } CMessage::~CMessage(){ if (message != NULL) free(message); } void CMessage::reallocMessage(long size){ message = (BYTE*)realloc(message,length+size); msglength = length+size; } BYTE CMessage::getId(){ return readByte(0); } long CMessage::getLength(){ return length; } CMessage * CMessage::createMsg(){ return (CMessage*)NULL; } int CMessage::reciveHead(CStream * stream){ return FALSE; } int CMessage::send(CStream * stream){ if (readIndex >= length){ return MESSAGE_OK; } long num = stream->writeBuf(&message[readIndex],length-readIndex); if (num == -1) return MESSAGE_BLOCKING; readIndex += num; if (readIndex == length) return MESSAGE_OK; return MESSAGE_BLOCKING; } int CMessage::recive(CStream * stream){ if (writeIndex >= length){ return MESSAGE_OK; } long num = stream->readBuf(&message[writeIndex],length-writeIndex); if (num == -1) return MESSAGE_BLOCKING; writeIndex += num; if (writeIndex == length) return MESSAGE_OK; return MESSAGE_BLOCKING; } int CMessage::reciveMessage(CStream * stream,long index,long size){ long num = stream->readBuf(&message[index],size); if (num == -1) return MESSAGE_BLOCKING; writeIndex += num; if (num == size) return MESSAGE_OK; return MESSAGE_BLOCKING; } int CMessage::sendMessage(CStream * stream,long index,long size){ long num = stream->writeBuf(&message[index],size); if (num == -1) return MESSAGE_BLOCKING; readIndex += num; if (num == size) return MESSAGE_OK; return MESSAGE_BLOCKING; } long CMessage::getWriteIndex(){ return writeIndex; } long CMessage::getReadIndex(){ return readIndex; } void CMessage::writeByte(long index,BYTE byte){ if (index < 0) index = currpos; if ((index > msglength) || (index < 0) || (message == NULL)) throw new CException("Message write index out of range exception"); message[index] = byte; currpos = index + 1; } void CMessage::writeWord(long index,WORD word){ writeByte(index,WORD_MS_BYTE(word)); writeByte(index+1,WORD_LS_BYTE(word)); } void CMessage::writeDWord(long index,DWORD dword){ writeWord(index,DWORD_MS_WORD(dword)); writeWord(index+2,DWORD_LS_WORD(dword)); } void CMessage::writeDouble(long index,double value){ long longval = (long)(value*1000.0); writeDWord(index,(DWORD)longval); } void CMessage::writeBuf(long index,BYTE * buf,long size){ long ii; for (ii = 0; ii < size; ii++){ writeByte(index+ii,buf[ii]); } } void CMessage::writeString(long index,char * str){ writeBuf(index,(BYTE*)str,strlen(str)+1); } void CMessage::writePosition(long index,const CPosition& position){ for (long ii = 0; ii < 3; ii++){ writeDouble(index+ii*4,position.getValue(ii)); } } void CMessage::writeDirection(long index,const CDirection& direction){ for (long ii = 0; ii < 3; ii++){ writeDouble(index+ii*4,direction.getValue(ii)); } } BYTE CMessage::readByte(long index){ if (index < 0) index = currpos; if ((index > msglength) || (index < 0) || (message == NULL)) { char msg[1024]; sprintf(msg,"Message read index %li out of range %li exception" ,index,msglength); throw new CException(msg); } currpos = index + 1; return message[index]; } WORD CMessage::readWord(long index){ return WORD_FROM_BYTE(readByte(index),readByte(index+1)); } DWORD CMessage::readDWord(long index){ return DWORD_FROM_WORD(readWord(index),readWord(index+2)); } double CMessage::readDouble(long index){ long longval; longval = (long)DWORD_FROM_WORD(readWord(index),readWord(index+2)); return (double)longval / 1000.0; } void CMessage::readBuf(long index,BYTE * buf,long size){ long ii; if (buf == NULL) throw new CException("Message buffer null exception"); for (ii = 0; ii < size; ii++){ buf[ii] = readByte(index+ii); } } char * CMessage::readString(long index){ if (index < 0) index = currpos; if ((index > msglength) || (index < 0) || (message == NULL)) throw new CException("Message readString index out of range exception"); long ii,size=0; char * str; // Find string size while (((index+size) < msglength) && (readByte(index+size++) != '\0')); // Malloc and copy string str = (char*)malloc(size); if (str == NULL) throw new CException("Out of memory exception"); for (ii = 0; ii < size; ii++) str[ii] = readByte(index+ii); return str; } CPosition CMessage::readPosition(long index){ CPosition position; for (long ii = 0; ii < 3; ii++){ position.setValue(ii,readDouble(index+ii*4)); } return position; } CDirection CMessage::readDirection(long index){ CDirection direction; for (long ii = 0; ii < 3; ii++){ direction.setValue(ii,readDouble(index+ii*4)); } return direction; }