nextcloud/apps/files_external/3rdparty/aws-sdk-php/Aws/S3/Sync/ChangedFilesIterator.php

126 lines
3.8 KiB
PHP

<?php
/**
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
namespace Aws\S3\Sync;
/**
* Iterator used to filter an internal iterator to only yield files that do not exist in the target iterator or files
* that have changed
*/
class ChangedFilesIterator extends \FilterIterator
{
/** @var \Iterator */
protected $sourceIterator;
/** @var \Iterator */
protected $targetIterator;
/** @var FilenameConverterInterface */
protected $sourceConverter;
/** @var FilenameConverterInterface */
protected $targetConverter;
/** @var array Previously loaded data */
protected $cache = array();
/**
* @param \Iterator $sourceIterator Iterator to wrap and filter
* @param \Iterator $targetIterator Iterator used to compare against the source iterator
* @param FilenameConverterInterface $sourceConverter Key converter to convert source to target keys
* @param FilenameConverterInterface $targetConverter Key converter to convert target to source keys
*/
public function __construct(
\Iterator $sourceIterator,
\Iterator $targetIterator,
FilenameConverterInterface $sourceConverter,
FilenameConverterInterface $targetConverter
) {
$this->targetIterator = $targetIterator;
$this->sourceConverter = $sourceConverter;
$this->targetConverter = $targetConverter;
parent::__construct($sourceIterator);
}
public function accept()
{
$current = $this->current();
$key = $this->sourceConverter->convert($this->normalize($current));
if (!($data = $this->getTargetData($key))) {
return true;
}
// Ensure the Content-Length matches and it hasn't been modified since the mtime
return $current->getSize() != $data[0] || $current->getMTime() > $data[1];
}
/**
* Returns an array of the files from the target iterator that were not found in the source iterator
*
* @return array
*/
public function getUnmatched()
{
return array_keys($this->cache);
}
/**
* Get key information from the target iterator for a particular filename
*
* @param string $key Target iterator filename
*
* @return array|bool Returns an array of data, or false if the key is not in the iterator
*/
protected function getTargetData($key)
{
$key = $this->cleanKey($key);
if (isset($this->cache[$key])) {
$result = $this->cache[$key];
unset($this->cache[$key]);
return $result;
}
$it = $this->targetIterator;
while ($it->valid()) {
$value = $it->current();
$data = array($value->getSize(), $value->getMTime());
$filename = $this->targetConverter->convert($this->normalize($value));
$filename = $this->cleanKey($filename);
if ($filename == $key) {
return $data;
}
$this->cache[$filename] = $data;
$it->next();
}
return false;
}
private function normalize($current)
{
return $current->getRealPath() ?: (string) $current;
}
private function cleanKey($key)
{
return ltrim($key, '/');
}
}