Browse Source

Upload files to 'classes'

Stortebeker 6 years ago
parent
commit
644250a24c
3 changed files with 356 additions and 382 deletions
  1. 114
    123
      classes/badges.class.php
  2. 76
    84
      classes/bencode.class.php
  3. 166
    175
      classes/bencodedecode.class.php

+ 114
- 123
classes/badges.class.php View File

@@ -1,145 +1,136 @@
1
-<?php
2
-class Badges
3
-{
4
-    /**
5
-     * Given a UserID, returns that user's badges
6
-     *
7
-     * @param int $UserID
8
-     * @return array of BadgeIDs
9
-     */
10
-    public static function get_badges($UserID)
11
-    {
12
-        return Users::user_info($UserID)['Badges'];
13
-    }
14
-
15
-    /**
16
-     * Awards UserID the given BadgeID
17
-     *
18
-     * @param int $UserID
19
-     * @param int $BadgeID
20
-     * @return bool success?
21
-     */
22
-    public static function award_badge($UserID, $BadgeID)
23
-    {
24
-        if (self::has_badge($UserID, $BadgeID)) {
25
-            return false;
26
-        } else {
27
-            $QueryID = G::$DB->get_query_id();
28
-            G::$DB->query("
1
+<?
2
+class Badges {
3
+  /**
4
+   * Given a UserID, returns that user's badges
5
+   *
6
+   * @param int $UserID
7
+   * @return array of BadgeIDs
8
+   */
9
+  public static function get_badges($UserID) {
10
+    return Users::user_info($UserID)['Badges'];
11
+  }
12
+
13
+  /**
14
+   * Awards UserID the given BadgeID
15
+   *
16
+   * @param int $UserID
17
+   * @param int $BadgeID
18
+   * @return bool success?
19
+   */
20
+  public static function award_badge($UserID, $BadgeID) {
21
+    if (self::has_badge($UserID, $BadgeID)) {
22
+      return false;
23
+    } else {
24
+      $QueryID = G::$DB->get_query_id();
25
+      G::$DB->query("
29 26
         INSERT INTO users_badges
30 27
           (UserID, BadgeID)
31 28
         VALUES
32 29
           ($UserID, $BadgeID)");
33
-            G::$DB->set_query_id($QueryID);
30
+      G::$DB->set_query_id($QueryID);
34 31
 
35
-            G::$Cache->delete_value('user_info_'.$UserID);
32
+      G::$Cache->delete_value('user_info_'.$UserID);
36 33
 
37
-            return true;
38
-        }
34
+      return true;
39 35
     }
40
-
41
-    /**
42
-     * Given a UserID, return that user's displayed badges
43
-     *
44
-     * @param int $UserID
45
-     * @return array of BadgeIDs
46
-     */
47
-    public static function get_displayed_badges($UserID)
48
-    {
49
-        $Result = [];
50
-
51
-        $Badges = self::get_badges($UserID);
52
-
53
-        foreach ($Badges as $Badge => $Displayed) {
54
-            if ($Displayed) {
55
-                $Result[] = $Badge;
56
-            }
57
-        }
58
-        return $Result;
36
+  }
37
+
38
+  /**
39
+   * Given a UserID, return that user's displayed badges
40
+   *
41
+   * @param int $UserID
42
+   * @return array of BadgeIDs
43
+   */
44
+  public static function get_displayed_badges($UserID) {
45
+    $Result = [];
46
+
47
+    $Badges = self::get_badges($UserID);
48
+
49
+    foreach ($Badges as $Badge => $Displayed) {
50
+      if ($Displayed)
51
+        $Result[] = $Badge;
59 52
     }
60
-
61
-    /**
62
-     * Returns true if the given user owns the given badge
63
-     *
64
-     * @param int $UserID
65
-     * @param int $BadgeID
66
-     * @return bool
67
-     */
68
-    public static function has_badge($UserID, $BadgeID)
69
-    {
70
-        $Badges = self::get_badges($UserID);
71
-
72
-        return array_key_exists($BadgeID, $Badges);
53
+    return $Result;
54
+  }
55
+
56
+  /**
57
+   * Returns true if the given user owns the given badge
58
+   *
59
+   * @param int $UserID
60
+   * @param int $BadgeID
61
+   * @return bool
62
+   */
63
+  public static function has_badge($UserID, $BadgeID) {
64
+    $Badges = self::get_badges($UserID);
65
+
66
+    return array_key_exists($BadgeID, $Badges);
67
+  }
68
+
69
+  /**
70
+   * Creates HTML for displaying a badge.
71
+   *
72
+   * @param int $BadgeID
73
+   * @param bool $Tooltip Should HTML contain a tooltip?
74
+   * @return string HTML
75
+   */
76
+  public static function display_badge($BadgeID, $Tooltip = false) {
77
+    $html = "";
78
+
79
+    if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
80
+      extract($Badges[$BadgeID]);
81
+    } else {
82
+      self::update_badge_cache();
83
+      if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
84
+        extract($Badges[$BadgeID]);
85
+      } else {
86
+        global $Debug;
87
+        $Debug->analysis('Invalid BadgeID ' . $BadgeID . ' requested.');
88
+      }
73 89
     }
74 90
 
75
-    /**
76
-     * Creates HTML for displaying a badge.
77
-     *
78
-     * @param int $BadgeID
79
-     * @param bool $Tooltip Should HTML contain a tooltip?
80
-     * @return string HTML
81
-     */
82
-    public static function display_badge($BadgeID, $Tooltip = false)
83
-    {
84
-        $html = "";
85
-
86
-        if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
87
-            extract($Badges[$BadgeID]);
88
-        } else {
89
-            self::update_badge_cache();
90
-            if (($Badges = G::$Cache->get_value('badges')) && array_key_exists($BadgeID, $Badges)) {
91
-                extract($Badges[$BadgeID]);
92
-            } else {
93
-                global $Debug;
94
-                $Debug->analysis('Invalid BadgeID ' . $BadgeID . ' requested.');
95
-            }
96
-        }
97
-
98
-        if ($Tooltip) {
99
-            $html .= '<a class="badge_icon"><img class="tooltip" alt="'.$Name.'" title="'.$Name.'</br>'.$Description.'" src="'.$Icon.'" /></a>';
100
-        } else {
101
-            $html .= '<a class="badge_icon"><img alt="'.$Name.'" title="'.$Name.'" src="'.$Icon.'" /></a>';
102
-        }
103
-
104
-        return $html;
91
+    if ($Tooltip) {
92
+      $html .= '<a class="badge_icon"><img class="tooltip" alt="'.$Name.'" title="'.$Name.'</br>'.$Description.'" src="'.$Icon.'" /></a>';
93
+    } else {
94
+      $html .= '<a class="badge_icon"><img alt="'.$Name.'" title="'.$Name.'" src="'.$Icon.'" /></a>';
105 95
     }
106 96
 
107
-    public static function display_badges($BadgeIDs, $Tooltip = false)
108
-    {
109
-        $html = "";
110
-        foreach ($BadgeIDs as $BadgeID) {
111
-            $html .= self::display_badge($BadgeID, $Tooltip);
112
-        }
113
-        return $html;
97
+    return $html;
98
+  }
99
+
100
+  public static function display_badges($BadgeIDs, $Tooltip = false) {
101
+    $html = "";
102
+    foreach ($BadgeIDs as $BadgeID) {
103
+      $html .= self::display_badge($BadgeID, $Tooltip);
114 104
     }
105
+    return $html;
106
+  }
115 107
 
116
-    private static function update_badge_cache()
117
-    {
118
-        $QueryID = G::$DB->get_query_id();
108
+  private static function update_badge_cache() {
109
+      $QueryID = G::$DB->get_query_id();
119 110
 
120
-        G::$DB->query("
111
+      G::$DB->query("
121 112
         SELECT
122 113
         ID, Icon, Name, Description
123 114
         FROM badges");
124 115
 
125
-        $badges = [];
126
-        if (G::$DB->has_results()) {
127
-            while (list($id, $icon, $name, $description) = G::$DB->next_record()) {
128
-                $badges[$id] = array('Icon' => $icon, 'Name' => $name, 'Description' => $Description);
129
-            }
130
-            G::$Cache->cache_value('badges', $badges);
131
-        }
132
-
133
-        G::$DB->set_query_id($QueryID);
134
-    }
135
-
136
-    public static function get_all_badges()
137
-    {
138
-        if (($Badges = G::$Cache->get_value('badges'))) {
139
-            return $Badges;
140
-        } else {
141
-            self::update_badge_cache();
142
-            return G::$Cache->get_value('badges');
116
+      $badges = [];
117
+      if (G::$DB->has_results()) {
118
+        while(list($id, $icon, $name, $description) = G::$DB->next_record()) {
119
+          $badges[$id] = array('Icon' => $icon, 'Name' => $name, 'Description' => $Description);
143 120
         }
121
+        G::$Cache->cache_value('badges', $badges);
122
+      }
123
+
124
+      G::$DB->set_query_id($QueryID);
125
+  }
126
+
127
+  public static function get_all_badges() {
128
+    if (($Badges = G::$Cache->get_value('badges'))) {
129
+      return $Badges;
130
+    } else {
131
+      self::update_badge_cache();
132
+      return G::$Cache->get_value('badges');
144 133
     }
134
+  }
145 135
 }
136
+?>

+ 76
- 84
classes/bencode.class.php View File

@@ -1,104 +1,96 @@
1
-<?php
1
+<?
2 2
 /**
3 3
  * If we're running a 32bit PHP version, we use small objects to store ints.
4 4
  * Overhead from the function calls is small enough to not worry about
5 5
  */
6
-class Int64
7
-{
8
-    private $Num;
6
+class Int64 {
7
+  private $Num;
9 8
 
10
-    public function __construct($Val)
11
-    {
12
-        $this->Num = $Val;
13
-    }
9
+  public function __construct($Val) {
10
+    $this->Num = $Val;
11
+  }
14 12
 
15
-    public static function make($Val)
16
-    {
17
-        return PHP_INT_SIZE === 4 ? new Int64($Val) : (int)$Val;
18
-    }
13
+  public static function make($Val) {
14
+    return PHP_INT_SIZE === 4 ? new Int64($Val) : (int)$Val;
15
+  }
19 16
 
20
-    public static function get($Val)
21
-    {
22
-        return PHP_INT_SIZE === 4 ? $Val->Num : $Val;
23
-    }
17
+  public static function get($Val) {
18
+    return PHP_INT_SIZE === 4 ? $Val->Num : $Val;
19
+  }
24 20
 
25
-    public static function is_int($Val)
26
-    {
27
-        return is_int($Val) || (is_object($Val) && get_class($Val) === 'Int64');
28
-    }
21
+  public static function is_int($Val) {
22
+    return is_int($Val) || (is_object($Val) && get_class($Val) === 'Int64');
23
+  }
29 24
 }
30 25
 
31 26
 /**
32 27
  * The encode class is simple and straightforward. The only thing to
33 28
  * note is that empty dictionaries are represented by boolean trues
34 29
  */
35
-class Bencode
36
-{
37
-    private $DefaultKeys = array( // Get rid of everything except these keys to save some space
30
+class Bencode {
31
+  private $DefaultKeys = array( // Get rid of everything except these keys to save some space
38 32
       'created by', 'creation date', 'encoding', 'info', 'comment');
39
-    private $Data;
40
-    public $Enc;
33
+  private $Data;
34
+  public $Enc;
41 35
 
42
-    /**
43
-     * Encode an arbitrary array (usually one that's just been decoded)
44
-     *
45
-     * @param array $Arg the thing to encode
46
-     * @param mixed $Keys string or array with keys in the input array to encode or true to encode everything
47
-     * @return bencoded string representing the content of the input array
48
-     */
49
-    public function encode($Arg = false, $Keys = false)
50
-    {
51
-        if ($Arg === false) {
52
-            $Data =& $this->Dec;
53
-        } else {
54
-            $Data =& $Arg;
55
-        }
56
-        if ($Keys === true) {
57
-            $this->Data = $Data;
58
-        } elseif ($Keys === false) {
59
-            $this->Data = array_intersect_key($Data, array_flip($this->DefaultKeys));
60
-        } elseif (is_array($Keys)) {
61
-            $this->Data = array_intersect_key($Data, array_flip($Keys));
62
-        } else {
63
-            $this->Data = isset($Data[$Keys]) ? $Data[$Keys] : false;
64
-        }
65
-        if (!$this->Data) {
66
-            return false;
67
-        }
68
-        $this->Enc = $this->_benc();
69
-        return $this->Enc;
36
+  /**
37
+   * Encode an arbitrary array (usually one that's just been decoded)
38
+   *
39
+   * @param array $Arg the thing to encode
40
+   * @param mixed $Keys string or array with keys in the input array to encode or true to encode everything
41
+   * @return bencoded string representing the content of the input array
42
+   */
43
+  public function encode($Arg = false, $Keys = false) {
44
+    if ($Arg === false) {
45
+      $Data =& $this->Dec;
46
+    } else {
47
+      $Data =& $Arg;
70 48
     }
49
+    if ($Keys === true) {
50
+      $this->Data = $Data;
51
+    } elseif ($Keys === false) {
52
+      $this->Data = array_intersect_key($Data, array_flip($this->DefaultKeys));
53
+    } elseif (is_array($Keys)) {
54
+      $this->Data = array_intersect_key($Data, array_flip($Keys));
55
+    } else {
56
+      $this->Data = isset($Data[$Keys]) ? $Data[$Keys] : false;
57
+    }
58
+    if (!$this->Data) {
59
+      return false;
60
+    }
61
+    $this->Enc = $this->_benc();
62
+    return $this->Enc;
63
+  }
71 64
 
72
-    /**
73
-     * Internal encoding function that does the actual job
74
-     *
75
-     * @return bencoded string
76
-     */
77
-    private function _benc()
78
-    {
79
-        if (!is_array($this->Data)) {
80
-            if (Int64::is_int($this->Data)) { // Integer
81
-                return 'i'.Int64::get($this->Data).'e';
82
-            }
83
-            if ($this->Data === true) { // Empty dictionary
84
-                return 'de';
85
-            }
86
-            return strlen($this->Data).':'.$this->Data; // String
87
-        }
88
-        if (empty($this->Data) || Int64::is_int(key($this->Data))) {
89
-            $IsDict = false;
90
-        } else {
91
-            $IsDict = true;
92
-            ksort($this->Data); // Dictionaries must be sorted
93
-        }
94
-        $Ret = $IsDict ? 'd' : 'l';
95
-        foreach ($this->Data as $Key => $Value) {
96
-            if ($IsDict) {
97
-                $Ret .= strlen($Key).':'.$Key;
98
-            }
99
-            $this->Data = $Value;
100
-            $Ret .= $this->_benc();
101
-        }
102
-        return $Ret.'e';
65
+  /**
66
+   * Internal encoding function that does the actual job
67
+   *
68
+   * @return bencoded string
69
+   */
70
+  private function _benc() {
71
+    if (!is_array($this->Data)) {
72
+      if (Int64::is_int($this->Data)) { // Integer
73
+        return 'i'.Int64::get($this->Data).'e';
74
+      }
75
+      if ($this->Data === true) { // Empty dictionary
76
+        return 'de';
77
+      }
78
+      return strlen($this->Data).':'.$this->Data; // String
79
+    }
80
+    if (empty($this->Data) || Int64::is_int(key($this->Data))) {
81
+      $IsDict = false;
82
+    } else {
83
+      $IsDict = true;
84
+      ksort($this->Data); // Dictionaries must be sorted
85
+    }
86
+    $Ret = $IsDict ? 'd' : 'l';
87
+    foreach ($this->Data as $Key => $Value) {
88
+      if ($IsDict) {
89
+        $Ret .= strlen($Key).':'.$Key;
90
+      }
91
+      $this->Data = $Value;
92
+      $Ret .= $this->_benc();
103 93
     }
94
+    return $Ret.'e';
95
+  }
104 96
 }

+ 166
- 175
classes/bencodedecode.class.php View File

@@ -1,196 +1,187 @@
1
-<?php
1
+<?
2 2
 /**
3 3
  * The decode class is simple and straightforward. The only thing to
4 4
  * note is that empty dictionaries are represented by boolean trues
5 5
  */
6
-class BencodeDecode extends Bencode
7
-{
8
-    private $Data;
9
-    private $Length;
10
-    private $Pos = 0;
11
-    public $Dec = [];
12
-    public $ExitOnError = true;
13
-    const SnipLength = 40;
6
+class BencodeDecode extends Bencode {
7
+  private $Data;
8
+  private $Length;
9
+  private $Pos = 0;
10
+  public $Dec = [];
11
+  public $ExitOnError = true;
12
+  const SnipLength = 40;
14 13
 
15
-    /**
16
-     * Decode prepararations
17
-     *
18
-     * @param string $Arg bencoded string or path to bencoded file to decode
19
-     * @param bool $IsPath needs to be true if $Arg is a path
20
-     * @return decoded data with a suitable structure
21
-     */
22
-    public function __construct($Arg = false, $IsPath = false, $Strict = true)
23
-    {
24
-        if (!$Strict) {
25
-            $this->ExitOnError = false;
26
-        }
27
-        if ($Arg === false) {
28
-            if (empty($this->Enc)) {
29
-                return false;
30
-            }
31
-        } else {
32
-            if ($IsPath === true) {
33
-                return $this->bdec_file($Arg);
34
-            }
35
-            $this->Data = $Arg;
36
-        }
37
-        return $this->decode();
14
+  /**
15
+   * Decode prepararations
16
+   *
17
+   * @param string $Arg bencoded string or path to bencoded file to decode
18
+   * @param bool $IsPath needs to be true if $Arg is a path
19
+   * @return decoded data with a suitable structure
20
+   */
21
+  function __construct($Arg = false, $IsPath = false, $Strict = true) {
22
+    if (!$Strict) {
23
+      $this->ExitOnError = false;
38 24
     }
39
-
40
-    /**
41
-     * Decodes a bencoded file
42
-     *
43
-     * @param $Path path to bencoded file to decode
44
-     * @return decoded data with a suitable structure
45
-     */
46
-    public function bdec_file($Path = false)
47
-    {
48
-        if (empty($Path)) {
49
-            return false;
50
-        }
51
-        if (!$this->Data = @file_get_contents($Path, FILE_BINARY)) {
52
-            return $this->error("Error: file '$Path' could not be opened.\n");
53
-        }
54
-        return $this->decode();
25
+    if ($Arg === false) {
26
+      if (empty($this->Enc)) {
27
+        return false;
28
+      }
29
+    } else {
30
+      if ($IsPath === true) {
31
+        return $this->bdec_file($Arg);
32
+      }
33
+      $this->Data = $Arg;
55 34
     }
35
+    return $this->decode();
36
+  }
56 37
 
57
-    /**
58
-     * Decodes a string with bencoded data
59
-     *
60
-     * @param mixed $Arg bencoded data or false to decode the content of $this->Data
61
-     * @return decoded data with a suitable structure
62
-     */
63
-    public function decode($Arg = false)
64
-    {
65
-        if ($Arg !== false) {
66
-            $this->Data = $Arg;
67
-        } elseif (!$this->Data) {
68
-            $this->Data = $this->Enc;
69
-        }
70
-        if (!$this->Data) {
71
-            return false;
72
-        }
73
-        $this->Length = strlen($this->Data);
74
-        $this->Pos = 0;
75
-        $this->Dec = $this->_bdec();
76
-        if ($this->Pos < $this->Length) {
77
-            // Not really necessary, but if the torrent is invalid, it's better to warn than to silently truncate it
78
-            return $this->error();
79
-        }
80
-        return $this->Dec;
38
+  /**
39
+   * Decodes a bencoded file
40
+   *
41
+   * @param $Path path to bencoded file to decode
42
+   * @return decoded data with a suitable structure
43
+   */
44
+  public function bdec_file($Path = false) {
45
+    if (empty($Path)) {
46
+      return false;
81 47
     }
48
+    if (!$this->Data = @file_get_contents($Path, FILE_BINARY)) {
49
+      return $this->error("Error: file '$Path' could not be opened.\n");
50
+    }
51
+    return $this->decode();
52
+  }
82 53
 
83
-    /**
84
-     * Internal decoding function that does the actual job
85
-     *
86
-     * @return decoded data with a suitable structure
87
-     */
88
-    private function _bdec()
89
-    {
90
-        switch ($this->Data[$this->Pos]) {
91
-            case 'i':
92
-                $this->Pos++;
93
-                $Value = substr($this->Data, $this->Pos, strpos($this->Data, 'e', $this->Pos) - $this->Pos);
94
-                if (!ctype_digit($Value) && !($Value[0] == '-' && ctype_digit(substr($Value, 1)))) {
95
-                    return $this->error();
96
-                }
97
-                $this->Pos += strlen($Value) + 1;
98
-                return Int64::make($Value);
99
-
100
-            case 'l':
101
-                $Value = [];
102
-                $this->Pos++;
103
-                while ($this->Data[$this->Pos] != 'e') {
104
-                    if ($this->Pos >= $this->Length) {
105
-                        return $this->error();
106
-                    }
107
-                    $Value[] = $this->_bdec();
108
-                }
109
-                $this->Pos++;
110
-                return $Value;
54
+  /**
55
+   * Decodes a string with bencoded data
56
+   *
57
+   * @param mixed $Arg bencoded data or false to decode the content of $this->Data
58
+   * @return decoded data with a suitable structure
59
+   */
60
+  public function decode($Arg = false) {
61
+    if ($Arg !== false) {
62
+      $this->Data = $Arg;
63
+    } elseif (!$this->Data) {
64
+      $this->Data = $this->Enc;
65
+    }
66
+    if (!$this->Data) {
67
+      return false;
68
+    }
69
+    $this->Length = strlen($this->Data);
70
+    $this->Pos = 0;
71
+    $this->Dec = $this->_bdec();
72
+    if ($this->Pos < $this->Length) {
73
+      // Not really necessary, but if the torrent is invalid, it's better to warn than to silently truncate it
74
+      return $this->error();
75
+    }
76
+    return $this->Dec;
77
+  }
111 78
 
112
-            case 'd':
113
-                $Value = [];
114
-                $this->Pos++;
115
-                while ($this->Data[$this->Pos] != 'e') {
116
-                    $Length = substr($this->Data, $this->Pos, strpos($this->Data, ':', $this->Pos) - $this->Pos);
117
-                    if (!ctype_digit($Length)) {
118
-                        return $this->error();
119
-                    }
120
-                    $this->Pos += strlen($Length) + $Length + 1;
121
-                    $Key = substr($this->Data, $this->Pos - $Length, $Length);
122
-                    if ($this->Pos >= $this->Length) {
123
-                        return $this->error();
124
-                    }
125
-                    $Value[$Key] = $this->_bdec();
126
-                }
127
-                $this->Pos++;
128
-              // Use boolean true to keep track of empty dictionaries
129
-                return empty($Value) ? true : $Value;
79
+  /**
80
+   * Internal decoding function that does the actual job
81
+   *
82
+   * @return decoded data with a suitable structure
83
+   */
84
+  private function _bdec() {
85
+    switch ($this->Data[$this->Pos]) {
130 86
 
131
-            default:
132
-                $Length = substr($this->Data, $this->Pos, strpos($this->Data, ':', $this->Pos) - $this->Pos);
133
-                if (!ctype_digit($Length)) {
134
-                    return $this->error(); // Even if the string is likely to be decoded correctly without this check, it's malformed
135
-                }
136
-                $this->Pos += strlen($Length) + $Length + 1;
137
-                return substr($this->Data, $this->Pos - $Length, $Length);
87
+      case 'i':
88
+        $this->Pos++;
89
+        $Value = substr($this->Data, $this->Pos, strpos($this->Data, 'e', $this->Pos) - $this->Pos);
90
+        if (!ctype_digit($Value) && !($Value[0] == '-' && ctype_digit(substr($Value, 1)))) {
91
+          return $this->error();
138 92
         }
139
-    }
93
+        $this->Pos += strlen($Value) + 1;
94
+        return Int64::make($Value);
140 95
 
141
-    /**
142
-     * Convert everything to the correct data types and optionally escape strings
143
-     *
144
-     * @param bool $Escape whether to escape the textual data
145
-     * @param mixed $Data decoded data or false to use the $Dec property
146
-     * @return decoded data with more useful data types
147
-     */
148
-    public function dump($Escape = true, $Data = false)
149
-    {
150
-        if ($Data === false) {
151
-            $Data = $this->Dec;
152
-        }
153
-        if (Int64::is_int($Data)) {
154
-            return Int64::get($Data);
96
+      case 'l':
97
+        $Value = [];
98
+        $this->Pos++;
99
+        while ($this->Data[$this->Pos] != 'e') {
100
+          if ($this->Pos >= $this->Length) {
101
+            return $this->error();
102
+          }
103
+          $Value[] = $this->_bdec();
155 104
         }
156
-        if (is_bool($Data)) {
157
-            return [];
105
+        $this->Pos++;
106
+        return $Value;
107
+
108
+      case 'd':
109
+        $Value = [];
110
+        $this->Pos++;
111
+        while ($this->Data[$this->Pos] != 'e') {
112
+          $Length = substr($this->Data, $this->Pos, strpos($this->Data, ':', $this->Pos) - $this->Pos);
113
+          if (!ctype_digit($Length)) {
114
+            return $this->error();
115
+          }
116
+          $this->Pos += strlen($Length) + $Length + 1;
117
+          $Key = substr($this->Data, $this->Pos - $Length, $Length);
118
+          if ($this->Pos >= $this->Length) {
119
+            return $this->error();
120
+          }
121
+          $Value[$Key] = $this->_bdec();
158 122
         }
159
-        if (is_array($Data)) {
160
-            $Output = [];
161
-            foreach ($Data as $Key => $Val) {
162
-                $Output[$Key] = $this->dump($Escape, $Val);
163
-            }
164
-            return $Output;
123
+        $this->Pos++;
124
+        // Use boolean true to keep track of empty dictionaries
125
+        return empty($Value) ? true : $Value;
126
+
127
+      default:
128
+        $Length = substr($this->Data, $this->Pos, strpos($this->Data, ':', $this->Pos) - $this->Pos);
129
+        if (!ctype_digit($Length)) {
130
+          return $this->error(); // Even if the string is likely to be decoded correctly without this check, it's malformed
165 131
         }
166
-        return $Escape ? htmlentities($Data) : $Data;
132
+        $this->Pos += strlen($Length) + $Length + 1;
133
+        return substr($this->Data, $this->Pos - $Length, $Length);
167 134
     }
135
+  }
168 136
 
169
-    /**
170
-     * Display an error and halt the operation unless the $ExitOnError property is false
171
-     *
172
-     * @param string $ErrMsg the error message to display
173
-     */
174
-    private function error($ErrMsg = false)
175
-    {
176
-        static $ErrorPos;
177
-        if ($this->Pos === $ErrorPos) {
178
-            // The recursive nature of the class requires this to avoid duplicate error messages
179
-            return false;
180
-        }
181
-        if ($this->ExitOnError) {
182
-            if ($ErrMsg === false) {
183
-                printf(
184
-                    "Malformed string. Invalid character at pos 0x%X: %s\n",
185
-                    $this->Pos,
186
-                    str_replace(array("\r","\n"), array('',' '), htmlentities(substr($this->Data, $this->Pos, self::SnipLength)))
187
-                );
188
-            } else {
189
-                echo $ErrMsg;
190
-            }
191
-            exit();
192
-        }
193
-        $ErrorPos = $this->Pos;
194
-        return false;
137
+  /**
138
+   * Convert everything to the correct data types and optionally escape strings
139
+   *
140
+   * @param bool $Escape whether to escape the textual data
141
+   * @param mixed $Data decoded data or false to use the $Dec property
142
+   * @return decoded data with more useful data types
143
+   */
144
+  public function dump($Escape = true, $Data = false) {
145
+    if ($Data === false) {
146
+      $Data = $this->Dec;
147
+    }
148
+    if (Int64::is_int($Data)) {
149
+      return Int64::get($Data);
150
+    }
151
+    if (is_bool($Data)) {
152
+      return [];
153
+    }
154
+    if (is_array($Data)) {
155
+      $Output = [];
156
+      foreach ($Data as $Key => $Val) {
157
+        $Output[$Key] = $this->dump($Escape, $Val);
158
+      }
159
+      return $Output;
160
+    }
161
+    return $Escape ? htmlentities($Data) : $Data;
162
+  }
163
+
164
+  /**
165
+   * Display an error and halt the operation unless the $ExitOnError property is false
166
+   *
167
+   * @param string $ErrMsg the error message to display
168
+   */
169
+  private function error($ErrMsg = false) {
170
+    static $ErrorPos;
171
+    if ($this->Pos === $ErrorPos) {
172
+      // The recursive nature of the class requires this to avoid duplicate error messages
173
+      return false;
174
+    }
175
+    if ($this->ExitOnError) {
176
+      if ($ErrMsg === false) {
177
+        printf("Malformed string. Invalid character at pos 0x%X: %s\n",
178
+            $this->Pos, str_replace(array("\r","\n"), array('',' '), htmlentities(substr($this->Data, $this->Pos, self::SnipLength))));
179
+      } else {
180
+        echo $ErrMsg;
181
+      }
182
+      exit();
195 183
     }
184
+    $ErrorPos = $this->Pos;
185
+    return false;
186
+  }
196 187
 }

Loading…
Cancel
Save