218 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * Furnace Tracker - multi-system chiptune tracker
 | 
						|
 * Copyright (C) 2021-2023 tildearrow and contributors
 | 
						|
 *
 | 
						|
 * 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.,
 | 
						|
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
						|
 */
 | 
						|
 | 
						|
#include "safeWriter.h"
 | 
						|
 | 
						|
#define WRITER_BUF_SIZE 16384
 | 
						|
 | 
						|
unsigned char* SafeWriter::getFinalBuf() {
 | 
						|
  return buf;
 | 
						|
}
 | 
						|
 | 
						|
void SafeWriter::checkSize(size_t amount) {
 | 
						|
  while ((curSeek+amount)>=bufLen) {
 | 
						|
    unsigned char* newBuf=new unsigned char[bufLen+WRITER_BUF_SIZE];
 | 
						|
    memcpy(newBuf,buf,bufLen);
 | 
						|
    delete[] buf;
 | 
						|
    buf=newBuf;
 | 
						|
    bufLen+=WRITER_BUF_SIZE;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
bool SafeWriter::seek(ssize_t where, int whence) {
 | 
						|
  ssize_t supposed;
 | 
						|
  switch (whence) {
 | 
						|
    case SEEK_SET:
 | 
						|
      supposed=where;
 | 
						|
      break;
 | 
						|
    case SEEK_CUR:
 | 
						|
      supposed=curSeek+where;
 | 
						|
      break;
 | 
						|
    case SEEK_END:
 | 
						|
      supposed=len+where;
 | 
						|
      break;
 | 
						|
    default:
 | 
						|
      return false;
 | 
						|
  }
 | 
						|
  if (supposed<0) supposed=0;
 | 
						|
  if (supposed>(ssize_t)len) supposed=len;
 | 
						|
  curSeek=supposed;
 | 
						|
  return true;
 | 
						|
}
 | 
						|
 | 
						|
size_t SafeWriter::tell() {
 | 
						|
  return curSeek;
 | 
						|
}
 | 
						|
 | 
						|
size_t SafeWriter::size() {
 | 
						|
  return len;
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::write(const void* what, size_t count) {
 | 
						|
  if (!operative) return 0;
 | 
						|
  checkSize(count);
 | 
						|
  memcpy(buf+curSeek,what,count);
 | 
						|
  curSeek+=count;
 | 
						|
  if (curSeek>len) len=curSeek;
 | 
						|
  return count;
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeC(signed char val) {
 | 
						|
  return write(&val,1);
 | 
						|
}
 | 
						|
 | 
						|
#ifdef TA_BIG_ENDIAN
 | 
						|
int SafeWriter::writeS_BE(short val) {
 | 
						|
  return write(&val,2);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeS(short val) {
 | 
						|
  unsigned char bytes[2]{(unsigned char)((val>>8)&0xff), (unsigned char)(val&0xff)};
 | 
						|
  return write(bytes,2);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeI(int val) {
 | 
						|
  unsigned char bytes[4];
 | 
						|
  bytes[0]=((unsigned int)val)&0xff;
 | 
						|
  bytes[1]=(((unsigned int)val)>>8)&0xff;
 | 
						|
  bytes[2]=(((unsigned int)val)>>16)&0xff;
 | 
						|
  bytes[3]=(((unsigned int)val)>>24)&0xff;
 | 
						|
  return write(bytes,4);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeL(int64_t val) {
 | 
						|
  unsigned char bytes[8];
 | 
						|
  bytes[0]=((uint64_t)val)&0xff;
 | 
						|
  bytes[1]=(((uint64_t)val)>>8)&0xff;
 | 
						|
  bytes[2]=(((uint64_t)val)>>16)&0xff;
 | 
						|
  bytes[3]=(((uint64_t)val)>>24)&0xff;
 | 
						|
  bytes[4]=(((uint64_t)val)>>32)&0xff;
 | 
						|
  bytes[5]=(((uint64_t)val)>>40)&0xff;
 | 
						|
  bytes[6]=(((uint64_t)val)>>48)&0xff;
 | 
						|
  bytes[7]=(((uint64_t)val)>>56)&0xff;
 | 
						|
  return write(bytes,8);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeF(float val) {
 | 
						|
  unsigned char bytes[4];
 | 
						|
  bytes[0]=((unsigned char*)(&val))[3];
 | 
						|
  bytes[1]=((unsigned char*)(&val))[2];
 | 
						|
  bytes[2]=((unsigned char*)(&val))[1];
 | 
						|
  bytes[3]=((unsigned char*)(&val))[0];
 | 
						|
  return write(bytes,4);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeD(double val) {
 | 
						|
  unsigned char bytes[8];
 | 
						|
  bytes[0]=((unsigned char*)(&val))[7];
 | 
						|
  bytes[1]=((unsigned char*)(&val))[6];
 | 
						|
  bytes[2]=((unsigned char*)(&val))[5];
 | 
						|
  bytes[3]=((unsigned char*)(&val))[4];
 | 
						|
  bytes[4]=((unsigned char*)(&val))[3];
 | 
						|
  bytes[5]=((unsigned char*)(&val))[2];
 | 
						|
  bytes[6]=((unsigned char*)(&val))[1];
 | 
						|
  bytes[7]=((unsigned char*)(&val))[0];
 | 
						|
  return write(bytes,8);
 | 
						|
}
 | 
						|
#else
 | 
						|
int SafeWriter::writeS(short val) {
 | 
						|
  return write(&val,2);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeS_BE(short val) {
 | 
						|
  unsigned char bytes[2]{(unsigned char)((val>>8)&0xff), (unsigned char)(val&0xff)};
 | 
						|
  return write(bytes,2);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeI(int val) {
 | 
						|
  return write(&val,4);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeI_BE(int val) {
 | 
						|
  unsigned char bytes[4] {
 | 
						|
    (unsigned char)((val>>24)&0xff),
 | 
						|
    (unsigned char)((val>>16)&0xff),
 | 
						|
    (unsigned char)((val>>8)&0xff),
 | 
						|
    (unsigned char)(val&0xff)
 | 
						|
  };
 | 
						|
  return write(bytes,4);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeL(int64_t val) {
 | 
						|
  return write(&val,8);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeF(float val) {
 | 
						|
  return write(&val,4);
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeD(double val) {
 | 
						|
  return write(&val,8);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
int SafeWriter::writeWString(WString val, bool pascal) {
 | 
						|
  if (pascal) {
 | 
						|
    writeS((unsigned short)val.size());
 | 
						|
    for (wchar_t& i: val) {
 | 
						|
      writeS(i);
 | 
						|
    }
 | 
						|
    return 2+val.size()*2;
 | 
						|
  } else {
 | 
						|
    for (wchar_t& i: val) {
 | 
						|
      writeS(i);
 | 
						|
    }
 | 
						|
    writeS(0);
 | 
						|
    return 2+val.size()*2;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeText(String val) {
 | 
						|
  return write(val.c_str(),val.size());
 | 
						|
}
 | 
						|
 | 
						|
int SafeWriter::writeString(String val, bool pascal) {
 | 
						|
  if (pascal) {
 | 
						|
    writeC((unsigned char)val.size());
 | 
						|
    return write(val.c_str(),val.size())+1;
 | 
						|
  } else {
 | 
						|
    return write(val.c_str(),val.size()+1);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void SafeWriter::init() {
 | 
						|
  if (operative) return;
 | 
						|
  buf=new unsigned char[WRITER_BUF_SIZE];
 | 
						|
  bufLen=WRITER_BUF_SIZE;
 | 
						|
  len=0;
 | 
						|
  curSeek=0;
 | 
						|
  operative=true;
 | 
						|
}
 | 
						|
 | 
						|
SafeReader* SafeWriter::toReader() {
 | 
						|
  return new SafeReader(buf,len);
 | 
						|
}
 | 
						|
 | 
						|
void SafeWriter::finish() {
 | 
						|
  if (!operative) return;
 | 
						|
  delete[] buf;
 | 
						|
  buf=NULL;
 | 
						|
  operative=false;
 | 
						|
}
 |