Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13994311
D12073.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
D12073.id.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Thu, Oct 24, 5:17 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6715003
Default Alt Text
D12073.id.diff (5 KB)
Attached To
Mode
D12073: Stream chunks when sending chunked files
Attached
Detach File
Event Timeline
Log In to Comment