Page MenuHomePhabricator

D12073.diff
No OneTemporary

D12073.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1795,6 +1795,7 @@
'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php',
'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php',
'PhabricatorFileChunk' => 'applications/files/storage/PhabricatorFileChunk.php',
+ 'PhabricatorFileChunkIterator' => 'applications/files/engine/PhabricatorFileChunkIterator.php',
'PhabricatorFileChunkQuery' => 'applications/files/query/PhabricatorFileChunkQuery.php',
'PhabricatorFileCommentController' => 'applications/files/controller/PhabricatorFileCommentController.php',
'PhabricatorFileComposeController' => 'applications/files/controller/PhabricatorFileComposeController.php',
@@ -5096,6 +5097,10 @@
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
),
+ 'PhabricatorFileChunkIterator' => array(
+ 'Phobject',
+ 'Iterator',
+ ),
'PhabricatorFileChunkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorFileCommentController' => 'PhabricatorFileController',
'PhabricatorFileComposeController' => 'PhabricatorFileController',
diff --git a/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php b/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php
--- a/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php
+++ b/src/applications/files/engine/PhabricatorChunkedFileStorageEngine.php
@@ -177,4 +177,15 @@
return 32;
}
+ public function getFileDataIterator(PhabricatorFile $file, $begin, $end) {
+ $chunks = id(new PhabricatorFileChunkQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withChunkHandles(array($file->getStorageHandle()))
+ ->withByteRange($begin, $end)
+ ->needDataFiles(true)
+ ->execute();
+
+ return new PhabricatorFileChunkIterator($chunks, $begin, $end);
+ }
+
}
diff --git a/src/applications/files/engine/PhabricatorFileChunkIterator.php b/src/applications/files/engine/PhabricatorFileChunkIterator.php
new file mode 100644
--- /dev/null
+++ b/src/applications/files/engine/PhabricatorFileChunkIterator.php
@@ -0,0 +1,72 @@
+<?php
+
+final class PhabricatorFileChunkIterator
+ extends Phobject
+ implements Iterator {
+
+ private $chunks;
+ private $cursor;
+ private $begin;
+ private $end;
+ private $data;
+
+ public function __construct(array $chunks, $begin = null, $end = null) {
+ $chunks = msort($chunks, 'getByteStart');
+ $this->chunks = $chunks;
+
+ if ($begin !== null) {
+ foreach ($chunks as $key => $chunk) {
+ if ($chunk->getByteEnd() >= $begin) {
+ unset($chunks[$key]);
+ }
+ break;
+ }
+ $this->begin = $begin;
+ }
+
+ if ($end !== null) {
+ foreach ($chunks as $key => $chunk) {
+ if ($chunk->getByteStart() <= $end) {
+ unset($chunks[$key]);
+ }
+ }
+ $this->end = $end;
+ }
+ }
+
+ public function current() {
+ $chunk = head($this->chunks);
+ $data = $chunk->getDataFile()->loadFileData();
+
+ if ($this->end !== null) {
+ if ($chunk->getByteEnd() > $this->end) {
+ $data = substr($data, 0, ($this->end - $chunk->getByteStart()));
+ }
+ }
+
+ if ($this->begin !== null) {
+ if ($chunk->getByteStart() < $this->begin) {
+ $data = substr($data, ($this->begin - $chunk->getByteStart()));
+ }
+ }
+
+ return $data;
+ }
+
+ public function key() {
+ return head_key($this->chunks);
+ }
+
+ public function next() {
+ unset($this->chunks[$this->key()]);
+ }
+
+ public function rewind() {
+ return;
+ }
+
+ public function valid() {
+ return (count($this->chunks) > 0);
+ }
+
+}
diff --git a/src/applications/files/engine/PhabricatorFileStorageEngine.php b/src/applications/files/engine/PhabricatorFileStorageEngine.php
--- a/src/applications/files/engine/PhabricatorFileStorageEngine.php
+++ b/src/applications/files/engine/PhabricatorFileStorageEngine.php
@@ -290,5 +290,20 @@
return $engine->getChunkSize();
}
+ public function getFileDataIterator(PhabricatorFile $file, $begin, $end) {
+ // The default implementation is trivial and just loads the entire file
+ // upfront.
+ $data = $file->loadFileData();
+
+ if ($begin !== null && $end !== null) {
+ $data = substr($data, $begin, ($end - $begin));
+ } else if ($begin !== null) {
+ $data = substr($data, $begin);
+ } else if ($end !== null) {
+ $data = substr($data, 0, $end);
+ }
+
+ return array($data);
+ }
}
diff --git a/src/applications/files/storage/PhabricatorFile.php b/src/applications/files/storage/PhabricatorFile.php
--- a/src/applications/files/storage/PhabricatorFile.php
+++ b/src/applications/files/storage/PhabricatorFile.php
@@ -612,19 +612,8 @@
* @return Iterable Iterable object which emits requested data.
*/
public function getFileDataIterator($begin = null, $end = null) {
- // The default implementation is trivial and just loads the entire file
- // upfront.
- $data = $this->loadFileData();
-
- if ($begin !== null && $end !== null) {
- $data = substr($data, $begin, ($end - $begin));
- } else if ($begin !== null) {
- $data = substr($data, $begin);
- } else if ($end !== null) {
- $data = substr($data, 0, $end);
- }
-
- return array($data);
+ $engine = $this->instantiateStorageEngine();
+ return $engine->getFileDataIterator($this, $begin, $end);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 17, 3:23 AM (2 d, 14 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6715003
Default Alt Text
D12073.diff (5 KB)

Event Timeline