Skip to content

Commit a358358

Browse files
committed
Added files
1 parent a23532a commit a358358

File tree

5 files changed

+320
-25
lines changed

5 files changed

+320
-25
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
.idea/

LICENSE

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -174,28 +174,3 @@
174174
of your accepting any such warranty or additional liability.
175175

176176
END OF TERMS AND CONDITIONS
177-
178-
APPENDIX: How to apply the Apache License to your work.
179-
180-
To apply the Apache License to your work, attach the following
181-
boilerplate notice, with the fields enclosed by brackets "{}"
182-
replaced with your own identifying information. (Don't include
183-
the brackets!) The text should be enclosed in the appropriate
184-
comment syntax for the file format. We also recommend that a
185-
file or class name and description of purpose be included on the
186-
same "printed page" as the copyright notice for easier
187-
identification within third-party archives.
188-
189-
Copyright {yyyy} {name of copyright owner}
190-
191-
Licensed under the Apache License, Version 2.0 (the "License");
192-
you may not use this file except in compliance with the License.
193-
You may obtain a copy of the License at
194-
195-
http://www.apache.org/licenses/LICENSE-2.0
196-
197-
Unless required by applicable law or agreed to in writing, software
198-
distributed under the License is distributed on an "AS IS" BASIS,
199-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200-
See the License for the specific language governing permissions and
201-
limitations under the License.

src/lower.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php

src/upper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php

src/wstring.php

Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
<?php
2+
3+
final class wstring implements ArrayAccess
4+
{
5+
/** @var array */
6+
protected $codes;
7+
/** @var array */
8+
protected $chars;
9+
/** @var string|null */
10+
protected $string;
11+
/** @var int */
12+
protected $length;
13+
14+
public function __construct(array $codes, array $chars)
15+
{
16+
$this->codes = $codes;
17+
$this->chars = $chars;
18+
$this->length = count($codes);
19+
}
20+
21+
public function offsetExists($offset)
22+
{
23+
return isset($this->codes[$offset]);
24+
}
25+
26+
public function offsetGet($offset)
27+
{
28+
return $this->chars[$offset];
29+
}
30+
31+
public function offsetSet($offset, $value)
32+
{
33+
throw new Exception("Invalid operation");
34+
}
35+
36+
public function offsetUnset($offset)
37+
{
38+
throw new Exception("Invalid operation");
39+
}
40+
41+
/**
42+
* @return int
43+
*/
44+
public function length()
45+
{
46+
return $this->length;
47+
}
48+
49+
/**
50+
* @return bool
51+
*/
52+
public function isEmpty()
53+
{
54+
return $this->length === 0;
55+
}
56+
57+
/**
58+
* @param int $start
59+
* @param int|null $length
60+
* @return wstring
61+
*/
62+
public function substr($start, $length = null)
63+
{
64+
return $this->substring($start, $length);
65+
}
66+
67+
68+
/**
69+
* @param int $start
70+
* @param int|null $length
71+
* @return wstring
72+
*/
73+
public function substring($start, $length = null)
74+
{
75+
$cp = array_slice($this->codes, $start, $length);
76+
$ch = array_slice($this->chars, $start, $length);
77+
78+
return new self($cp, $ch);
79+
}
80+
81+
/**
82+
* @param string|wstring $text
83+
* @param int $offset
84+
* @return int|false
85+
* @throws Exception
86+
*/
87+
public function indexOf($text, $offset = 0)
88+
{
89+
$text = wstring($text);
90+
91+
if($offset < 0){
92+
$offset = 0;
93+
}
94+
95+
$cp1 = $this->codes;
96+
$cp2 = $text->codes;
97+
98+
for($i = $offset, $l = $this->length - $text->length; $i <= $l; $i++){
99+
$match = true;
100+
101+
for($j = 0, $f = $text->length; $j < $f; $j++){
102+
if($cp1[$i + $j] != $cp2[$j]){
103+
$match = false;
104+
break;
105+
}
106+
}
107+
108+
if($match){
109+
return $i;
110+
}
111+
}
112+
113+
return false;
114+
}
115+
116+
/**
117+
* @param string|wstring $character_mask
118+
* @return wstring
119+
*/
120+
public function trim($character_mask = " \t\n\r\0\x0B")
121+
{
122+
return $this->doTrim($character_mask);
123+
}
124+
125+
/**
126+
* @param string|wstring $character_mask
127+
* @return wstring
128+
*/
129+
public function ltrim($character_mask = " \t\n\r\0\x0B")
130+
{
131+
return $this->doTrim($character_mask, true, false);
132+
}
133+
134+
/**
135+
* @param string|wstring $character_mask
136+
* @return wstring
137+
*/
138+
public function rtrim($character_mask = " \t\n\r\0\x0B")
139+
{
140+
return $this->doTrim($character_mask, false, true);
141+
}
142+
143+
/**
144+
* @param string|wstring $subject
145+
* @param string|wstring $replace
146+
* @param int $offset
147+
* @return wstring
148+
* @throws Exception
149+
*/
150+
public function replace($subject, $replace, $offset = 0)
151+
{
152+
$subject = wstring($subject);
153+
$replace = wstring($replace);
154+
155+
if(false === $pos = $this->indexOf($subject, $offset)){
156+
return clone $this;
157+
}
158+
159+
$cp1 = array_slice($this->codes, 0, $pos);
160+
$cp2 = array_slice($this->codes, $pos + $subject->length);
161+
$ch1 = array_slice($this->chars, 0, $pos);
162+
$ch2 = array_slice($this->chars, $pos + $subject->length);
163+
164+
$cp = array_merge($cp1, $replace->codes, $cp2);
165+
$ch = array_merge($ch1, $replace->chars, $ch2);
166+
167+
return new self($cp, $ch);
168+
}
169+
170+
/**
171+
* @return string
172+
*/
173+
public function __toString()
174+
{
175+
if($this->string === null){
176+
$this->string = implode('', $this->chars);
177+
}
178+
return $this->string;
179+
}
180+
181+
/**
182+
* @param $character_mask
183+
* @param bool $left
184+
* @param bool $right
185+
* @return wstring
186+
* @throws Exception
187+
*/
188+
protected function doTrim($character_mask, $left = true, $right = true)
189+
{
190+
$character_mask = wstring($character_mask);
191+
192+
$cm = $character_mask->codes;
193+
$cp = $this->codes;
194+
$l = count($cm);
195+
$start = 0;
196+
$end = $this->length;
197+
198+
if($left){
199+
for ($i = 0; $i < $this->length; $i++) {
200+
if (!in_array($cp[$i], $cm)) {
201+
break;
202+
}
203+
}
204+
$start = $i;
205+
}
206+
207+
if($right){
208+
for ($i = $this->length - 1; $i > $start; $i--) {
209+
if (!in_array($cp[$i], $cm)) {
210+
break;
211+
}
212+
}
213+
$end = $i + 1;
214+
}
215+
216+
$cp = array_slice($cp, $start, $end - $start);
217+
$ch = array_slice($this->chars, $start, $end - $start);
218+
219+
return new self($cp, $ch);
220+
}
221+
}
222+
223+
/**
224+
* @param $string
225+
* @return wstring
226+
* @throws Exception
227+
*/
228+
function wstring($string)
229+
{
230+
if($string instanceof wstring){
231+
return $string;
232+
}
233+
234+
$codes = $chars = array();
235+
236+
if(false === $text = json_encode((string) $string)) {
237+
throw new Exception("Invalid UTF-8 string");
238+
}
239+
240+
for($i = 1, $l = strlen($text) - 1; $i < $l; $i++) {
241+
$c = $text[$i];
242+
243+
if($c === '\\'){
244+
if(isset($text[$i + 1])){
245+
246+
if($text[$i + 1] === 'u'){
247+
248+
$codes[] = $cp = hexdec(substr($text, $i, 6));
249+
250+
if ($cp < 0x80) {
251+
$chars[] = chr($cp);
252+
} elseif ($cp <= 0x7FF) {
253+
$chars[] = chr(($cp >> 6) + 0xC0) . chr(($cp & 0x3F) + 0x80);
254+
} elseif ($cp <= 0xFFFF) {
255+
$chars[] = chr(($cp >> 12) + 0xE0) . chr((($cp >> 6) & 0x3F) + 0x80) . chr(($cp & 0x3F) + 0x80);
256+
} elseif ($cp <= 0x10FFFF) {
257+
$chars[] = chr(($cp >> 18) + 0xF0) . chr((($cp >> 12) & 0x3F) + 0x80)
258+
. chr((($cp >> 6) & 0x3F) + 0x80) . chr(($cp & 0x3F) + 0x80);
259+
} else {
260+
throw new Exception("Invalid UTF-8");
261+
}
262+
263+
$i += 5;
264+
continue;
265+
266+
} else{
267+
268+
switch ($text[$i + 1]){
269+
case '\\':
270+
$c = "\\";
271+
break;
272+
case '\'':
273+
$c = "'";
274+
break;
275+
case '"':
276+
$c = '"';
277+
break;
278+
case 'n':
279+
$c = "\n";
280+
break;
281+
case 'r':
282+
$c = "\r";
283+
break;
284+
case 't':
285+
$c = "\t";
286+
break;
287+
case 'b':
288+
$c = "\b";
289+
break;
290+
case 'f':
291+
$c = "\f";
292+
break;
293+
case 'v':
294+
$c = "\v";
295+
break;
296+
case '0':
297+
$c = "\0";
298+
break;
299+
default:
300+
$c = $text[$i + 1];
301+
}
302+
303+
$codes[] = ord($c);
304+
$chars[] = $c;
305+
$i++;
306+
continue;
307+
}
308+
}
309+
}
310+
311+
$codes[] = ord($c);
312+
$chars[] = $c;
313+
}
314+
315+
return new wstring($codes, $chars, null);
316+
}

0 commit comments

Comments
 (0)