示例#1
0
    Analysis::Result::Ptr Detect(const Parameters::Accessor& params, DataLocation::Ptr input, const Module::DetectCallback& callback) const override
    {
      const Binary::Container::Ptr rawData = input->GetData();
      const std::size_t size = rawData->Size();
      Statistic::Self().Enqueue(size);
      if (size < MIN_MINIMAL_RAW_SIZE)
      {
        Dbg("Size is too small (%1%)", size);
        return Analysis::CreateUnmatchedResult(size);
      }

      const RawPluginParameters scanParams(params);
      const std::size_t minRawSize = scanParams.GetMinimalSize();

      const String currentPath = input->GetPath()->AsString();
      Dbg("Detecting modules in raw data at '%1%'", currentPath);
      const Log::ProgressCallback::Ptr progress = MakePtr<RawProgressCallback>(callback, static_cast<uint_t>(size), currentPath);
      const Module::DetectCallback& noProgressCallback = Module::CustomProgressDetectCallbackAdapter(callback);

      const ArchivePlugin::Iterator::Ptr availableArchives = ArchivePluginsEnumerator::Create()->Enumerate();
      const ArchivePlugin::Iterator::Ptr usedArchives = scanParams.GetDoubleAnalysis()
        ? MakePtr<DoubleAnalysisArchivePlugins>(availableArchives)
        : availableArchives;
      RawDetectionPlugins usedPlugins(params, PlayerPluginsEnumerator::Create()->Enumerate(), usedArchives, *this);

      ScanDataLocation::Ptr subLocation = MakePtr<ScanDataLocation>(input, Description->Id(), 0);

      while (subLocation->HasToScan(minRawSize))
      {
        const std::size_t offset = subLocation->GetOffset();
        progress->OnProgress(static_cast<uint_t>(offset));
        usedPlugins.SetOffset(offset);
        const Module::DetectCallback& curCallback = offset ? noProgressCallback : callback;
        const std::size_t bytesToSkip = usedPlugins.Detect(subLocation, curCallback);
        if (!subLocation.unique())
        {
          Dbg("Sublocation is captured. Duplicate.");
          subLocation = MakePtr<ScanDataLocation>(input, Description->Id(), offset);
        }
        subLocation->Move(std::max(bytesToSkip, SCAN_STEP));
      }
      return Analysis::CreateMatchedResult(size);
    }
示例#2
0
 DataLocation::Ptr Open(const Parameters::Accessor& /*params*/, DataLocation::Ptr location, const Analysis::Path& inPath) const override
 {
   const String& pathComp = inPath.GetIterator()->Get();
   std::size_t offset = 0;
   if (RawPath.GetIndex(pathComp, offset))
   {
     const Binary::Container::Ptr inData = location->GetData();
     const Binary::Container::Ptr subData = inData->GetSubcontainer(offset, inData->Size() - offset);
     return CreateNestedLocation(location, subData, Description->Id(), pathComp); 
   }
   return DataLocation::Ptr();
 }
示例#3
0
 Analysis::Result::Ptr DetectIn(LookaheadPluginsStorage<T>& container, DataLocation::Ptr input, const Module::DetectCallback& callback) const
 {
   const bool firstScan = 0 == Offset;
   const std::size_t maxSize = input->GetData()->Size();
   for (typename T::Iterator::Ptr iter = container.Enumerate(); iter->IsValid(); iter->Next())
   {
     Time::Timer timer;
     const typename T::Ptr plugin = iter->Get();
     const Analysis::Result::Ptr result = plugin->Detect(Params, input, callback);
     const String id = plugin->GetDescription()->Id();
     if (const std::size_t usedSize = result->GetMatchedDataSize())
     {
       Statistic::Self().AddAimed(*plugin, timer);
       Dbg("Detected %1% in %2% bytes at %3%.", id, usedSize, input->GetPath()->AsString());
       return result;
     }
     else
     {
       if (!firstScan)
       {
         Statistic::Self().AddMissed(*plugin, timer);
         timer = Time::Timer();
       }
       const std::size_t lookahead = result->GetLookaheadOffset();
       container.SetPluginLookahead(*plugin, id, lookahead);
       if (lookahead == maxSize)
       {
         Statistic::Self().AddAimed(*plugin, timer);
       }
       else
       {
         Statistic::Self().AddScanned(*plugin, timer);
       }
     }
   }
   const std::size_t minLookahead = container.GetMinimalPluginLookahead();
   return Analysis::CreateUnmatchedResult(minLookahead);
 }
示例#4
0
 virtual Analysis::Result::Ptr Detect(DataLocation::Ptr input, const Module::DetectCallback& callback) const
 {
   const Binary::Container::Ptr rawData = input->GetData();
   if (const Formats::Archived::Container::Ptr archive = Decoder->Decode(*rawData))
   {
     if (const uint_t count = archive->CountFiles())
     {
       ContainerDetectCallback detect(~std::size_t(0), Description->Id(), input, count, callback);
       archive->ExploreFiles(detect);
     }
     return Analysis::CreateMatchedResult(archive->Size());
   }
   return Analysis::CreateUnmatchedResult(Decoder->GetFormat(), rawData);
 }
示例#5
0
 virtual DataLocation::Ptr Open(const Parameters::Accessor& /*commonParams*/, DataLocation::Ptr location, const Analysis::Path& inPath) const
 {
   const Binary::Container::Ptr rawData = location->GetData();
   if (const Formats::Archived::Container::Ptr archive = Decoder->Decode(*rawData))
   {
     if (const Formats::Archived::File::Ptr fileToOpen = FindFile(*archive, inPath))
     {
       if (const Binary::Container::Ptr subData = fileToOpen->GetData())
       {
         return CreateNestedLocation(location, subData, Description->Id(), fileToOpen->GetName());
       }
     }
   }
   return DataLocation::Ptr();
 }
示例#6
0
文件: packed.cpp 项目: djdron/zxtune
 Analysis::Result::Ptr DetectModulesInArchive(const Parameters::Accessor& params, Plugin::Ptr plugin, const Formats::Packed::Decoder& decoder, 
   DataLocation::Ptr inputData, const Module::DetectCallback& callback)
 {
   const Binary::Container::Ptr rawData = inputData->GetData();
   if (Formats::Packed::Container::Ptr subData = decoder.Decode(*rawData))
   {
     const Module::CustomProgressDetectCallbackAdapter noProgressCallback(callback);
     const String subPlugin = plugin->Id();
     const String subPath = EncodeArchivePluginToPath(subPlugin);
     const DataLocation::Ptr subLocation = CreateNestedLocation(inputData, subData, subPlugin, subPath);
     Module::Detect(params, subLocation, noProgressCallback);
     return Analysis::CreateMatchedResult(subData->PackedSize());
   }
   const Binary::Format::Ptr format = decoder.GetFormat();
   return Analysis::CreateUnmatchedResult(format, rawData);
 }
示例#7
0
 DataLocation::Ptr OpenLocation(Parameters::Accessor::Ptr coreParams, Binary::Container::Ptr data, const String& subpath)
 {
   const ArchivePluginsEnumerator::Ptr usedPlugins = ArchivePluginsEnumerator::Create();
   DataLocation::Ptr resolvedLocation = boost::make_shared<UnresolvedLocation>(data);
   const Analysis::Path::Ptr sourcePath = Analysis::ParsePath(subpath, Text::MODULE_SUBPATH_DELIMITER[0]);
   for (Analysis::Path::Ptr unresolved = sourcePath; !unresolved->Empty(); unresolved = sourcePath->Extract(resolvedLocation->GetPath()->AsString()))
   {
     const String toResolve = unresolved->AsString();
     Dbg("Resolving '%1%'", toResolve);
     if (!(resolvedLocation = TryToOpenLocation(*usedPlugins, *coreParams, resolvedLocation, *unresolved)))
     {
       throw MakeFormattedError(THIS_LINE, translate("Failed to resolve subpath '%1%'."), subpath);
     }
   }
   Dbg("Resolved '%1%'", subpath);
   return resolvedLocation;
 }
示例#8
0
文件: packed.cpp 项目: djdron/zxtune
 DataLocation::Ptr OpenDataFromArchive(Plugin::Ptr plugin, const Formats::Packed::Decoder& decoder,
   DataLocation::Ptr inputData, const Analysis::Path& pathToOpen)
 {
   const String pathComponent = pathToOpen.GetIterator()->Get();
   if (!IsArchivePluginPathComponent(pathComponent))
   {
     return DataLocation::Ptr();
   }
   const String pluginId = DecodeArchivePluginFromPathComponent(pathComponent);
   if (pluginId != plugin->Id())
   {
     return DataLocation::Ptr();
   }
   const Binary::Container::Ptr rawData = inputData->GetData();
   if (Formats::Packed::Container::Ptr subData = decoder.Decode(*rawData))
   {
     return CreateNestedLocation(inputData, subData, pluginId, pathComponent);
   }
   return DataLocation::Ptr();
 }