bool XMLConversion::SetupReader() { if(_reader) return true; //do not need to make a new reader //setup libxml2 for use in a potentially multithreaded //environment xmlInitParser(); //If the inputstream is not at the start (probably arising in fastsearch), //save its position and rewind so that the reader initialization is ok. //(Getting the requested object is handled in ReadXML(), when the format is known.) _requestedpos = GetInStream()->tellg(); if(_requestedpos < 0) _requestedpos = 0; if(_requestedpos) GetInStream()->seekg(0); //Set up a parser from an input stream _reader = xmlReaderForIO( ReadStream, //xmlInputReadCallback (static member function) NULL,//xmlInputCloseCallback (static member function) this, //context "", //URL NULL, //encoding 0); //options if (_reader == NULL) { cerr << "Cannot set up libxml2 reader" << endl; return false; } //A new reader immediately reads 4 bytes (presumably to determine //the encoding). _lastpos = GetInStream()->tellg(); return true; }
HRESULT CCoderMixer2ST::GetInStream( ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 streamIndex, ISequentialInStream **inStreamRes) { CMyComPtr<ISequentialInStream> seqInStream; int i; for(i = 0; i < _bindInfo.InStreams.Size(); i++) if (_bindInfo.InStreams[i] == streamIndex) { seqInStream = inStreams[i]; *inStreamRes = seqInStream.Detach(); return S_OK; } int binderIndex = _bindInfo.FindBinderForInStream(streamIndex); if (binderIndex < 0) return E_INVALIDARG; UInt32 coderIndex, coderStreamIndex; _bindInfo.FindOutStream(_bindInfo.BindPairs[binderIndex].OutIndex, coderIndex, coderStreamIndex); CCoderInfo &coder = _coders[coderIndex]; if (!coder.Coder) return E_NOTIMPL; coder.Coder.QueryInterface(IID_ISequentialInStream, &seqInStream); if (!seqInStream) return E_NOTIMPL; UInt32 startIndex = _bindInfo.GetCoderInStreamIndex(coderIndex); CMyComPtr<ICompressSetInStream> setInStream; if (!coder.Coder) return E_NOTIMPL; coder.Coder.QueryInterface(IID_ICompressSetInStream, &setInStream); if (!setInStream) return E_NOTIMPL; if (coder.NumInStreams > 1) return E_NOTIMPL; for (i = 0; i < (int)coder.NumInStreams; i++) { CMyComPtr<ISequentialInStream> seqInStream2; RINOK(GetInStream(inStreams, inSizes, startIndex + i, &seqInStream2)); RINOK(setInStream->SetInStream(seqInStream2)); } *inStreamRes = seqInStream.Detach(); return S_OK; }
bool XMLConversion::ReadXML(XMLBaseFormat* pFormat, OBBase* pOb) { if(_requestedpos) { //The initial stream position was not at the start, probably because of fastsearch //Read and discard the first object to synchronize the reader, //then continue getting the requested object. //Assumes the objects are all at the same level in the DOM tree. SetOneObjectOnly(); //probably already set streampos SavedReqestedPos = _requestedpos; _requestedpos=0;//don't do this again ReadXML(pFormat,pOb); GetInStream()->seekg(SavedReqestedPos); } //**Parse int result=1; while(GetInStream()->good() && (_SkipNextRead || (result=xmlTextReaderRead(_reader))==1)) //read may not be called { _SkipNextRead=false; if(_LookingForNamespace) { const xmlChar* puri = xmlTextReaderConstNamespaceUri(_reader); if(puri) { string uri((const char*)puri); //Look up appropriate format class from the namespace URI NsMapType::iterator nsiter; nsiter = Namespaces().find(uri); if(nsiter!=Namespaces().end()) { XMLBaseFormat* pNewFormat = nsiter->second; //Must have same target, e.g. OBMol, as current format if(pNewFormat->GetType() == pFormat->GetType()) { _LookingForNamespace=false; _SkipNextRead=true; SetInFormat(pNewFormat); pNewFormat->ReadMolecule(pOb,this); return true; } } } } const xmlChar* pname = xmlTextReaderConstLocalName(_reader); int typ = xmlTextReaderNodeType(_reader); if(typ==XML_READER_TYPE_SIGNIFICANT_WHITESPACE || !pname) continue; //Text nodes handled in format class string ElName((const char*)pname); //Pass the node on to the appropriate format class bool ret; if(typ==XML_READER_TYPE_ELEMENT) ret= pFormat->DoElement(ElName); else if(typ==XML_READER_TYPE_END_ELEMENT) ret= pFormat->EndElement(ElName); else continue; _lastpos = GetInStream()->tellg(); if(!ret) //derived format callback has stopped processing by returning false; //leave reader intact so it can be continued to be used. if(!IsOption("n",OBConversion::INOPTIONS)) { _LookingForNamespace = true; return true; } } if(result==-1) { xmlError* perr = xmlGetLastError(); if(perr && perr->level!=XML_ERR_NONE) { obErrorLog.ThrowError("XML Parser " + GetInFilename(), perr->message, obError); } xmlResetError(perr); GetInStream()->setstate(ios::eofbit); return false; } return GetInStream()->good() && result!=0; }
STDMETHODIMP CCoderMixer2ST::Code(ISequentialInStream **inStreams, const UInt64 **inSizes, UInt32 numInStreams, ISequentialOutStream **outStreams, const UInt64 **outSizes, UInt32 numOutStreams, ICompressProgressInfo *progress) { if (numInStreams != (UInt32)_bindInfo.InStreams.Size() || numOutStreams != (UInt32)_bindInfo.OutStreams.Size()) return E_INVALIDARG; // Find main coder int _mainCoderIndex = -1; int i; for (i = 0; i < _coders.Size(); i++) if (_coders[i].IsMain) { _mainCoderIndex = i; break; } if (_mainCoderIndex < 0) for (i = 0; i < _coders.Size(); i++) if (_coders[i].NumInStreams > 1) { if (_mainCoderIndex >= 0) return E_NOTIMPL; _mainCoderIndex = i; } if (_mainCoderIndex < 0) _mainCoderIndex = 0; // _mainCoderIndex = 0; // _mainCoderIndex = _coders.Size() - 1; CCoderInfo &mainCoder = _coders[_mainCoderIndex]; CObjectVector< CMyComPtr<ISequentialInStream> > seqInStreams; CObjectVector< CMyComPtr<ISequentialOutStream> > seqOutStreams; UInt32 startInIndex = _bindInfo.GetCoderInStreamIndex(_mainCoderIndex); UInt32 startOutIndex = _bindInfo.GetCoderOutStreamIndex(_mainCoderIndex); for (i = 0; i < (int)mainCoder.NumInStreams; i++) { CMyComPtr<ISequentialInStream> seqInStream; RINOK(GetInStream(inStreams, inSizes, startInIndex + i, &seqInStream)); seqInStreams.Add(seqInStream); } for (i = 0; i < (int)mainCoder.NumOutStreams; i++) { CMyComPtr<ISequentialOutStream> seqOutStream; RINOK(GetOutStream(outStreams, outSizes, startOutIndex + i, &seqOutStream)); seqOutStreams.Add(seqOutStream); } CRecordVector< ISequentialInStream * > seqInStreamsSpec; CRecordVector< ISequentialOutStream * > seqOutStreamsSpec; for (i = 0; i < (int)mainCoder.NumInStreams; i++) seqInStreamsSpec.Add(seqInStreams[i]); for (i = 0; i < (int)mainCoder.NumOutStreams; i++) seqOutStreamsSpec.Add(seqOutStreams[i]); for (i = 0; i < _coders.Size(); i++) { if (i == _mainCoderIndex) continue; CCoderInfo &coder = _coders[i]; CMyComPtr<ICompressSetOutStreamSize> setOutStreamSize; coder.Coder.QueryInterface(IID_ICompressSetOutStreamSize, &setOutStreamSize); if (setOutStreamSize) { RINOK(setOutStreamSize->SetOutStreamSize(coder.OutSizePointers[0])); } } if (mainCoder.Coder) { RINOK(mainCoder.Coder->Code( seqInStreamsSpec[0], seqOutStreamsSpec[0], mainCoder.InSizePointers[0], mainCoder.OutSizePointers[0], progress)); } else { RINOK(mainCoder.Coder2->Code( &seqInStreamsSpec.Front(), &mainCoder.InSizePointers.Front(), mainCoder.NumInStreams, &seqOutStreamsSpec.Front(), &mainCoder.OutSizePointers.Front(), mainCoder.NumOutStreams, progress)); } CMyComPtr<IOutStreamFlush> flush; seqOutStreams.Front().QueryInterface(IID_IOutStreamFlush, &flush); if (flush) return flush->Flush(); return S_OK; }