📄 datablok.h
字号:
// datablok.h// arbitrary block of data// copyright SafeTP Development Group, Inc., 2000 Terms of use are as specified in license.txt#ifndef __DATABLOK_H#define __DATABLOK_H#include "typ.h" // byte, boolclass DataBlock {private: // data byte *data; // data itself (may be NULL) int dataLen; // length of data, starting at data[0] int allocated; // amount of memory allocated at 'data' // invariants: 0 <= dataLen <= allocated // (data==NULL) == (allocated==0) // endpost: 'data' will be kept allocated with one extra byte at the // end, where an endpost byte is written. thus, we have another // invariant: // (data!=NULL) implies data[allocated] == endpost static byte const endpost;private: // funcs void init(int allocatedSize); // base ctor static byte *allocate(int size); // allocate a block of memory, writing endpost void copyCtorShared(DataBlock const &obj); // shared by both copy constructors (actually, only one is the true // copy ctor...) void ctor(byte const *srcData, int dataLen); void ctor(byte const *srcData, int dataLen, int allocatedSize); // shared ctor calls as a workaround for char casting problems void selfCheck() const; // confirm that invariants are truepublic: // funcs // constructors DataBlock(int allocatedSize = 0); // make an empty datablock holder; when allocatedSize is 0, 'data' // is initially set to NULL EXPLICIT DataBlock(char const *srcString); // make a copy of 'srcString' data, which is null-terminated DataBlock(byte const *srcData, int dataLen) { ctor(srcData, dataLen); } DataBlock(char const *srcData, int dataLen) { ctor((byte const*)srcData, dataLen); } // make a copy of 'srcData', which is 'dataLen' bytes long DataBlock(byte const *srcData, int dataLen, int allocatedSize) { ctor(srcData, dataLen, allocatedSize); } DataBlock(char const *srcData, int dataLen, int allocatedSize) { ctor((byte const*)srcData, dataLen, allocatedSize); } // make a copy of 'srcData', which is 'dataLen' bytes long, in a buffer // that is 'allocatedSize' bytes long DataBlock(DataBlock const &obj); // copy data, allocate same amount as 'obj' DataBlock(DataBlock const &obj, int minToAllocate); // copy obj's contents; allocate either obj.getAllocated() or // minToAllocate, whichever is larger (this turns out to be a // common idiom) ~DataBlock(); // selectors byte const *getDataC() const { return data; } int getDataLen() const { return dataLen; } int getAllocated() const { return allocated; } bool dataEqual(DataBlock const &obj) const; // compares data length and data-length bytes of data bool allEqual(DataBlock const &obj) const; // compares data, length, and allocation length bool operator== (DataBlock const &obj) const { return dataEqual(obj); } bool operator!= (DataBlock const &obj) const { return !operator==(obj); } // SM, 1/24/99: with the coding of blokutil, I've finally clarified that // allocation length is a concern of efficiency, not correctness, and so // have changed the meaning of == to just look at data. The old behavior // is available as 'allEqual()'. // mutators byte *getData() { return data; } void setDataLen(int newLen); // asserts that 0 <= newLen <= allocated void setAllocated(int newAllocated); // i.e. realloc void addNull(); // add a null ('\0') to the end; there must be sufficient allocated space void changeDataLen(int changeAmount) { setDataLen(getDataLen() + changeAmount); } void ensureAtLeast(int minAllocated); // if 'allocated' is currently less than minAllocated, then // set 'allocated' to minAllocated (preserving existing contents) void growDataLen(int changeAmount); // grows allocated data if necessary, whereas changeDataLen will throw // an exception if there isn't already enough allocated space void setFromString(char const *srcString); void setFromBlock(byte const *srcData, int dataLen); DataBlock& operator= (DataBlock const &obj); // causes data AND allocation length equality // convenient file read/write void writeToFile(char const *fname) const; void readFromFile(char const *fname); // for debugging enum { DEFAULT_PRINT_BYTES = 16 }; void print(char const *label = NULL, int bytesPerLine = DEFAULT_PRINT_BYTES) const; // write a simple representation to stdout // if label is not NULL, the data is surrounded by '---'-style delimiters void dontPrint(char const *label = NULL, int bytesPerLine = DEFAULT_PRINT_BYTES) const; // does nothing; useful for two reasons: // 1. lets me define macros that expand to 'print' during debug // and dontPrint during non-debug // 2. plays a vital role in a g++ bug workaround (g++ sucks!!) // utility, defined here for no good reason static void printHexLine(byte const *data, int length, int lineLength); // print 'length' bytes of 'data' in hex // blank-pad the output as if 'linelen' bytes were present static void printPrintableLine(byte const *data, int length, char unprintable = '.'); // print 'length' bytes of 'data', substituting 'unprintable' for bytes for // which 'isprint' is false};#endif // __DATABLOK_H
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -