//Write the file back out, with the changes bool BlueZip::Write(bool Store) { //TODO: Do not use a TempFile, send straight to the output char TempFileName[MAX_PATH]; File f; zList* z; zList** next = &Files; //where to insert the next zList int i, j; //global enumeration variables if ((Files == NULL) && (Pending == NULL)) { ErrMsg("Blank ZIP files not allowed"); return false; } //Always use a temporary file name (they may have the ZIP file on a floppy) f = FileOpenTemp(TempFileName); if (!FileValid(f)) { ErrMsg(Failed to open the temporary file); return false; } if (Files != NULL) { File Orig = FileOpenRead(FileName); if (!FileValid(Orig)) { ErrMsg("Failed to open the reading file"); return false; } const int BlockSize = 4096; char* Buffer = new char[BlockSize]; datCentral hLocal; for (z = Files; z != NULL; z = z->next) { if (!z->Delete) { //Remove any that have dropped out of the list *next = z; next = &z->next; //Perform a ZIP copy SeekBeg(Orig, z->data.Offset + z->FileDeltaPos); z->data.Offset = FilePos(f); u32 sig; FileRead(Orig, &sig, 4); Assert(sig == sigLocal); FileWrite(f, &sig, 4); hLocal.ReadLocal(Orig); hLocal.WriteLocal(f); i = hLocal.CompSize + hLocal.lFileName + hLocal.lExtra; while(i != 0) { j = min(i, BlockSize); FileRead(Orig, Buffer, j); FileWrite(f, Buffer, j); i -= j; } } } FileClose(Orig); delete[] Buffer; } while (Pending != NULL) { fList* fAdd = Pending; Pending = Pending->next; z = fAdd->ZipUp(f, Store); if (z == NULL) { ErrMsg("Failed to add the file"); } else { *next = z; next = &z->next; } delete fAdd; } //Write out the central header data.Count = 0; data.Offset = FilePos(f); for (z = Files; z != NULL; z = z->next, data.Count++) z->WriteCentral(f); data.Size = FilePos(f) - data.Offset; WriteEnd(f); FileClose(f); //Using a temp file if (!FileReplace(FileName, TempFileName)) { ErrMsg("Failed to copy the temporary file"); return false; } return true; }
//! Use Expat parser to parse an XML file bool mxflib::XMLParserParseFile(XML_Parser *pParser, mxflib::XMLParserHandlerPtr Hand, void *UserData, const char *filename, bool ParseNamespaces /*=false*/) { if(!Hand) { error("No handler defined in call to XMLParserParseFile()\n"); return false; } // Open the input file FileHandle InFile = FileOpenRead(filename); if(!FileValid(InFile)) { Hand->fatalError(UserData, "Couldn't open file %s\n", filename); return false; } // Build a new parser XML_Parser Parser = ParseNamespaces ? XML_ParserCreateNS(NULL, '|') : XML_ParserCreate(NULL); if(!Parser) { Hand->fatalError(UserData, "Could't create an expat XML parser\n"); FileClose(InFile); return false; } // Set the caller's parser pointer if requested if(pParser) *pParser = Parser; // Set the element handlers XML_SetElementHandler(Parser, Hand->startElement, Hand->endElement); // Set the user data XML_SetUserData(Parser, UserData); int Done = 0; do { const int BufferSize = 1024 * 64; UInt8 *Buffer = (UInt8*)XML_GetBuffer(Parser, BufferSize); int Bytes = (int)FileRead(InFile, Buffer, BufferSize); if(FileEof(InFile)) Done = -1; if (XML_ParseBuffer(Parser, Bytes, Done) == XML_STATUS_ERROR) { Hand->fatalError(UserData, "Parse error at line %d:\n%s\n", XML_GetCurrentLineNumber(Parser), XML_ErrorString(XML_GetErrorCode(Parser))); XML_ParserFree(Parser); FileClose(InFile); return false; } } while(!Done); // Free the parser XML_ParserFree(Parser); FileClose(InFile); return true; }