// - close the file bferr TBinFileBase::close(void) { if (platformFileIsOpen()) { // remove empty space from end of file truncate(fBinFileHeader.numrecords); // write new header flushHeader(); // close file platformCloseFile(); } return BFE_OK; } // TBinFileBase::close
//______________________________________________________________________________ void xml2guidovisitor::visitStart ( S_part& elt ) { partsummary ps; xml_tree_browser browser(&ps); browser.browse(*elt); smartlist<int>::ptr voices = ps.getVoices (); int targetStaff = 0xffff; // initialized to a value we'll unlikely encounter bool notesOnly = false; rational currentTimeSign (0,1); // browse the parts voice by voice: allows to describe voices that spans over several staves for (unsigned int i = 0; i < voices->size(); i++) { int targetVoice = (*voices)[i]; int mainstaff = ps.getMainStaff(targetVoice); if (targetStaff == mainstaff) { notesOnly = true; } else { notesOnly = false; targetStaff = mainstaff; fCurrentStaffIndex++; } Sguidoelement seq = guidoseq::create(); push (seq); Sguidoelement tag = guidotag::create("staff"); tag->add (guidoparam::create(fCurrentStaffIndex, false)); add (tag); flushHeader (fHeader); flushPartHeader (fPartHeaders[elt->getAttributeValue("id")]); xmlpart2guido pv(fGenerateComments, fGenerateStem, fGenerateBars); pv.generatePositions (fGeneratePositions); xml_tree_browser browser(&pv); pv.initialize(seq, targetStaff, fCurrentStaffIndex, targetVoice, notesOnly, currentTimeSign); browser.browse(*elt); pop(); currentTimeSign = pv.getTimeSign(); } }
// - create new DB file according to params set with setFileInfo bferr TBinFileBase::create(uInt32 aRecordsize, uInt32 aExtraHeadersize, void *aExtraHeaderP, bool aOverwrite) { bferr e; close(); // try to open e=open(aExtraHeadersize,NULL); // do not pass our new header data in case there is an old file already if (e==BFE_NOTFOUND || aOverwrite) { close(); // create new file if (!platformOpenFile(fFilename.c_str(),fopm_create)) return BFE_IOERR; // could not create for some reason // prepare header fBinFileHeader.idword=fIdWord; fBinFileHeader.version=fVersion; fBinFileHeader.headersize=sizeof(TBinFileHeader)+aExtraHeadersize; fBinFileHeader.recordsize=aRecordsize; fBinFileHeader.numrecords=0; fBinFileHeader.allocatedrecords=0; fBinFileHeader.uniquerecordid=0; fHeaderDirty = true; // - link in the new extra header buffer fExtraHeaderP = aExtraHeaderP; fExtraHeaderDirty = true; // make sure it gets written // write entire header e=flushHeader(); // opened with new version fFoundVersion = fVersion; } else if (e==BFE_OK) { // already exists close(); e=BFE_EXISTS; } return e; } // TBinFileBase::create
// - try to open existing DB file according to params set with setFileInfo bferr TBinFileBase::open(uInt32 aExtraHeadersize, void *aExtraHeaderP, TUpdateFunc aUpdateFunc) { // make sure it is closed first close(); // save extra header info fExtraHeaderSize=aExtraHeadersize; fExtraHeaderP=aExtraHeaderP; // try to open file for (binary) update if (!platformOpenFile(fFilename.c_str(),fopm_update)) return BFE_NOTFOUND; // read header fHeaderDirty=false; platformSeekFile(0); if (!platformReadFile(&fBinFileHeader,sizeof(fBinFileHeader))) { close(); return BFE_BADSTRUCT; } // check type and Version if (fBinFileHeader.idword!=fIdWord) { close(); return BFE_BADTYPE; } // remember the version we found when trying to open fFoundVersion = fBinFileHeader.version; // check need for upgrade if (fBinFileHeader.version!=fVersion) { // try to update file if update-func is provided if (aUpdateFunc) { // check if we can update (no data provided for update) uInt32 newrecordsize=aUpdateFunc(fFoundVersion,fVersion,NULL,NULL,0); if (newrecordsize) { // we can update from current to requested version // - allocate buffer for all records uInt32 numrecords = fBinFileHeader.numrecords; uInt32 oldrecordsize = fBinFileHeader.recordsize; void *oldrecords = malloc(numrecords * oldrecordsize); if (!oldrecords) return BFE_MEMORY; // - read all current records into memory (relative to old headersize) readRecord(0,oldrecords,numrecords); // Update header because extra header might have changed in size if (fExtraHeaderP && (fBinFileHeader.headersize!=sizeof(TBinFileHeader)+fExtraHeaderSize)) { // (extra) header has changed in size // - read old extra header (or part of it that will be retained in case it shrinks between versions) uInt32 oldEHdrSz = fBinFileHeader.headersize-sizeof(TBinFileHeader); platformSeekFile(sizeof(TBinFileHeader)); platformReadFile(fExtraHeaderP,oldEHdrSz<=fExtraHeaderSize ? oldEHdrSz : fExtraHeaderSize); // - adjust the overall header size fBinFileHeader.headersize = sizeof(TBinFileHeader)+fExtraHeaderSize; // - let the update function handle init of the extra header aUpdateFunc(fFoundVersion,fVersion,NULL,fExtraHeaderP,0); // - make sure new extra header gets written fExtraHeaderDirty = true; } // - modify header fields fBinFileHeader.version=fVersion; // update version fBinFileHeader.recordsize=newrecordsize; // update record size fHeaderDirty=true; // header must be updated // - write new header (to make sure file is at least as long as header+extraheader) flushHeader(); // - truncate the file (taking new extra header size into account already, in case it has changed) truncate(); // - now convert buffered records void *newrecord = malloc(newrecordsize); for (uInt32 i=0; i<numrecords; i++) { // call updatefunc to convert record if (aUpdateFunc(fFoundVersion,fVersion,(void *)((uInt8 *)oldrecords+i*oldrecordsize),newrecord,oldrecordsize)) { // save new record uInt32 newi; newRecord(newi,newrecord); } } // - forget buffers free(newrecord); free(oldrecords); // - flush new header flushHeader(); } else { // cannot update close(); return BFE_BADVERSION; } } else { // cannot update close(); return BFE_BADVERSION; } } // check record compatibility if (fExpectedRecordSize && fExpectedRecordSize!=fBinFileHeader.recordsize) { close(); return BFE_BADSTRUCT; } // check extra header compatibility if (fBinFileHeader.headersize<sizeof(TBinFileHeader)+fExtraHeaderSize) { close(); return BFE_BADSTRUCT; } // read extra header if (fExtraHeaderP && fExtraHeaderSize>0) { platformSeekFile(sizeof(TBinFileHeader)); platformReadFile(fExtraHeaderP,fExtraHeaderSize); fExtraHeaderDirty=false; } return BFE_OK; } // TBinFileBase::open