aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_external/3rdparty/aws-sdk-php/Aws/S3/Sync/ChangedFilesIterator.php
blob: 3cf309df90122e7741a8e0413f29b6ddeafaacda (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?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;

use Aws\S3\S3Client;

/**
 * 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((string) $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)
    {
        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((string) $value);
            if ($filename == $key) {
                return $data;
            }
            $this->cache[$filename] = $data;
            $it->next();
        }

        return false;
    }
}