/***************************************************************************
 *   Copyright (C) 2005 by Juergen Thies                                   *
 *   layout@juergenthies.de                                                *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "filewrite.h"



fileWrite::fileWrite(QString filename)
 : QFile(filename)
{
bufferPos=0;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
compress=false;
if (filename.right(2)=="gz") {
	compress=true;
	//printf("compress\n");
	}
}


fileWrite::~fileWrite()
{
}

bool fileWrite::open(){
bool end=QFile::open(QIODevice::WriteOnly );
if (!end) {
	if (compress) compressinit=false;
	}
return end;
}

void fileWrite::close(){
writeBuffer();
if (compress) {
	int r;
	do {
	zlib.next_out= (quint8 *)&zlibBuf[0];
	zlib.avail_out=16*2048;
	r=deflate(&zlib,Z_FINISH); 
	writeData((char *)&zlibBuf[0],16*2048-zlib.avail_out);
	//printf("end wrote %d\n",16*2048-zlib.avail_out);
	} while (r==Z_FINISH);
	deflateEnd(&zlib);
	//writeData((char *)&zlibBuf[0],16*2048-zlib.avail_out);
	}
QFile::close();
}

void fileWrite::writeBuffer(){
if (bufferPos==0) return;
if (!compress){
	int i=writeData((char *)&buffer[0],bufferPos);
	int start=i;
	while (i!=bufferPos){
	int i=writeData((char *)&buffer[start],bufferPos-start);
	start+=i;
	i=start;
	}
} else {
	if (!compressinit){
			zlib.next_in= (quint8 *)&buffer[0];
			zlib.next_out= (quint8 *)&zlibBuf[0];
			zlib.avail_in=0;
			zlib.avail_out=16*2048;
			zlib.zalloc=Z_NULL;
			zlib.zfree=Z_NULL;
			zlib.opaque=Z_NULL;
			deflateInit2(&zlib,Z_DEFAULT_COMPRESSION,Z_DEFLATED,MAX_WBITS +16,8,Z_DEFAULT_STRATEGY);
			//printf("init wrote %d\n",16*2048-zlib.avail_out);
			writeData((char *)&zlibBuf[0],16*2048-zlib.avail_out);
			//printf("decompress2 %d %d\n",zlib.avail_out,zlib.avail_in);
			compressinit=true;
	}
	zlib.next_in= (quint8 *)&buffer[0];
	zlib.avail_in=bufferPos;
	uint last=zlib.avail_in+1;
	while (zlib.avail_in>0){
		zlib.next_out= (quint8 *)&zlibBuf[0];
		zlib.avail_out=16*2048;
		if (zlib.avail_in<last) deflate(&zlib,Z_NO_FLUSH); 
		else deflate(&zlib,Z_SYNC_FLUSH); 
		last=zlib.avail_in;
		writeData((char *)&zlibBuf[0],16*2048-zlib.avail_out);
		//printf("wrote %d\n",16*2048-zlib.avail_out);
	}
	
	
}
bufferPos=0;
/*int newPos=0;
for (newPos=0;bufferPos<bufferRead;newPos++){
   buffer[newPos]=buffer[bufferPos];
   bufferPos++;	
 }
int i=read((char *)&buffer[newPos],bufferSize-newPos);
bufferRead=i+newPos;
if (i<(bufferSize-newPos)) lastBlock=true;
bufferPos=0;*/

}

void fileWrite::writeString(QString s, int size){
  if (bufferPos>256000-size)writeBuffer();
  const char *a=s.toAscii().constData();
  bufferPos--;
  for (int b=0;b<size;b++){buffer[++bufferPos]=*a++;}
  bufferPos++;
}

void fileWrite::writeUInt8(quint8 i){
//printf("wrote uint8 %d\n",i);
  if (bufferPos>256000-1)writeBuffer();
  quint8 *p;
  p = (quint8 *)&buffer[bufferPos];
  *p=i;
  bufferPos+=1;
}

void fileWrite::writeUInt16(quint16 i){
if (bufferPos>256000-2)writeBuffer();
if (noswap) {
	quint16 *p;
	p = (quint16 *)&buffer[bufferPos];
	*p=i;
    } else {
        register uchar *p = (uchar *)(&i);
	    buffer[bufferPos+1]=*p++;
	    buffer[bufferPos]=*p;
    }
bufferPos+=2;
}

void fileWrite::writeInt16(qint16 i){
if (bufferPos>256000-2)writeBuffer();
if (noswap) {
	qint16 *p;
	p = (qint16 *)&buffer[bufferPos];
	*p=i;
    } else {
        register uchar *p = (uchar *)(&i);
	    buffer[bufferPos+1]=*p++;
	    buffer[bufferPos]=*p;
    }
bufferPos+=2;
}



void fileWrite::writeInt32(qint32 i){
if (bufferPos>256000-2)writeBuffer();
if (noswap) {
	qint32 *p;
	p = (qint32 *)&buffer[bufferPos];
	*p=i;
    } else {
        register uchar *p = (uchar *)(&i);
	    buffer[bufferPos+3]=*p++;
            buffer[bufferPos+2]=*p++;
	    buffer[bufferPos+1]=*p++;
	    buffer[bufferPos]=*p;
    }
bufferPos+=4;
}

