/*------------------------------------------------------------------------------ -- This file is a part of the SocExplorer Software -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS -- -- 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 -------------------------------------------------------------------------------*/ /*-- Author : Alexis Jeandet -- Mail : alexis.jeandet@member.fsf.org ----------------------------------------------------------------------------*/ #include "srecfile.h" #include #include "binaryfile.h" srecFile::srecFile() { } srecFile::srecFile(const QString &File) { openFile(File); } srecFile::srecFile(const QStringList &Files) { openFiles(Files); } srecFile::~srecFile() { } bool srecFile::openFile(const QString &File) { return openFiles(QStringList()<p_isSrec=true; this->p_isSrec &= isSREC(Files.at(i)); this->p_files.append(new QFile(Files.at(i))); this->p_files.at(i)->open(QIODevice::ReadOnly); parseFile(this->p_files.at(i)); } return true; } bool srecFile::isopened() { bool opened = true; for(int i=0;ip_files.count();i++) { opened &= p_files.at(i)->isOpen(); } return opened; } int srecFile::closeFile() { for(int i=0;i srecFile::getFragments() { return p_fragments; } bool srecFile::toSrec(QList fragments, const QString &File) { QString line; QFile file(File); file.open(QIODevice::WriteOnly); if(file.isOpen()) { QTextStream stream( &file ); //First build header stream << buildRecord(0,0,File.toStdString().c_str(),File.count()); for(int i=0;isize));j+=16) { stream << buildRecord(3,fragment->address+j,fragment->data+j,16); } int rem = fragment->size % 16; if(rem) { stream << buildRecord(3,fragment->address+fragment->size-rem,fragment->data+fragment->size-rem,rem); } stream << buildRecord(7,fragment->address,NULL,0); } file.close(); return true; } return false; } bool srecFile::toSrec(const QString &File) { return toSrec(p_fragments,File); } bool srecFile::toBinary(const QString &File) { return binaryFile::toBinary(p_fragments,File); } int srecFile::lineCount() { return p_lineCount; } int srecFile::getFragmentsCount() { return p_fragments.count(); } int srecFile::getFragmentAddress(int index) { if((index < p_fragments.count()) && (index>=0)) { return p_fragments.at(index)->address; } return 0; } int srecFile::getFragmentSize(int index) { if((index < p_fragments.count()) && (index>=0)) { return p_fragments.at(index)->size; } return 0; } codeFragment *srecFile::getFragment(int index) { if((index < p_fragments.count()) && (index>=0)) { return p_fragments.at(index); } return NULL; } QString srecFile::getFragmentHeader(int index) { if((index < p_fragments.count()) && (index>=0)) { return p_fragments.at(index)->header; } return ""; } bool srecFile::getFragmentData(int index, char **buffer) { if((index < p_fragments.count()) && (index>=0)) { *buffer = (char *)this->p_fragments.at(index)->data; return true; } return false; } bool srecFile::isSREC() { return p_isSrec & isopened(); } bool srecFile::isSREC(const QString &File) { QFile file(File); file.open(QIODevice::ReadOnly); if(file.isOpen()) { file.seek(0); QString line=file.readLine(); file.close(); return ((line.at(0)=='S')&&(line.at(1)=='0')); } return false; } void srecFile::parseFile(QFile *file) { if(file->isOpen()) { this->p_lineCount = 0; file->seek(0); codeFragment* fragment=NULL; char* data; quint64 size=0; quint64 address=-1; QString header; while (!file->atEnd()) { QString line = file->readLine(); p_lineCount++; int rectype = parseLine(line,&address,&data,&size); if(rectype==0) { header.clear(); header.append(data); fragment = new codeFragment(data,size,address); fragment->header = header; p_fragments.append(fragment); } else { if((rectype>=1) && (rectype<=3)) { bool merged = false; //Could I merge it with an other fragment? // TODO should make merging optionnal for(int i=0;iaddress+frag->size)==address) && (merged==false) && (size!=0)) { char* mergedData=(char*)malloc(size+frag->size); memcpy(mergedData,frag->data,frag->size); memcpy(mergedData+frag->size,data,size); free(frag->data); free(data); frag->data = mergedData; frag->size = frag->size+size; merged = true; } } if(!merged) { fragment = new codeFragment(data,size,address); fragment->header = header; p_fragments.append(fragment); } } else { } } } } } int srecFile::parseLine(const QString &record, quint64 *address, char **data, quint64 *size) { #define newData (*data) #define newAddress (*address) #define newSize (*size) int recType = -1; if((record.count()>4) && checkSum(record)) { if(record.at(0)=='S') { recType = record.at(1).toLatin1() & 0x0F; //Header type if(recType==0) { newAddress = record.mid(4,4).toInt(0,16); newSize = record.mid(2,2).toInt(0,16) - 3; if(newSize>0) { newData=(char*)malloc(newSize+1); for(int i=0;i<(int)newSize;i++) { newData[i] = ((char)record.mid((2*i)+8,2).toInt(0,16)); } newData[newSize] = '\0'; // force string end for header } } //2 address byte record type if((recType==1) || (recType==5) || (recType==9)) { newAddress = record.mid(4,4).toInt(0,16); newSize = record.mid(2,2).toInt(0,16) - 3; if(newSize>0) { newData=(char*)malloc(newSize); for(int i=0;i<(int)newSize;i++) { newData[i] = ((char)record.mid((2*i)+8,2).toInt(0,16)); } } } //3 address byte record type if((recType==2) || (recType==6) || (recType==8)) { newAddress = record.mid(4,6).toInt(0,16); newSize = record.mid(2,2).toInt(0,16) - 4; if(newSize>0) { newData=(char*)malloc(newSize); for(int i=0;i<(int)newSize;i++) { newData[i] = ((char)record.mid((2*i)+10,2).toInt(0,16)); } } } //4 address byte record type if((recType==3) || (recType==7)) { newAddress = record.mid(4,8).toInt(0,16); newSize = record.mid(2,2).toInt(0,16) - 5; if(newSize>0) { newData=(char*)malloc(newSize); for(int i=0;i<(int)newSize;i++) { newData[i] = ((char)record.mid((2*i)+12,2).toInt(0,16)); } } } } } return recType; } char srecFile::lineCheckSum(const QString &line) { char sum=0; QString localLine = line; bool ok; if(localLine.at(0)=='S') // then should skip the first two digits { localLine.remove(0,2); } for(int i=0;i=0) && (recType<=9)) { record.append("S"); record.append(QString::number(recType)); //2 address byte record type if((recType==0) || (recType==1) || (recType==5) || (recType==9)) { record.append(QString("%1").arg(3+size,2,16).replace(' ','0')); record.append(QString("%1").arg(address,4,16).replace(' ','0')); } //3 address byte record type if((recType==2) || (recType==6) || (recType==8)) { record.append(QString("%1").arg(4+size,2,16).replace(' ','0')); record.append(QString("%1").arg(address,6,16).replace(' ','0')); } //4 address byte record type if((recType==3) || (recType==7)) { record.append(QString("%1").arg(5+size,2,16).replace(' ','0')); record.append(QString("%1").arg(address,8,16).replace(' ','0')); } for(int i=0; i