예제 #1
0
  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;
  }
예제 #2
0
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;
}
예제 #3
0
  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;
  }
예제 #4
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;
}