.htaccess
1 year ago
Sparse.php
1 year ago
SparseRegion.php
1 year ago
index.html
1 year ago
web.config
1 year ago
Sparse.php
138 lines
| 1 | <?php |
| 2 | /* |
| 3 | * |
| 4 | * JetBackup @ package |
| 5 | * Created By Idan Ben-Ezra |
| 6 | * |
| 7 | * Copyrights @ JetApps |
| 8 | * https://www.jetapps.com |
| 9 | * |
| 10 | **/ |
| 11 | namespace JetBackup\Archive\Header\Sparse; |
| 12 | |
| 13 | use JetBackup\Archive\Archive; |
| 14 | use JetBackup\Archive\Data\SetterGetter; |
| 15 | use JetBackup\Archive\Header\Header; |
| 16 | |
| 17 | class Sparse extends SetterGetter { |
| 18 | |
| 19 | const LENGTH_ATIME = 12; |
| 20 | const LENGTH_CTIME = 12; |
| 21 | const LENGTH_OFFSET = 12; |
| 22 | const LENGTH_LONGNAME = 4; |
| 23 | const LENGTH_PAD = 1; |
| 24 | const LENGTH_REGIONS = (SparseRegion::REGION_LENGTH * 4); |
| 25 | const LENGTH_EXTENDED = 1; |
| 26 | const LENGTH_REALSIZE = 12; |
| 27 | const LENGTH_PAD_END = 5; |
| 28 | const LENGTH_EXTENDED_REGIONS = (SparseRegion::REGION_LENGTH * 21); |
| 29 | const LENGTH_EXTENDED_PAD = 7; |
| 30 | |
| 31 | const OFFSET_ATIME = 0; |
| 32 | const OFFSET_CTIME = self::LENGTH_ATIME; |
| 33 | const OFFSET_OFFSET = self::LENGTH_ATIME + self::LENGTH_CTIME; |
| 34 | const OFFSET_LONGNAME = self::LENGTH_ATIME + self::LENGTH_CTIME + self::LENGTH_OFFSET; |
| 35 | const OFFSET_REGIONS = self::LENGTH_ATIME + self::LENGTH_CTIME + self::LENGTH_OFFSET + self::LENGTH_LONGNAME + |
| 36 | self::LENGTH_PAD; |
| 37 | const OFFSET_EXTENDED = self::LENGTH_ATIME + self::LENGTH_CTIME + self::LENGTH_OFFSET + self::LENGTH_LONGNAME + |
| 38 | self::LENGTH_PAD + self::LENGTH_REGIONS; |
| 39 | const OFFSET_REALSIZE = self::LENGTH_ATIME + self::LENGTH_CTIME + self::LENGTH_OFFSET + self::LENGTH_LONGNAME + |
| 40 | self::LENGTH_PAD + self::LENGTH_REGIONS + self::LENGTH_EXTENDED; |
| 41 | const OFFSET_EXTENDED_REGIONS = 0; |
| 42 | const OFFSET_EXTENDED_EXTENDED = self::LENGTH_EXTENDED_REGIONS; |
| 43 | |
| 44 | const |
| 45 | ATIME = 'atime', |
| 46 | CTIME = 'ctime', |
| 47 | OFFSET = 'offset', |
| 48 | LONGNAME = 'longname', |
| 49 | REALSIZE = 'realsize', |
| 50 | REGIONS = 'regions'; |
| 51 | |
| 52 | public function __construct($data=[]) { |
| 53 | parent::__construct($data); |
| 54 | if(isset($data[self::REGIONS])) foreach($data[self::REGIONS] as $part) $this->addRegion(new SparseRegion($part)); |
| 55 | } |
| 56 | |
| 57 | public function setAtime($time, $octal=true) { $this->set(self::ATIME, $octal ? octdec(trim($time)) : (int) $time); } |
| 58 | public function getAtime($octal=true) { return Header::_getDecOct($this->get(self::ATIME), $octal, self::LENGTH_ATIME); } |
| 59 | |
| 60 | public function setCtime($time, $octal=true) { $this->set(self::CTIME, $octal ? octdec(trim($time)) : (int) $time); } |
| 61 | public function getCtime($octal=true) { return Header::_getDecOct($this->get(self::CTIME), $octal, self::LENGTH_CTIME); } |
| 62 | |
| 63 | public function setOffset($offset, $octal=true) { $this->set(self::OFFSET, $octal ? octdec(trim($offset)) : (int) $offset); } |
| 64 | public function getOffset($octal=true) { return Header::_getDecOct($this->get(self::OFFSET), $octal, self::LENGTH_OFFSET); } |
| 65 | |
| 66 | public function setLongName($name, $octal=true) { $this->set(self::LONGNAME, $octal ? octdec(trim($name)) : (int) $name); } |
| 67 | public function getLongName($octal=true) { return Header::_getDecOct($this->get(self::LONGNAME), $octal, self::LENGTH_LONGNAME); } |
| 68 | |
| 69 | public function setRealSize($size, $octal=true) { $this->set(self::REALSIZE, $octal ? octdec(trim($size)) : (int) $size); } |
| 70 | public function getRealSize($octal=true) { return Header::_getDecOct($this->get(self::REALSIZE), $octal, self::LENGTH_REALSIZE); } |
| 71 | |
| 72 | public function setRegions($regions) { $this->set(self::REGIONS, $regions); } |
| 73 | |
| 74 | /** |
| 75 | * @return SparseRegion[] |
| 76 | */ |
| 77 | public function getRegions(): array { return $this->get(self::REGIONS, []); } |
| 78 | |
| 79 | /** |
| 80 | * @param SparseRegion $region |
| 81 | * |
| 82 | * @return void |
| 83 | */ |
| 84 | public function addRegion(SparseRegion $region) { |
| 85 | $parts = $this->getRegions(); |
| 86 | $parts[] = $region; |
| 87 | $this->setRegions($parts); |
| 88 | } |
| 89 | |
| 90 | public static function fromPrefix($prefix, callable $readDataBlock):?Sparse { |
| 91 | if(!trim($prefix) || strlen($prefix) != Header::LENGTH_PREFIX) return null; |
| 92 | $sparse = new Sparse(); |
| 93 | $sparse->setAtime(substr($prefix, self::OFFSET_ATIME, self::LENGTH_ATIME)); |
| 94 | $sparse->setCtime(substr($prefix, self::OFFSET_CTIME, self::LENGTH_CTIME)); |
| 95 | $sparse->setOffset(substr($prefix, self::OFFSET_OFFSET, self::LENGTH_OFFSET)); |
| 96 | $sparse->setLongName(substr($prefix, self::OFFSET_LONGNAME, self::LENGTH_LONGNAME)); |
| 97 | $sparse->setRealSize(substr($prefix, self::OFFSET_REALSIZE, self::LENGTH_REALSIZE)); |
| 98 | |
| 99 | $regions_data = substr($prefix, self::OFFSET_REGIONS, self::LENGTH_REGIONS); |
| 100 | |
| 101 | $extended = trim(substr($prefix, self::OFFSET_EXTENDED, self::LENGTH_EXTENDED)); |
| 102 | while($extended) { |
| 103 | $extended_data = $readDataBlock(); |
| 104 | $regions_data .= substr($extended_data, self::OFFSET_EXTENDED_REGIONS, self::LENGTH_EXTENDED_REGIONS); |
| 105 | $extended = trim(substr($extended_data, self::OFFSET_EXTENDED_EXTENDED, self::LENGTH_EXTENDED)); |
| 106 | } |
| 107 | |
| 108 | $objects = (strlen($regions_data) / SparseRegion::REGION_LENGTH); |
| 109 | |
| 110 | for($i = 0; $i < $objects; $i++) { |
| 111 | if(!($region = SparseRegion::fromData(substr($regions_data, $i * SparseRegion::REGION_LENGTH, SparseRegion::REGION_LENGTH)))) continue; |
| 112 | $sparse->addRegion($region); |
| 113 | } |
| 114 | |
| 115 | return $sparse; |
| 116 | } |
| 117 | |
| 118 | public function buildExtended(callable $writeExtended) { |
| 119 | |
| 120 | // write the extra sparse regions |
| 121 | $regions = $this->getRegions(); |
| 122 | $sparse_data = ''; |
| 123 | while($regions) { |
| 124 | $region = array_shift($regions); |
| 125 | |
| 126 | $sparse_data .= $region->getOffset(); |
| 127 | $sparse_data .= $region->getNumbytes(); |
| 128 | |
| 129 | // 504 bytes is the max we can add to 1 block |
| 130 | if(strlen($sparse_data) == Sparse::LENGTH_EXTENDED_REGIONS || !sizeof($regions)) { |
| 131 | $sparse_data .= sizeof($regions) ? Archive::TRUE_CHAR : Archive::NULL_CHAR; // extended |
| 132 | $sparse_data .= str_repeat(Archive::NULL_CHAR, Sparse::LENGTH_EXTENDED_PAD); // pad |
| 133 | $writeExtended($sparse_data); |
| 134 | $sparse_data = ''; |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | } |