1 /* 2 * This file is part of Dune Legacy. 3 * 4 * Dune Legacy is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * Dune Legacy is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with Dune Legacy. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef OMEMORYSTREAM_H 19 #define OMEMORYSTREAM_H 20 21 #include "OutputStream.h" 22 #include <stdlib.h> 23 #include <string> 24 25 class OMemoryStream : public OutputStream 26 { 27 public: OMemoryStream()28 OMemoryStream() 29 : currentPos(0), bufferSize(0), pBuffer(nullptr) { 30 ; 31 } 32 ~OMemoryStream()33 ~OMemoryStream() { 34 free(pBuffer); 35 } 36 open()37 void open() { 38 free(pBuffer); 39 40 currentPos = 0; 41 bufferSize = 4; 42 pBuffer = (char*) malloc(4); 43 if(pBuffer == nullptr) { 44 THROW(OMemoryStream::error, "OMemoryStream::open(): malloc failed!"); 45 } 46 } 47 getData()48 const char* getData() const { 49 return pBuffer; 50 } 51 getDataLength()52 size_t getDataLength() const { 53 return (bReadOnly == true) ? bufferSize : currentPos; 54 } 55 flush()56 void flush() { 57 ; 58 } 59 writeString(const std::string & str)60 void writeString(const std::string& str) { 61 ensureBufferSize(currentPos + str.length() + sizeof(Uint32)); 62 63 writeUint32(str.length()); 64 65 if(!str.empty()) { 66 memcpy(pBuffer + currentPos, str.c_str(), str.length()); 67 currentPos += str.length(); 68 } 69 } 70 71 writeUint8(Uint8 x)72 void writeUint8(Uint8 x) { 73 ensureBufferSize(currentPos + sizeof(Uint8)); 74 *((Uint8*) (pBuffer + currentPos)) = x; 75 currentPos += sizeof(Uint8); 76 } 77 writeUint16(Uint16 x)78 void writeUint16(Uint16 x) { 79 ensureBufferSize(currentPos + sizeof(Uint16)); 80 x = SDL_SwapLE16(x); 81 *((Uint16*) (pBuffer + currentPos)) = x; 82 currentPos += sizeof(Uint16); 83 } 84 writeUint32(Uint32 x)85 void writeUint32(Uint32 x) { 86 ensureBufferSize(currentPos + sizeof(Uint32)); 87 x = SDL_SwapLE32(x); 88 *((Uint32*) (pBuffer + currentPos)) = x; 89 currentPos += sizeof(Uint32); 90 } 91 writeUint64(Uint64 x)92 void writeUint64(Uint64 x) { 93 ensureBufferSize(currentPos + sizeof(Uint64)); 94 x = SDL_SwapLE64(x); 95 *((Uint64*) (pBuffer + currentPos)) = x; 96 currentPos += sizeof(Uint64); 97 } 98 writeBool(bool x)99 void writeBool(bool x) { 100 writeUint8(x == true ? 1 : 0); 101 } 102 writeFloat(float x)103 void writeFloat(float x) { 104 if(sizeof(float) != sizeof(Uint32)) { 105 THROW(OMemoryStream::error, "OMemoryStream::writeFloat(): sizeof(float) != sizeof(Uint32). Cannot save floats on such systems."); 106 } 107 Uint32 tmp; 108 memcpy(&tmp,&x,sizeof(Uint32)); // workaround for a strange optimization in gcc 4.1 109 writeUint32(tmp); 110 } 111 ensureBufferSize(size_t minBufferSize)112 void ensureBufferSize(size_t minBufferSize) { 113 if(minBufferSize < bufferSize) { 114 return; 115 } 116 117 size_t newBufferSize = ((bufferSize * 3) / 2); 118 if(newBufferSize < minBufferSize) { 119 newBufferSize = minBufferSize; 120 } 121 122 char* pNewBuffer = (char*) realloc(pBuffer, newBufferSize); 123 if(pNewBuffer == nullptr) { 124 THROW(OMemoryStream::error, "OMemoryStream::ensureBufferSize(): realloc failed!"); 125 } else { 126 pBuffer = pNewBuffer; 127 bufferSize = newBufferSize; 128 } 129 } 130 131 private: 132 size_t currentPos; 133 size_t bufferSize; 134 char* pBuffer; 135 }; 136 137 #endif // OMEMORYSTREAM_H 138