TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
G3D::BinaryOutput Class Reference

#include <BinaryOutput.h>

Public Member Functions

 BinaryOutput ()
 
 BinaryOutput (const std::string &filename, G3DEndian fileEndian)
 
 ~BinaryOutput ()
 
void compress (int level=9)
 
bool ok () const
 
const uint8getCArray () const
 
void setEndian (G3DEndian fileEndian)
 
G3DEndian endian () const
 
std::string getFilename () const
 
void commit (bool flush=true)
 
void commit (uint8 *)
 
void reset ()
 
int64 length () const
 
int64 size () const
 
void setLength (int64 n)
 
int64 position () const
 
void setPosition (int64 p)
 
void writeBytes (const void *b, size_t count)
 
void writeInt8 (int8 i)
 
void writeBool8 (bool b)
 
void writeUInt8 (uint8 i)
 
void writeUNorm8 (unorm8 i)
 
void writeUInt16 (uint16 u)
 
void writeInt16 (int16 i)
 
void writeUInt32 (uint32 u)
 
void writeInt32 (int32 i)
 
void writeUInt64 (uint64 u)
 
void writeInt64 (int64 i)
 
void writeFloat32 (float32 f)
 
void writeFloat64 (float64 f)
 
void writeString (const std::string &s)
 
void writeString (const std::string &s, int len)
 
void writeString (const char *s)
 
void writeStringEven (const std::string &s)
 
void writeStringEven (const char *s)
 
void writeString32 (const char *s)
 
void writeString32 (const std::string &s)
 
void writeVector4 (const Vector4 &v)
 
void writeVector3 (const Vector3 &v)
 
void writeVector2 (const Vector2 &v)
 
void writeColor4 (const Color4 &v)
 
void writeColor3 (const Color3 &v)
 
void skip (int n)
 
void beginBits ()
 
void writeBits (uint32 bitString, int numBits)
 
void endBits ()
 

Private Member Functions

void reserveBytesWhenOutOfMemory (size_t bytes)
 
void reallocBuffer (size_t bytes, size_t oldBufferLen)
 
void reserveBytes (size_t bytes)
 
 BinaryOutput (const BinaryOutput &)
 
BinaryOutputoperator= (const BinaryOutput &)
 
bool operator== (const BinaryOutput &)
 

Private Attributes

std::string m_filename
 
bool m_committed
 
int m_beginEndBits
 
int8 m_bitString
 
int m_bitPos
 
bool m_swapBytes
 
G3DEndian m_fileEndian
 
uint8m_buffer
 
size_t m_bufferLen
 
size_t m_maxBufferLen
 
int64 m_pos
 
bool m_init
 
int64 m_alreadyWritten
 
bool m_ok
 

Detailed Description

Sequential or random access byte-order independent binary file access.

The compress() call can be used to compress with zlib.

Any method call can trigger an out of memory error (thrown as char*) when writing to "<memory>" instead of a file.

Compressed writing and seeking backwards is not supported for huge files (i.e., BinaryOutput may have to dump the contents to disk if they exceed available RAM).

Constructor & Destructor Documentation

G3D::BinaryOutput::BinaryOutput ( const BinaryOutput )
private
G3D::BinaryOutput::BinaryOutput ( )

You must call setEndian() if you use this (memory) constructor.

201  {
202  m_alreadyWritten = 0;
203  m_swapBytes = false;
204  m_pos = 0;
205  m_filename = "<memory>";
206  m_buffer = NULL;
207  m_bufferLen = 0;
208  m_maxBufferLen = 0;
209  m_beginEndBits = 0;
210  m_bitString = 0;
211  m_bitPos = 0;
212  m_ok = true;
213  m_committed = false;
214 }
bool m_committed
Definition: BinaryOutput.h:56
size_t m_bufferLen
Definition: BinaryOutput.h:77
int m_beginEndBits
Definition: BinaryOutput.h:59
arena_t NULL
Definition: jemalloc_internal.h:624
size_t m_maxBufferLen
Definition: BinaryOutput.h:80
bool m_swapBytes
Definition: BinaryOutput.h:70
bool m_ok
Definition: BinaryOutput.h:91
int64 m_pos
Definition: BinaryOutput.h:83
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
int m_bitPos
Definition: BinaryOutput.h:67
std::string m_filename
Definition: BinaryOutput.h:54
int8 m_bitString
Definition: BinaryOutput.h:64
uint8 * m_buffer
Definition: BinaryOutput.h:74
G3D::BinaryOutput::BinaryOutput ( const std::string &  filename,
G3DEndian  fileEndian 
)

Doesn't actually open the file; commit() does that. Use "<memory>" as the filename if you're going to commit to memory.

Verify ability to write to disk

219  {
220 
221  m_pos = 0;
222  m_alreadyWritten = 0;
223  setEndian(fileEndian);
224  m_filename = filename;
225  m_buffer = NULL;
226  m_bufferLen = 0;
227  m_maxBufferLen = 0;
228  m_beginEndBits = 0;
229  m_bitString = 0;
230  m_bitPos = 0;
231  m_committed = false;
232 
233  m_ok = true;
235  commit(false);
236  m_committed = false;
237 }
void setEndian(G3DEndian fileEndian)
Definition: BinaryOutput.cpp:265
bool m_committed
Definition: BinaryOutput.h:56
size_t m_bufferLen
Definition: BinaryOutput.h:77
int m_beginEndBits
Definition: BinaryOutput.h:59
arena_t NULL
Definition: jemalloc_internal.h:624
size_t m_maxBufferLen
Definition: BinaryOutput.h:80
bool m_ok
Definition: BinaryOutput.h:91
int64 m_pos
Definition: BinaryOutput.h:83
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
int m_bitPos
Definition: BinaryOutput.h:67
void commit(bool flush=true)
Definition: BinaryOutput.cpp:322
std::string m_filename
Definition: BinaryOutput.h:54
int8 m_bitString
Definition: BinaryOutput.h:64
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

G3D::BinaryOutput::~BinaryOutput ( )
256  {
259  m_buffer = NULL;
260  m_bufferLen = 0;
261  m_maxBufferLen = 0;
262 }
size_t m_bufferLen
Definition: BinaryOutput.h:77
arena_t NULL
Definition: jemalloc_internal.h:624
size_t m_maxBufferLen
Definition: BinaryOutput.h:80
#define debugAssert(exp)
Definition: debugAssert.h:160
static void free(void *p)
Definition: System.cpp:1473
bool isValidHeapPointer(const void *x)
Definition: debug.h:38
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

Member Function Documentation

void G3D::BinaryOutput::beginBits ( )

Call before a series of BinaryOutput::writeBits calls. Only writeBits can be called between beginBits and endBits without corrupting the stream.

511  {
512  debugAssertM(m_beginEndBits == 0, "Already in beginBits...endBits");
513  m_bitString = 0x00;
514  m_bitPos = 0;
515  m_beginEndBits = 1;
516 }
int m_beginEndBits
Definition: BinaryOutput.h:59
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
int m_bitPos
Definition: BinaryOutput.h:67
int8 m_bitString
Definition: BinaryOutput.h:64
void G3D::BinaryOutput::commit ( bool  flush = true)

Write the bytes to disk. It is ok to call this multiple times; it will just overwrite the previous file.

Parent directories are created as needed if they do not exist.

Not called from the destructor; you must call it yourself.

Parameters
flushIf true (default) the file is ready for reading when the method returns, otherwise the method returns immediately and writes the file in the background.
322  {
323  debugAssertM(! m_committed, "Cannot commit twice");
324  m_committed = true;
325  debugAssertM(m_beginEndBits == 0, "Missing endBits before commit");
326 
327  if (m_filename == "<memory>") {
328  return;
329  }
330 
331  // Make sure the directory exists.
332  std::string root, base, ext, path;
333  Array<std::string> pathArray;
334  parseFilename(m_filename, root, pathArray, base, ext);
335 
336  path = root + stringJoin(pathArray, '/');
337  if (! FileSystem::exists(path, false)) {
339  }
340 
341  const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
342 
343  alwaysAssertM(m_filename != "<memory>", "Writing to memory file");
344  FILE* file = FileSystem::fopen(m_filename.c_str(), mode);
345 
346  if (! file) {
347  logPrintf("Error %d while trying to open \"%s\"\n", errno, m_filename.c_str());
348  }
349  m_ok = (file != NULL) && m_ok;
350 
351  if (m_ok) {
352  debugAssertM(file, std::string("Could not open '") + m_filename + "'");
353 
354  if (m_buffer != NULL) {
356 
357  size_t success = fwrite(m_buffer, m_bufferLen, 1, file);
358  (void)success;
359  debugAssertM(success == 1, std::string("Could not write to '") + m_filename + "'");
360  }
361  if (flush) {
362  fflush(file);
363  }
364  FileSystem::fclose(file);
365  file = NULL;
366  }
367 }
bool m_committed
Definition: BinaryOutput.h:56
size_t m_bufferLen
Definition: BinaryOutput.h:77
int m_beginEndBits
Definition: BinaryOutput.h:59
static void fclose(FILE *f)
Definition: FileSystem.h:290
arena_t NULL
Definition: jemalloc_internal.h:624
std::string stringJoin(const G3D::Array< std::string > &a, char joinChar)
Definition: stringutils.cpp:252
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
bool m_ok
Definition: BinaryOutput.h:91
static bool exists(const std::string &f, bool trustCache=true, bool caseSensitive=true)
Definition: FileSystem.h:401
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
std::string m_filename
Definition: BinaryOutput.h:54
static FILE * fopen(const char *filename, const char *mode)
Definition: FileSystem.h:282
void logPrintf(const char *fmt,...)
Definition: Log.cpp:25
void parseFilename(const std::string &filename, std::string &drive, Array< std::string > &path, std::string &base, std::string &ext)
Definition: fileutils.cpp:457
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
static void createDirectory(const std::string &path)
Definition: FileSystem.h:356
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::commit ( uint8 out)

Write the bytes to memory (which must be of at least size() bytes).

371  {
372  debugAssertM(! m_committed, "Cannot commit twice");
373  m_committed = true;
374 
376 }
static void memcpy(void *dst, const void *src, size_t numBytes)
Definition: System.cpp:643
bool m_committed
Definition: BinaryOutput.h:56
size_t m_bufferLen
Definition: BinaryOutput.h:77
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

void G3D::BinaryOutput::compress ( int  level = 9)

Compresses the data in the buffer in place, preceeding it with a little-endian uint32 indicating the uncompressed size.

Call immediately before commit().

Cannot be used for huge files (ones where the data was already written to disk)– will throw char*.

Parameters
levelCompression level. 0 = fast, low compression; 9 = slow, high compression
276  {
277  if (m_alreadyWritten > 0) {
278  throw "Cannot compress huge files (part of this file has already been written to disk).";
279  }
280  debugAssertM(! m_committed, "Cannot compress after committing.");
281  alwaysAssertM(m_bufferLen < 0xFFFFFFFF, "Compress only works for 32-bit files.");
282 
283  // This is the worst-case size, as mandated by zlib
284  unsigned long compressedSize = iCeil(m_bufferLen * 1.001) + 12;
285 
286  // Save the old buffer and reallocate to the worst-case size
287  const uint8* src = m_buffer;
288  const uint32 srcSize = (uint32)m_bufferLen;
289 
290  // add space for the 4-byte header
291  m_maxBufferLen = compressedSize + 4;
293 
294  // Write the header containing the old buffer size, which is needed for decompression
295  {
296  const uint8* convert = (const uint8*)&srcSize;
297  if (m_swapBytes) {
298  m_buffer[0] = convert[3];
299  m_buffer[1] = convert[2];
300  m_buffer[2] = convert[1];
301  m_buffer[3] = convert[0];
302  } else {
303  m_buffer[0] = convert[0];
304  m_buffer[1] = convert[1];
305  m_buffer[2] = convert[2];
306  m_buffer[3] = convert[3];
307  }
308  }
309 
310  // Compress and write after the header
311  int result = compress2(m_buffer + 4, &compressedSize, src, srcSize, iClamp(level, 0, 9));
312 
313  debugAssert(result == Z_OK); (void)result;
314  m_bufferLen = compressedSize + 4;
315  m_pos = m_bufferLen;
316 
317  // Free the old data
318  System::free((void*)src);
319 }
bool m_committed
Definition: BinaryOutput.h:56
size_t m_bufferLen
Definition: BinaryOutput.h:77
size_t m_maxBufferLen
Definition: BinaryOutput.h:80
bool m_swapBytes
Definition: BinaryOutput.h:70
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
Yes & convert(fmt::ULongLong)
int64 m_pos
Definition: BinaryOutput.h:83
static void * malloc(size_t bytes)
Definition: System.cpp:1441
#define debugAssert(exp)
Definition: debugAssert.h:160
uint32_t uint32
Definition: Define.h:150
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
static void free(void *p)
Definition: System.cpp:1473
#define Z_OK
Definition: zlib.h:173
uint8_t uint8
Definition: Define.h:152
uint32_t uint32
Definition: g3dmath.h:168
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
int iClamp(int val, int low, int hi)
Definition: g3dmath.h:545
uint8 * m_buffer
Definition: BinaryOutput.h:74
int iCeil(double fValue)
Definition: g3dmath.h:539

+ Here is the call graph for this function:

void G3D::BinaryOutput::endBits ( )

Call after a series of BinaryOutput::writeBits calls. This will finish out with zeros the last byte into which bits were written.

539  {
540  debugAssertM(m_beginEndBits == 1, "Not in beginBits...endBits");
541  if (m_bitPos > 0) {
543  }
544  m_bitString = 0;
545  m_bitPos = 0;
546  m_beginEndBits = 0;
547 }
int m_beginEndBits
Definition: BinaryOutput.h:59
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
int m_bitPos
Definition: BinaryOutput.h:67
int8 m_bitString
Definition: BinaryOutput.h:64

+ Here is the call graph for this function:

G3DEndian G3D::BinaryOutput::endian ( ) const
inline
159  {
160  return m_fileEndian;
161  }
G3DEndian m_fileEndian
Definition: BinaryOutput.h:72
const uint8* G3D::BinaryOutput::getCArray ( ) const
inline

Returns a pointer to the internal memory buffer.

153  {
154  return m_buffer;
155  }
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the caller graph for this function:

std::string G3D::BinaryOutput::getFilename ( ) const
inline
163  {
164  return m_filename;
165  }
std::string m_filename
Definition: BinaryOutput.h:54
int64 G3D::BinaryOutput::length ( ) const
inline
196  {
197  return m_bufferLen + m_alreadyWritten;
198  }
size_t m_bufferLen
Definition: BinaryOutput.h:77
int64 m_alreadyWritten
Definition: BinaryOutput.h:89

+ Here is the caller graph for this function:

bool G3D::BinaryOutput::ok ( ) const

True if no errors have been encountered.

271  {
272  return m_ok;
273 }
bool m_ok
Definition: BinaryOutput.h:91
BinaryOutput& G3D::BinaryOutput::operator= ( const BinaryOutput )
private
bool G3D::BinaryOutput::operator== ( const BinaryOutput )
private
int64 G3D::BinaryOutput::position ( ) const
inline

Returns the current byte position in the file, where 0 is the beginning and getLength() - 1 is the end.

232  {
233  return m_pos + m_alreadyWritten;
234  }
int64 m_pos
Definition: BinaryOutput.h:83
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
void G3D::BinaryOutput::reallocBuffer ( size_t  bytes,
size_t  oldBufferLen 
)
private
113  {
114  //debugPrintf("reallocBuffer(%d, %d)\n", bytes, oldBufferLen);
115 
116  size_t newBufferLen = (int)(m_bufferLen * 1.5) + 100;
117  uint8* newBuffer = NULL;
118 
119  if ((m_filename == "<memory>") || (newBufferLen < MAX_BINARYOUTPUT_BUFFER_SIZE)) {
120  // We're either writing to memory (in which case we *have* to
121  // try and allocate) or we've been asked to allocate a
122  // reasonable size buffer.
123 
124  // debugPrintf(" realloc(%d)\n", newBufferLen);
125  newBuffer = (uint8*)System::realloc(m_buffer, newBufferLen);
126  if (newBuffer != NULL) {
127  m_maxBufferLen = newBufferLen;
128  }
129  }
130 
131  if ((newBuffer == NULL) && (bytes > 0)) {
132  // Realloc failed; we're probably out of memory. Back out
133  // the entire call and try to dump some data to disk.
134  alwaysAssertM(m_filename != "<memory>", "Realloc failed while writing to memory.");
135  m_bufferLen = oldBufferLen;
137  } else {
138  // Realloc succeeded
139  m_buffer = newBuffer;
141  }
142 }
size_t m_bufferLen
Definition: BinaryOutput.h:77
arena_t NULL
Definition: jemalloc_internal.h:624
size_t m_maxBufferLen
Definition: BinaryOutput.h:80
static void * realloc(void *block, size_t bytes)
Definition: System.cpp:1463
#define MAX_BINARYOUTPUT_BUFFER_SIZE
Definition: BinaryOutput.cpp:30
void reserveBytesWhenOutOfMemory(size_t bytes)
Definition: BinaryOutput.cpp:145
#define debugAssert(exp)
Definition: debugAssert.h:160
std::string m_filename
Definition: BinaryOutput.h:54
uint8_t uint8
Definition: Define.h:152
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
bool isValidHeapPointer(const void *x)
Definition: debug.h:38
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::reserveBytes ( size_t  bytes)
inlineprivate

Make sure at least bytes can be written, resizing if necessary.

101  {
102  debugAssert(bytes > 0);
103  size_t oldBufferLen = m_bufferLen;
104 
105  m_bufferLen = max(m_bufferLen, (size_t)(m_pos + bytes));
106  if (m_bufferLen > m_maxBufferLen) {
107  reallocBuffer(bytes, oldBufferLen);
108  }
109  }
size_t m_bufferLen
Definition: BinaryOutput.h:77
size_t m_maxBufferLen
Definition: BinaryOutput.h:80
int64 m_pos
Definition: BinaryOutput.h:83
T max(const T &x, const T &y)
Definition: g3dmath.h:320
#define debugAssert(exp)
Definition: debugAssert.h:160
void reallocBuffer(size_t bytes, size_t oldBufferLen)
Definition: BinaryOutput.cpp:113

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::reserveBytesWhenOutOfMemory ( size_t  bytes)
private
145  {
146  if (m_filename == "<memory>") {
147  throw "Out of memory while writing to memory in BinaryOutput (no RAM left).";
148  } else if ((int)bytes > (int)m_maxBufferLen) {
149  throw "Out of memory while writing to disk in BinaryOutput (could not create a large enough buffer).";
150  } else {
151 
152  // Dump the contents to disk. In order to enable seeking backwards,
153  // we keep the last 10 MB in memory.
154  size_t writeBytes = m_bufferLen - 10 * 1024 * 1024;
155 
156  if (writeBytes < m_bufferLen / 3) {
157  // We're going to write less than 1/3 of the file;
158  // give up and just write the whole thing.
159  writeBytes = m_bufferLen;
160  }
161  debugAssert(writeBytes > 0);
162 
163  //debugPrintf("Writing %d bytes to disk\n", writeBytes);
164 
165  const char* mode = (m_alreadyWritten > 0) ? "ab" : "wb";
166  alwaysAssertM(m_filename != "<memory>", "Writing memory file");
167  FILE* file = FileSystem::fopen(m_filename.c_str(), mode);
168  debugAssert(file);
169 
170  size_t count = fwrite(m_buffer, 1, writeBytes, file);
171  debugAssert(count == writeBytes); (void)count;
172 
173  fclose(file);
174  file = NULL;
175 
176  // Record that we saved this data.
179  m_pos -= writeBytes;
180 
181  debugAssert(m_bufferLen < m_maxBufferLen);
182  debugAssert(m_bufferLen >= 0);
183  debugAssert(m_pos >= 0);
185 
186  // Shift the unwritten data back appropriately in the buffer.
190 
191  // *now* we allocate bytes (there should presumably be enough
192  // space in the buffer; if not, we'll come back through this
193  // code and dump the last 10MB to disk as well. Note that the
194  // bytes > maxBufferLen case above would already have triggered
195  // if this call couldn't succeed.
196  reserveBytes(bytes);
197  }
198 }
static void memcpy(void *dst, const void *src, size_t numBytes)
Definition: System.cpp:643
size_t m_bufferLen
Definition: BinaryOutput.h:77
int64_t int64
Definition: Define.h:145
arena_t NULL
Definition: jemalloc_internal.h:624
size_t m_maxBufferLen
Definition: BinaryOutput.h:80
int64 m_pos
Definition: BinaryOutput.h:83
#define debugAssert(exp)
Definition: debugAssert.h:160
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
void writeBytes(const void *b, size_t count)
Definition: BinaryOutput.h:260
std::string m_filename
Definition: BinaryOutput.h:54
static FILE * fopen(const char *filename, const char *mode)
Definition: FileSystem.h:282
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165
bool isValidHeapPointer(const void *x)
Definition: debug.h:38
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::reset ( )

A memory BinaryOutput may be reset so that it can be written to again without allocating new memory. The underlying array will not be deallocated, but the reset structure will act like a newly intialized one.

240  {
242  alwaysAssertM(m_filename == "<memory>",
243  "Can only reset a BinaryOutput that writes to memory.");
244 
245  // Do not reallocate, just clear the size of the buffer.
246  m_pos = 0;
247  m_alreadyWritten = 0;
248  m_bufferLen = 0;
249  m_beginEndBits = 0;
250  m_bitString = 0;
251  m_bitPos = 0;
252  m_committed = false;
253 }
bool m_committed
Definition: BinaryOutput.h:56
size_t m_bufferLen
Definition: BinaryOutput.h:77
int m_beginEndBits
Definition: BinaryOutput.h:59
int64 m_pos
Definition: BinaryOutput.h:83
#define debugAssert(exp)
Definition: debugAssert.h:160
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
int m_bitPos
Definition: BinaryOutput.h:67
std::string m_filename
Definition: BinaryOutput.h:54
int8 m_bitString
Definition: BinaryOutput.h:64
#define alwaysAssertM(exp, message)
Definition: debugAssert.h:165

+ Here is the caller graph for this function:

void G3D::BinaryOutput::setEndian ( G3DEndian  fileEndian)
265  {
266  m_fileEndian = fileEndian;
267  m_swapBytes = (fileEndian != System::machineEndian());
268 }
bool m_swapBytes
Definition: BinaryOutput.h:70
G3DEndian m_fileEndian
Definition: BinaryOutput.h:72
static G3DEndian machineEndian()
Definition: System.h:219

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::setLength ( int64  n)
inline

Sets the length of the file to n, padding with 0's past the current end. Does not change the position of the next byte to be written unless n < size().

Throws char* when resetting a huge file to be shorter than its current length.

213  {
214  n = n - m_alreadyWritten;
215 
216  if (n < 0) {
217  throw "Cannot resize huge files to be shorter.";
218  }
219 
220  if (n < (int64)m_bufferLen) {
221  m_pos = n;
222  }
223  if (n > (int64)m_bufferLen) {
224  reserveBytes((size_t)(n - m_bufferLen));
225  }
226  }
size_t m_bufferLen
Definition: BinaryOutput.h:77
int64_t int64
Definition: Define.h:145
int64 m_pos
Definition: BinaryOutput.h:83
int64 m_alreadyWritten
Definition: BinaryOutput.h:89
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::setPosition ( int64  p)
inline

Sets the position. Can set past length, in which case the file is padded with zeros up to one byte before the next to be written.

May throw a char* exception when seeking backwards on a huge file.

244  {
245  p = p - m_alreadyWritten;
246 
247  if (p > (int64)m_bufferLen) {
248  setLength((int)(p + (int64)m_alreadyWritten));
249  }
250 
251  if (p < 0) {
252  throw "Cannot seek more than 10 MB backwards on huge files.";
253  }
254 
255  m_pos = (int)p;
256  }
void setLength(int64 n)
Definition: BinaryOutput.h:213
size_t m_bufferLen
Definition: BinaryOutput.h:77
int64_t int64
Definition: Define.h:145
int64 m_pos
Definition: BinaryOutput.h:83
int64 m_alreadyWritten
Definition: BinaryOutput.h:89

+ Here is the call graph for this function:

int64 G3D::BinaryOutput::size ( ) const
inline
200  {
201  return length();
202  }
int64 length() const
Definition: BinaryOutput.h:196

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::skip ( int  n)
inline

Skips ahead n bytes.

387  {
388  if (m_pos + n > (int64)m_bufferLen) {
390  }
391  m_pos += n;
392  }
void setLength(int64 n)
Definition: BinaryOutput.h:213
size_t m_bufferLen
Definition: BinaryOutput.h:77
int64_t int64
Definition: Define.h:145
int64 m_pos
Definition: BinaryOutput.h:83
int64 m_alreadyWritten
Definition: BinaryOutput.h:89

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeBits ( uint32  bitString,
int  numBits 
)

Write numBits from bitString to the output stream. Bits are numbered from low to high.

Can only be called between beginBits and endBits. Bits written are semantically little-endian, regardless of the actual endian-ness of the system. That is, writeBits(0xABCD, 16) writes 0xCD to the first byte and 0xAB to the second byte. However, if used with BinaryInput::readBits, the ordering is transparent to the caller.

519  {
520 
521  while (numBits > 0) {
522  // Extract the current bit of value and
523  // insert it into the current byte
524  m_bitString |= (value & 1) << m_bitPos;
525  ++m_bitPos;
526  value = value >> 1;
527  --numBits;
528 
529  if (m_bitPos > 7) {
530  // We've reached the end of this byte
532  m_bitString = 0x00;
533  m_bitPos = 0;
534  }
535  }
536 }
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283
int m_bitPos
Definition: BinaryOutput.h:67
int8 m_bitString
Definition: BinaryOutput.h:64
const FieldDescriptor value
Definition: descriptor.h:1522

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeBool8 ( bool  b)
inline
279  {
280  writeInt8(b ? 1 : 0);
281  }
void writeInt8(int8 i)
Definition: BinaryOutput.h:273

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeBytes ( const void *  b,
size_t  count 
)
inline
261  {
262 
263  reserveBytes(count);
264  debugAssert(m_pos >= 0);
265  debugAssert(m_bufferLen >= count);
266  System::memcpy(m_buffer + m_pos, b, count);
267  m_pos += count;
268  }
static void memcpy(void *dst, const void *src, size_t numBytes)
Definition: System.cpp:643
size_t m_bufferLen
Definition: BinaryOutput.h:77
int64 m_pos
Definition: BinaryOutput.h:83
#define debugAssert(exp)
Definition: debugAssert.h:160
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeColor3 ( const Color3 v)
504  {
505  writeFloat32(v.r);
506  writeFloat32(v.g);
507  writeFloat32(v.b);
508 }
void writeFloat32(float32 f)
Definition: BinaryOutput.h:312

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeColor4 ( const Color4 v)
496  {
497  writeFloat32(v.r);
498  writeFloat32(v.g);
499  writeFloat32(v.b);
500  writeFloat32(v.a);
501 }
void writeFloat32(float32 f)
Definition: BinaryOutput.h:312

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeFloat32 ( float32  f)
inline
312  {
314  union {
315  float32 a;
316  uint32 b;
317  };
318  a = f;
319  writeUInt32(b);
320  }
int m_beginEndBits
Definition: BinaryOutput.h:59
#define debugAssert(exp)
Definition: debugAssert.h:160
float float32
Definition: g3dmath.h:172
uint32_t uint32
Definition: Define.h:150
void writeUInt32(uint32 u)
Definition: BinaryOutput.cpp:395

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeFloat64 ( float64  f)
inline
322  {
323  union {
324  float64 a;
325  uint64 b;
326  };
327  a = f;
328  writeUInt64(b);
329  }
double float64
Definition: g3dmath.h:173
void writeUInt64(uint64 u)
Definition: BinaryOutput.cpp:415
uint64_t uint64
Definition: Define.h:149

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeInt16 ( int16  i)
inline
295  {
296  writeUInt16(*(uint16*)&i);
297  }
void writeUInt16(uint16 u)
Definition: BinaryOutput.cpp:379
uint16_t uint16
Definition: Define.h:151

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeInt32 ( int32  i)
inline
301  {
303  writeUInt32(*(uint32*)&i);
304  }
int m_beginEndBits
Definition: BinaryOutput.h:59
#define debugAssert(exp)
Definition: debugAssert.h:160
uint32_t uint32
Definition: Define.h:150
void writeUInt32(uint32 u)
Definition: BinaryOutput.cpp:395

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeInt64 ( int64  i)
inline
308  {
309  writeUInt64(*(uint64*)&i);
310  }
void writeUInt64(uint64 u)
Definition: BinaryOutput.cpp:415
uint64_t uint64
Definition: Define.h:149

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeInt8 ( int8  i)
inline

Writes a signed 8-bit integer to the current position.

273  {
274  reserveBytes(1);
275  m_buffer[m_pos] = *(uint8*)&i;
276  ++m_pos;
277  }
int64 m_pos
Definition: BinaryOutput.h:83
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8_t uint8
Definition: Define.h:152
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeString ( const std::string &  s)
inline

Write a string with NULL termination.

334  {
335  writeString(s.c_str());
336  }
void writeString(const std::string &s)
Definition: BinaryOutput.h:334

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeString ( const std::string &  s,
int  len 
)
inline

Write a string that always consumes len bytes, truncating or padding as necessary

339  {
340  const int pad = len - ((int)s.length() + 1);
341  if (pad >= 0) {
342  writeString(s.c_str());
343  for (int i = 0; i < pad; ++i) {
344  writeUInt8(0);
345  }
346  } else {
347  // Truncate
348  writeBytes(s.c_str(), len);
349  }
350  }
IntFormatSpec< int, AlignTypeSpec< TYPE_CODE >, Char > pad(int value, unsigned width, Char fill= ' ')
void writeString(const std::string &s)
Definition: BinaryOutput.h:334
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283
void writeBytes(const void *b, size_t count)
Definition: BinaryOutput.h:260

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeString ( const char *  s)
437  {
438  // +1 is because strlen doesn't count the null
439  size_t len = strlen(s) + 1;
440 
442  reserveBytes(len);
443  System::memcpy(m_buffer + m_pos, s, len);
444  m_pos += len;
445 }
static void memcpy(void *dst, const void *src, size_t numBytes)
Definition: System.cpp:643
int m_beginEndBits
Definition: BinaryOutput.h:59
int64 m_pos
Definition: BinaryOutput.h:83
#define debugAssert(exp)
Definition: debugAssert.h:160
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeString32 ( const char *  s)
463  {
464  // Write the NULL and count it
465  size_t len = strlen(s) + 1;
466  writeUInt32((uint32)len);
467 
469  reserveBytes(len);
470  System::memcpy(m_buffer + m_pos, s, len);
471  m_pos += len;
472 }
static void memcpy(void *dst, const void *src, size_t numBytes)
Definition: System.cpp:643
int m_beginEndBits
Definition: BinaryOutput.h:59
int64 m_pos
Definition: BinaryOutput.h:83
#define debugAssert(exp)
Definition: debugAssert.h:160
uint32_t uint32
Definition: Define.h:150
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
void writeUInt32(uint32 u)
Definition: BinaryOutput.cpp:395
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeString32 ( const std::string &  s)
inline

Write a NULL-terminated string with a 32-bit length field in front of it. The NULL character is included in the length count.

370  {
371  writeString32(s.c_str());
372  }
void writeString32(const char *s)
Definition: BinaryOutput.cpp:463

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeStringEven ( const std::string &  s)
inline

Write a string, ensuring that the total length including NULL is even.

358  {
359  writeStringEven(s.c_str());
360  }
void writeStringEven(const std::string &s)
Definition: BinaryOutput.h:358
void G3D::BinaryOutput::writeStringEven ( const char *  s)
448  {
449  // +1 is because strlen doesn't count the null
450  size_t len = strlen(s) + 1;
451 
452  reserveBytes(len);
453  System::memcpy(m_buffer + m_pos, s, len);
454  m_pos += len;
455 
456  // Pad with another NULL
457  if ((len % 2) == 1) {
458  writeUInt8(0);
459  }
460 }
static void memcpy(void *dst, const void *src, size_t numBytes)
Definition: System.cpp:643
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283
int64 m_pos
Definition: BinaryOutput.h:83
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeUInt16 ( uint16  u)
379  {
380  reserveBytes(2);
381 
382  uint8* convert = (uint8*)&u;
383 
384  if (m_swapBytes) {
385  m_buffer[m_pos] = convert[1];
386  m_buffer[m_pos + 1] = convert[0];
387  } else {
388  *(uint16*)(m_buffer + m_pos) = u;
389  }
390 
391  m_pos += 2;
392 }
bool m_swapBytes
Definition: BinaryOutput.h:70
Yes & convert(fmt::ULongLong)
int64 m_pos
Definition: BinaryOutput.h:83
uint16_t uint16
Definition: Define.h:151
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8_t uint8
Definition: Define.h:152
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeUInt32 ( uint32  u)
395  {
396  reserveBytes(4);
397 
398  uint8* convert = (uint8*)&u;
399 
401 
402  if (m_swapBytes) {
403  m_buffer[m_pos] = convert[3];
404  m_buffer[m_pos + 1] = convert[2];
405  m_buffer[m_pos + 2] = convert[1];
406  m_buffer[m_pos + 3] = convert[0];
407  } else {
408  *(uint32*)(m_buffer + m_pos) = u;
409  }
410 
411  m_pos += 4;
412 }
int m_beginEndBits
Definition: BinaryOutput.h:59
bool m_swapBytes
Definition: BinaryOutput.h:70
Yes & convert(fmt::ULongLong)
int64 m_pos
Definition: BinaryOutput.h:83
#define debugAssert(exp)
Definition: debugAssert.h:160
uint32_t uint32
Definition: Define.h:150
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8_t uint8
Definition: Define.h:152
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeUInt64 ( uint64  u)
415  {
416  reserveBytes(8);
417 
418  uint8* convert = (uint8*)&u;
419 
420  if (m_swapBytes) {
421  m_buffer[m_pos] = convert[7];
422  m_buffer[m_pos + 1] = convert[6];
423  m_buffer[m_pos + 2] = convert[5];
424  m_buffer[m_pos + 3] = convert[4];
425  m_buffer[m_pos + 4] = convert[3];
426  m_buffer[m_pos + 5] = convert[2];
427  m_buffer[m_pos + 6] = convert[1];
428  m_buffer[m_pos + 7] = convert[0];
429  } else {
430  *(uint64*)(m_buffer + m_pos) = u;
431  }
432 
433  m_pos += 8;
434 }
bool m_swapBytes
Definition: BinaryOutput.h:70
Yes & convert(fmt::ULongLong)
int64 m_pos
Definition: BinaryOutput.h:83
uint64_t uint64
Definition: Define.h:149
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8_t uint8
Definition: Define.h:152
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeUInt8 ( uint8  i)
inline
283  {
284  reserveBytes(1);
285  m_buffer[m_pos] = i;
286  ++m_pos;
287  }
int64 m_pos
Definition: BinaryOutput.h:83
void reserveBytes(size_t bytes)
Definition: BinaryOutput.h:101
uint8 * m_buffer
Definition: BinaryOutput.h:74

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeUNorm8 ( unorm8  i)
inline
289  {
290  writeUInt8(i.bits());
291  }
void writeUInt8(uint8 i)
Definition: BinaryOutput.h:283

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeVector2 ( const Vector2 v)
490  {
491  writeFloat32(v.x);
492  writeFloat32(v.y);
493 }
void writeFloat32(float32 f)
Definition: BinaryOutput.h:312

+ Here is the call graph for this function:

void G3D::BinaryOutput::writeVector3 ( const Vector3 v)
483  {
484  writeFloat32(v.x);
485  writeFloat32(v.y);
486  writeFloat32(v.z);
487 }
void writeFloat32(float32 f)
Definition: BinaryOutput.h:312

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::BinaryOutput::writeVector4 ( const Vector4 v)
475  {
476  writeFloat32(v.x);
477  writeFloat32(v.y);
478  writeFloat32(v.z);
479  writeFloat32(v.w);
480 }
void writeFloat32(float32 f)
Definition: BinaryOutput.h:312

+ Here is the call graph for this function:

Member Data Documentation

int64 G3D::BinaryOutput::m_alreadyWritten
private

Number of bytes already written to the file. Even on 32-bit OS, this can be 64-bits

int G3D::BinaryOutput::m_beginEndBits
private

0 outside of beginBits...endBits, 1 inside

int G3D::BinaryOutput::m_bitPos
private

Position (from the lowest bit) currently used in bitString.

int8 G3D::BinaryOutput::m_bitString
private

The current string of bits being built up by beginBits...endBits. This string is treated semantically, as if the lowest bit was on the left and the highest was on the right.

uint8* G3D::BinaryOutput::m_buffer
private
size_t G3D::BinaryOutput::m_bufferLen
private

Size of the elements used

bool G3D::BinaryOutput::m_committed
private
G3DEndian G3D::BinaryOutput::m_fileEndian
private
std::string G3D::BinaryOutput::m_filename
private
bool G3D::BinaryOutput::m_init
private

is this initialized?

size_t G3D::BinaryOutput::m_maxBufferLen
private

Underlying size of memory allocaded

bool G3D::BinaryOutput::m_ok
private
int64 G3D::BinaryOutput::m_pos
private

Next byte in file

bool G3D::BinaryOutput::m_swapBytes
private

The documentation for this class was generated from the following files: