mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-01 00:43:02 +00:00
221 lines
5.1 KiB
C++
221 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_BE(int val) {
|
|
return write(&val,4);
|
|
}
|
|
|
|
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;
|
|
}
|