⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datablok.cpp

📁 伯克利做的SFTP安全文件传输协议
💻 CPP
字号:
// datablok.cc// code for datablok.h// copyright SafeTP Development Group, Inc., 2000  Terms of use are as specified in license.txt#include "datablok.h"     // this module#include "exc.h"          // xassert, CAUTIOUS_RELAY#include "crc.h"          // crc32#include "syserr.h"       // xsyserror#include <stdio.h>        // printf#include <string.h>       // memcpy#include <ctype.h>        // isprint        // define the endpost byte as something we hope is// unlikely to coincidentally be written during an// overrunbyte const DataBlock::endpost = 0xBB;        void DataBlock::init(int allocatedSize){  xassert(allocatedSize >= 0);  dataLen = 0;  allocated = allocatedSize;  if (allocated) {    data = allocate(allocated);  }  else {    data = NULL;  }      SELFCHECK();}        STATICDEF byte *DataBlock::allocate(int size){  byte *ret = new byte[size+1];  ret[size] = endpost;  return ret;}        void DataBlock::selfCheck() const{  if (!( 0 <= dataLen && dataLen <= allocated )) {    breaker();    // having trouble discovering the precise state under gdb  }  xassert(0 <= dataLen && dataLen <= allocated);  xassert( (data==NULL) == (allocated==0) );  xassert( data==NULL || data[allocated]==endpost );}        DataBlock::DataBlock(int allocatedSize){  init(allocatedSize);  SELFCHECK();}    DataBlock::DataBlock(char const *srcString){  init(0);  setFromString(srcString);  SELFCHECK();}        void DataBlock::ctor(byte const *srcData, int dataLen){  init(0);  setFromBlock(srcData, dataLen);  SELFCHECK();}void DataBlock::ctor(byte const *srcData, int srcDataLen, int allocatedSize){  xassert(srcDataLen <= allocatedSize);  init(allocatedSize);  dataLen = srcDataLen;  memcpy(data, srcData, dataLen);  SELFCHECK();}        DataBlock::DataBlock(DataBlock const &obj){  init(obj.allocated);  copyCtorShared(obj);}void DataBlock::copyCtorShared(DataBlock const &obj){  dataLen = obj.dataLen;  if (dataLen > 0) {    memcpy(data, obj.data, dataLen);  }  SELFCHECK();}DataBlock::DataBlock(DataBlock const &obj, int minToAllocate){  init(mymax(obj.getAllocated(), minToAllocate));  copyCtorShared(obj);}        DataBlock::~DataBlock(){  try {    SELFCHECK();    if (data) {      delete[] data;    }  }  CAUTIOUS_RELAY}        bool DataBlock::allEqual(DataBlock const &obj) const{  SELFCHECK();  return allocated == obj.allocated &&         dataEqual(obj);}bool DataBlock::dataEqual(DataBlock const &obj) const{  SELFCHECK();  if (dataLen != obj.dataLen ||      (dataLen > 0 &&       0 != memcmp(data, obj.data, dataLen))) {    return false;  }  else {    return true;  }}void DataBlock::setDataLen(int newLen){  SELFCHECK();  xassert(0 <= newLen && newLen <= allocated);  dataLen = newLen;  SELFCHECK();}        void DataBlock::setAllocated(int newAllocated){  SELFCHECK();  xassert(newAllocated >= 0);  if (allocated != newAllocated) {    // allocate new buffer    byte *newData = NULL;    if (newAllocated > 0) {      newData = allocate(newAllocated);    }    // truncate defined data    if (dataLen > newAllocated) {      dataLen = newAllocated;    }        // transfer data    if (dataLen > 0) {      memcpy(newData, data, dataLen);    }        // deallocate old buffer and replace with new buffer    delete[] data;    data = newData;    allocated = newAllocated;  }  SELFCHECK();}    void DataBlock::ensureAtLeast(int minAllocated){  if (allocated < minAllocated) {    setAllocated(minAllocated);  }}void DataBlock::growDataLen(int changeAmount){  ensureAtLeast(getDataLen() + changeAmount);  changeDataLen(changeAmount);}void DataBlock::addNull(){  SELFCHECK();  data[dataLen] = 0;  setDataLen(dataLen + 1);  SELFCHECK();}    void DataBlock::setFromString(char const *srcString){  SELFCHECK();  int len = strlen(srcString)+1;    // a string is its contents and the null terminator  setFromBlock((byte const*)srcString, len);  SELFCHECK();}    void DataBlock::setFromBlock(byte const *srcData, int len){  SELFCHECK();  if (len > allocated) {    setAllocated(len);  }  setDataLen(len);  if (len > 0) {    memcpy(data, srcData, len);  }  SELFCHECK();}DataBlock& DataBlock::operator= (DataBlock const &obj){  SELFCHECK();  if (this != &obj) {    setAllocated(obj.allocated);    dataLen = obj.dataLen;    memcpy(data, obj.data, dataLen);  }  SELFCHECK();  return *this;}void DataBlock::print(char const *label, int bytesPerLine) const{  xassert(bytesPerLine >= 1);  SELFCHECK();  if (label) {    printf("---- %s, length = %d, crc32 = 0x%lX ---- {\n",           label, getDataLen(),           crc32(getDataC(), getDataLen()));  }  int cursor = 0;  while (cursor < getDataLen()) {    int linelen = mymin(bytesPerLine, getDataLen() - cursor);    xassert(linelen >= 1);    // ensure can't loop infinitely    printf("  ");     // indent    printHexLine(getDataC() + cursor, linelen, bytesPerLine);    printf("   ");    printPrintableLine(getDataC() + cursor, linelen);    printf("\n");    cursor += linelen;  }  if (label) {    printf("}\n");  }  SELFCHECK();}// print 'length' bytes of 'data' in hex// blank-pad the output as if 'linelen' bytes were presentSTATICDEF void DataBlock::printHexLine(byte const *data, int length, int linelen){  xassert(data != NULL &&          length >= 1 &&          linelen >= length);  for (int i=0; i<linelen; i++) {    if (i < length) {      printf("%02X ", (byte)*data);      data++;    }    else {      printf("   ");    }  }}// print 'length' bytes of 'data', substituting 'unprintable' for bytes for// which 'isprint' is falseSTATICDEF void DataBlock::printPrintableLine(byte const *data, int length,                                             char unprintable){  xassert(data != NULL &&          length >= 1);  while (length--) {    if (isprint(*data)) {      printf("%c", *data);    }    else {      printf("%c", unprintable);    }    data++;  }}#if 0void DataBlock::print(char const *label) const{  enum { MARGIN = 70 };  if (label) {    printf("------ %s (length=%d) -------\n", label, getDataLen());  }  byte *p = data;  int i;  int column=0;  for (i=0; i<dataLen; i++, p++) {    if (isprint(*p)) {      if (*p != '\\') {        column += printf("%c", *p);      }      else {        printf("\\\\");     // otherwise '\\','x','nn','nn' would be ambiguous      }    }    else {      column += printf("\\x%02X", *p);    }    if (column >= MARGIN && (i+1) < dataLen) {      printf("\\\n");       // continuation lines end with backslash      column = 0;    }  }  // this makes spaces at the end of a buffer invisible.. oh well..  if (column != 0) {    // if didn't just newline...    printf("\n");  }  if (label) {    printf("------ end of %s -------\n", label);  }}#endif // 0void DataBlock::dontPrint(char const *, int) const{}void DataBlock::writeToFile(char const *fname) const{  FILE *fp = fopen(fname, "wb");  if (!fp) {    xsyserror("fopen", fname);  }  if (fwrite(getDataC(), 1, getDataLen(), fp) != (size_t)getDataLen()) {    xsyserror("fwrite", fname);  }  if (fclose(fp) != 0) {    xsyserror("fclose", fname);  }}void DataBlock::readFromFile(char const *fname){  FILE *fp = fopen(fname, "rb");  if (!fp) {    xsyserror("fopen", fname);  }  // seek to end to know how much to allocate  if (fseek(fp, 0, SEEK_END) != 0) {    xsyserror("fseek", fname);  }  long len = ftell(fp);  if (len < 0) {    xsyserror("ftell", fname);  }  setAllocated(len);  // read data  if (fseek(fp, 0, SEEK_SET) != 0) {    xsyserror("fseek", fname);  }  if (fread(getData(), 1, len, fp) != (size_t)len) {    xsyserror("fread", fname);  }  setDataLen(len);  if (fclose(fp) != 0) {    xsyserror("fclose", fname);  }}// ------------- self test code --------------#ifdef DATABLOK_TEST#include "exc.h"         // exceptionsint doit(){  // nest everything so the dtors are inside  {    // test printing function    {      DataBlock b(260);      for (int i=0; i<260; i++) {        b.getData()[i] = (byte)i;      }      b.setDataLen(260);      b.print("all bytes plus 4 extra");    }    DataBlock block("yadda smacker");    xassert(block.getDataLen() == 14);    DataBlock block2((byte*)"yadda smacker", 13, 14);    block2.addNull();    xassert(block == block2);    DataBlock block3;    block3 = block2;    xassert(block3 == block);    block3.setAllocated(5);       // truncates    block2.setAllocated(25);    xassert(block3 != block2);    // test file save/load    block.writeToFile("tempfile.blk");    DataBlock block4;    block4.readFromFile("tempfile.blk");    xassert(block == block4);    // test overrun detection    try {      {        DataBlock b(block);        b.getData()[block.getAllocated()] = 0;   // overrun        printf("this should cause an assertion failure:\n");        // invoke selfcheck in destructor      }      return printf("failed to detect overrun\n");    }    catch (...) {}  }      printf("test succeeded\n");  return 0;}    int main(){  try {    return doit();  }  catch (xBase &x) {    return printf("failed: %s\n", x.why());  }}    #endif // DATABLOK_TEST

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -