Subversion Repositories oidplus

Rev

Rev 1035 | Rev 1054 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
844 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 - 2022 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
1050 daniel-mar 20
namespace ViaThinkSoft\OIDplus;
844 daniel-mar 21
 
22
class OIDplusFourCC extends OIDplusObject {
23
        private $fourcc;
24
 
25
        // FourCC Syntax examples:
26
        // fourcc_transform('8BIM')       === array(56,66,73,77);   // Adobe Photoshop
27
        // fourcc_transform('AVI')        === array(65,86,73,32);   // AVI File (padded with whitespace)
28
        // fourcc_transform('Y3[10][10]') === array(89,51,10,10);   // 10bit Y'CbCr 4:2:2 video
29
        // Non-FourCC:  fourcc_transform returns false.
30
        private function fourcc_transform($fourcc) {
31
                $out = array();
32
                if ($fourcc === '') return false;
33
                for ($i=0; $i<4; $i++) {
34
                        if (strlen($fourcc) === 0) {
35
                                $out[] = 0x20; // fill with whitespace
36
                        } else {
37
                                if ($fourcc[0] !== '[') {
38
                                        $out[] = ord($fourcc[0]);
39
                                        $fourcc = substr($fourcc,1);
40
                                } else {
41
                                        $p = strpos($fourcc,']');
926 daniel-mar 42
                                        $out[] = (int)substr($fourcc,1,$p-1);
844 daniel-mar 43
                                        $fourcc = substr($fourcc,$p+1);
44
                                }
45
                        }
46
                }
47
                if ($fourcc !== '') return false;
48
                return $out;
49
        }
50
 
51
        public function __construct($fourcc) {
52
                if (self::fourcc_transform($fourcc) !== false) {
53
                        $this->fourcc = $fourcc; // leaf node
54
                } else {
55
                        $this->fourcc = $fourcc; // It is a category name
56
                }
57
        }
58
 
59
        public static function parse($node_id) {
60
                @list($namespace, $fourcc) = explode(':', $node_id, 2);
860 daniel-mar 61
                if ($namespace !== self::ns()) return false;
844 daniel-mar 62
                return new self($fourcc);
63
        }
64
 
65
        public static function objectTypeTitle() {
66
                return _L('Four-Character-Code (FourCC)');
67
        }
68
 
69
        public static function objectTypeTitleShort() {
70
                return _L('FourCC');
71
        }
72
 
73
        public static function ns() {
74
                return 'fourcc';
75
        }
76
 
77
        public static function root() {
860 daniel-mar 78
                return self::ns().':';
844 daniel-mar 79
        }
80
 
81
        public function isRoot() {
82
                return $this->fourcc == '';
83
        }
84
 
85
        public function nodeId($with_ns=true) {
859 daniel-mar 86
                return $with_ns ? self::root().$this->fourcc : $this->fourcc;
844 daniel-mar 87
        }
88
 
89
        public function addString($str) {
845 daniel-mar 90
 
91
                // Y3[10] [10] --> Y3[10][10]
92
                $test_str = trim($str);
93
                do {
94
                        $test_str2 = $test_str;
95
                        $test_str = str_replace(' [', '[', $test_str);
96
                        $test_str = str_replace('] ', ']', $test_str);
97
                } while ($test_str2 != $test_str);
98
 
99
                if (self::fourcc_transform($test_str) !== false) {
844 daniel-mar 100
                        // real FourCC
858 daniel-mar 101
                        return self::root() . $test_str;
844 daniel-mar 102
                } else {
103
                        // just a category
858 daniel-mar 104
                        if ($this->isRoot()) {
105
                                return self::root() . $str;
106
                        } else {
107
                                return $this->nodeId() . '/' . $str;
108
                        }
844 daniel-mar 109
                }
110
        }
111
 
112
        public function crudShowId(OIDplusObject $parent) {
850 daniel-mar 113
                if ($this->isLeafNode()) {
114
                        // We don't parse '/' in a valid FourCC code (i.e. Leaf node)
115
                        return $this->nodeId(false);
116
                } else {
117
                        if ($parent->isRoot()) {
118
                                return substr($this->nodeId(), strlen($parent->nodeId()));
119
                        } else {
120
                                return substr($this->nodeId(), strlen($parent->nodeId())+1);
121
                        }
122
                }
844 daniel-mar 123
        }
124
 
125
        public function jsTreeNodeName(OIDplusObject $parent = null) {
126
                if ($parent == null) return $this->objectTypeTitle();
127
                return $this->crudShowId($parent);
128
        }
129
 
130
        public function defaultTitle() {
131
                return $this->fourcc;
132
        }
133
 
134
        public function isLeafNode() {
135
                return self::fourcc_transform($this->fourcc) !== false;
136
        }
137
 
138
        private function getTechInfo() {
139
                $tech_info = array();
845 daniel-mar 140
                $tech_info[_L('FourCC code')]   = $this->fourcc;
141
                $tech_info[_L('C/C++ Literal')] = $this->getMultiCharLiteral();
844 daniel-mar 142
                $tech_info[_L('Hex Dump')]      = strtoupper(implode(' ', str_split($this->getHex(true),2)));
143
                $tech_info[_L('Big Endian')]    = '0x'.$this->getHex(true);
144
                $tech_info[_L('Little Endian')] = '0x'.$this->getHex(false);
145
                return $tech_info;
146
        }
147
 
148
        public function getContentPage(&$title, &$content, &$icon) {
149
                $icon = file_exists(__DIR__.'/img/main_icon.png') ? OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon.png' : '';
150
 
151
                if ($this->isRoot()) {
152
                        $title = OIDplusFourCC::objectTypeTitle();
153
 
154
                        $res = OIDplus::db()->query("select * from ###objects where parent = ?", array(self::root()));
155
                        if ($res->any()) {
962 daniel-mar 156
                                $content  = '<p>'._L('Please select a FourCC in the tree view at the left to show its contents.').'</p>';
844 daniel-mar 157
                        } else {
962 daniel-mar 158
                                $content  = '<p>'._L('Currently, no FourCC is registered in the system.').'</p>';
844 daniel-mar 159
                        }
160
 
161
                        if (!$this->isLeafNode()) {
162
                                if (OIDplus::authUtils()->isAdminLoggedIn()) {
163
                                        $content .= '<h2>'._L('Manage root objects / categories').'</h2>';
164
                                } else {
165
                                        $content .= '<h2>'._L('Available objects / categories').'</h2>';
166
                                }
167
                                $content .= '%%CRUD%%';
168
                        }
169
                } else {
170
                        $title = $this->getTitle();
171
 
172
                        if ($this->isLeafNode()) {
173
                                $tech_info = $this->getTechInfo();
174
                                $tech_info_html = '';
175
                                if (count($tech_info) > 0) {
176
                                        $tech_info_html .= '<h2>'._L('Technical information').'</h2>';
177
                                        $tech_info_html .= '<table border="0">';
178
                                        foreach ($tech_info as $key => $value) {
179
                                                $tech_info_html .= '<tr><td>'.$key.': </td><td><code>'.str_replace(' ','&nbsp;',$value).'</code></td></tr>';
180
                                        }
181
                                        $tech_info_html .= '</table>';
182
                                }
183
 
184
                                $content = $tech_info_html;
185
                        } else {
186
                                $content = '';
187
                        }
188
 
189
                        $content .= '<h2>'._L('Description').'</h2>%%DESC%%';
190
 
191
                        if (!$this->isLeafNode()) {
192
                                if ($this->userHasWriteRights()) {
928 daniel-mar 193
                                        $content .= '<h2>'._L('Create or change subordinate objects / categories').'</h2>';
844 daniel-mar 194
                                } else {
928 daniel-mar 195
                                        $content .= '<h2>'._L('Subordinate objects / categories').'</h2>';
844 daniel-mar 196
                                }
197
                                $content .= '%%CRUD%%';
198
                        }
199
                }
200
        }
201
 
1035 daniel-mar 202
        public function getIcon($row=null) {
203
                $in_login_treenode = false;
204
                foreach (debug_backtrace() as $trace) {
205
                        // If we are inside the "Login" area (i.e. "Root object links"), we want the
206
                        // correct icon, not a folder icon!
1050 daniel-mar 207
                        if ($trace['class'] === OIDplusPagePublicLogin::class) $in_login_treenode = true;
1035 daniel-mar 208
                }
209
 
210
                if (!$in_login_treenode && !$this->isLeafNode()) return null; // foldericon
211
 
844 daniel-mar 212
                return parent::getIcon($row);
213
        }
214
 
215
        public function one_up() {
216
                // A FourCC is a FourCC, there is no hierarchy
217
                return false;
218
        }
219
 
220
        public function distance($to) {
221
                // Distance between FourCCs is not possible
222
                return null;
223
        }
224
 
225
        public function getAltIds() {
226
                if ($this->isRoot()) return array();
227
                if (!$this->isLeafNode()) return array();
228
                $ids = parent::getAltIds();
229
                return $ids;
230
        }
231
 
232
        private function getHex($big_endian) {
233
                $type = self::fourcc_transform($this->fourcc);
234
                if ($type === false) return false;
235
                $dec = 0;
236
                if (!$big_endian) $type = array_reverse($type);
237
                for ($i=0;$i<4;$i++) $dec = ($dec<<8) + $type[$i];
238
                $hex = str_pad(dechex($dec), 8, "0", STR_PAD_LEFT);
239
                return $hex;
240
        }
241
 
845 daniel-mar 242
        private function getMultiCharLiteral() {
844 daniel-mar 243
                $type = self::fourcc_transform($this->fourcc);
244
                if ($type === false) return false;
926 daniel-mar 245
                return c_literal($type);
844 daniel-mar 246
        }
247
 
248
        public function getDirectoryName() {
249
                if ($this->isLeafNode()) {
250
                        // Leaf (FourCC)
251
                        // Example output: "fourcc_23496d52" for 'fourcc:#ImR'
252
                        return $this->ns().'_'.$this->getHex(true);
253
                } else {
254
                        // Category
255
                        return parent::getDirectoryName();
256
                }
257
        }
258
 
259
        public static function treeIconFilename($mode) {
260
                return 'img/'.$mode.'_icon16.png';
261
        }
850 daniel-mar 262
}