diff -r 1af5c1be89f8 -r 92d87f2e53c2 tools/elf4rom/src/outputfile.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/elf4rom/src/outputfile.cpp Fri Jan 15 09:07:44 2010 +0000 @@ -0,0 +1,125 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 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 Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "outputfile.h" + +static const size_t NumReservedFileFragments = 100; + +OutputFile::OutputFile(PathName aFileName) : + iFileName(aFileName), iOpened(false), iFd(-1), iCurrentOffset(0) +{ + assert(iFileName.size() != 0); + // reserve space for file fragments + iFileFragments.reserve(NumReservedFileFragments); +} + +OutputFile::~OutputFile(){ + iFileFragments.clear(); + if (iOpened) + Close(); +} + + +void OutputFile::Close(){ + if (iOpened) { + close(iFd); + iOpened = false; + } +} + +void OutputFile::Flush(){ + if (!iOpened) + Open(); + if (iFileFragments.size() > 0) { + FragmentList::iterator aFrag = iFileFragments.begin(); + FragmentList::iterator end = iFileFragments.end(); + while (aFrag != end) { + aFrag->Write(this); + aFrag++; + } + iFileFragments.clear(); + } +} + +void OutputFile::Dump(){ + Flush(); + Close(); +} + +const FileFragment & OutputFile::GetFileFragment(FileFragmentOwner * aOwner){ + size_t aSize = aOwner->Size(); + FileFragment aFragment(iCurrentOffset, aSize, aOwner); + iFileFragments.push_back(aFragment); + iCurrentOffset += ALIGN4(aSize); + return iFileFragments.back(); +} + +void OutputFile::Open(){ + if (!iOpened) { + if ((iFd = open(iFileName.c_str(), O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) { + char msg[1000]; + sprintf(msg, "Output file %s", iFileName.c_str()); + perror(msg); + exit(EXIT_FAILURE); + } + iOpened = true; + } +} + +void OutputFile::Write(size_t aOffset, size_t aSize, char * aData){ + assert(((aSize==0) && (aData==NULL)) || ((aSize>0) && (aData!=NULL))); + if (aSize == 0) return; + char msg[1000]; +#ifndef USE_PWRITE + if (lseek(iFd, aOffset, SEEK_SET) != (int)aOffset) { + sprintf(msg, "Failed to seek to offset %d in output file %s", aOffset, iFileName.c_str()); + goto error; + } + for (size_t n = 0; n < aSize;) { + if ((int)(n += write(iFd, aData+n, aSize - n)) == -1) { + sprintf(msg, "Failed to write to output file %s", iFileName.c_str()); + goto error; + } + } +#else + for (size_t n = 0; n < aSize;) { + if ((n += pwrite(iFd, aData+n, aSize - n, aOffset + n)) == -1) { + sprintf(msg, "Failed to write to output file %s", iFileName.c_str()); + goto error; + } + } +#endif + return; + +error: + perror(msg); +// should we close the file and delete it?? +#ifdef DELETE_OUTPUT_ON_ERROR + Close(); + unlink(iFileName); +#endif + exit(EXIT_FAILURE); +}