Пример #1
0
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
  UInt64 endPos = 0;
  {
    RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
    RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
  }
  
  _phySizeDefined = true;
  
  bool utf8_OK = true;
  if (!_forceCodePage)
  {
    if (!utf8_OK)
      _curCodePage = k_DefaultCodePage;
  }

  for (;;)
  {
    CItemEx item;
    bool filled;
    RINOK(ReadItem2(stream, filled, item));
    if (!filled)
      break;

    _isArc = true;
    _items.Add(item);

    if (!_forceCodePage)
    {
      if (utf8_OK) utf8_OK = CheckUTF8(item.Name, item.NameCouldBeReduced);
      if (utf8_OK) utf8_OK = CheckUTF8(item.LinkName, item.LinkNameCouldBeReduced);
      if (utf8_OK) utf8_OK = CheckUTF8(item.User);
      if (utf8_OK) utf8_OK = CheckUTF8(item.Group);
    }
    
    RINOK(stream->Seek(item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize));
    if (_phySize > endPos)
    {
      _error = k_ErrorType_UnexpectedEnd;
      break;
    }
    /*
    if (_phySize == endPos)
    {
      _errorMessage = "There are no trailing zero-filled records";
      break;
    }
    */
    if (callback)
    {
      if (_items.Size() == 1)
      {
        RINOK(callback->SetTotal(NULL, &endPos));
      }
      if ((_items.Size() & 0x3FF) == 0)
      {
        UInt64 numFiles = _items.Size();
        RINOK(callback->SetCompleted(&numFiles, &_phySize));
      }
    }
  }

  if (!_forceCodePage)
  {
    if (!utf8_OK)
      _curCodePage = k_DefaultCodePage;
  }
  _openCodePage = _curCodePage;

  if (_items.Size() == 0)
  {
    if (_error != k_ErrorType_OK)
    {
      _isArc = false;
      return S_FALSE;
    }
    CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
    if (!callback)
      return S_FALSE;
    callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
    if (!openVolumeCallback)
      return S_FALSE;
    NCOM::CPropVariant prop;
    if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK)
      return S_FALSE;
    if (prop.vt != VT_BSTR)
      return S_FALSE;
    unsigned len = MyStringLen(prop.bstrVal);
    if (len < 4 || MyStringCompareNoCase(prop.bstrVal + len - 4, L".tar") != 0)
      return S_FALSE;
  }

  _isArc = true;
  return S_OK;
}
Пример #2
0
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
  UInt64 endPos = 0;
  {
    RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos));
    RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
  }
  
  _phySizeDefined = true;
  for (;;)
  {
    CItemEx item;
    bool filled;
    RINOK(ReadItem2(stream, filled, item));
    if (!filled)
      break;
    _items.Add(item);
    
    RINOK(stream->Seek(item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize));
    if (_phySize > endPos)
    {
      _errorMessage = kUnexpectedEnd;
      break;
    }
    /*
    if (_phySize == endPos)
    {
      _errorMessage = "There are no trailing zero-filled records";
      break;
    }
    */
    if (callback != NULL)
    {
      if (_items.Size() == 1)
      {
        RINOK(callback->SetTotal(NULL, &endPos));
      }
      if (_items.Size() % 100 == 0)
      {
        UInt64 numFiles = _items.Size();
        RINOK(callback->SetCompleted(&numFiles, &_phySize));
      }
    }
  }

  if (_items.Size() == 0)
  {
    CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
    if (!callback)
      return S_FALSE;
    callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
    if (!openVolumeCallback)
      return S_FALSE;
    NCOM::CPropVariant prop;
    if (openVolumeCallback->GetProperty(kpidName, &prop) != S_OK)
      return S_FALSE;
    if (prop.vt != VT_BSTR)
      return S_FALSE;
    UString baseName = prop.bstrVal;
    baseName = baseName.Right(4);
    if (baseName.CompareNoCase(L".tar") != 0)
      return S_FALSE;
  }
  return S_OK;
}