1
|
|
|
<?php namespace Gears\String; |
2
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
3
|
|
|
// __________ __ ________ __________ |
4
|
|
|
// \______ \ |__ ______ / _____/ ____ _____ ______\______ \ _______ ___ |
5
|
|
|
// | ___/ | \\____ \/ \ ____/ __ \\__ \\_ __ \ | _// _ \ \/ / |
6
|
|
|
// | | | Y \ |_> > \_\ \ ___/ / __ \| | \/ | ( <_> > < |
7
|
|
|
// |____| |___| / __/ \______ /\___ >____ /__| |______ /\____/__/\_ \ |
8
|
|
|
// \/|__| \/ \/ \/ \/ \/ |
9
|
|
|
// ----------------------------------------------------------------------------- |
10
|
|
|
// Designed and Developed by Brad Jones <brad @="bjc.id.au" /> |
11
|
|
|
// ----------------------------------------------------------------------------- |
12
|
|
|
//////////////////////////////////////////////////////////////////////////////// |
13
|
|
|
|
14
|
|
|
use voku\helper\UTF8; |
15
|
|
|
use Icecave\Parity\Parity; |
16
|
|
|
use Icecave\Parity\SubClassComparableInterface as Comparable; |
17
|
|
|
use Gears\String\Exceptions\MisMatchedEncodingException; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* String Builder Class. |
21
|
|
|
* |
22
|
|
|
* This class is modeled off the .NET C# version. |
23
|
|
|
* @see https://goo.gl/utVtKG |
24
|
|
|
* |
25
|
|
|
* There is much debate about performance of such String Builders in PHP. |
26
|
|
|
* Most suggest PHP simply doesn't need such a class because strings are |
27
|
|
|
* mutable and for the most part I completely agree. |
28
|
|
|
* @see http://stackoverflow.com/questions/124067 |
29
|
|
|
* |
30
|
|
|
* However this is not a performance thing for me, personally I just like the |
31
|
|
|
* API that the C# StringBuilder class provides. Coming back to PHP development |
32
|
|
|
* after a lengthy .NET project, it was one of many things I missed. |
33
|
|
|
* |
34
|
|
|
* Also the main Gears\String\Str class is immutable anyway. |
35
|
|
|
* |
36
|
|
|
* @package Gears\String |
37
|
|
|
*/ |
38
|
|
|
class Builder implements Comparable |
39
|
|
|
{ |
40
|
|
|
/** |
41
|
|
|
* The string that this builder is building. |
42
|
|
|
* |
43
|
|
|
* @var \Gears\String\Str |
44
|
|
|
*/ |
45
|
|
|
protected $str; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* After building your string, you may retreive the underlying Str object. |
49
|
|
|
* |
50
|
|
|
* @return \Gears\String\Str |
51
|
|
|
*/ |
52
|
|
|
public function getStr() |
53
|
|
|
{ |
54
|
|
|
return $this->str; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* String Builder Constructor. |
59
|
|
|
* |
60
|
|
|
* @param string|Str $string Optionally provide an intial string. |
61
|
|
|
* |
62
|
|
|
* @param string|null $encoding The character encoding to use for this |
63
|
|
|
* string builder. If not specified, defaults |
64
|
|
|
* to the value returned from |
65
|
|
|
* mb_internal_encoding(). |
66
|
|
|
*/ |
67
|
|
|
public function __construct($string = '', $encoding = null) |
68
|
|
|
{ |
69
|
|
|
// If the provided $string is in fact a Str object and the builder has |
70
|
|
|
// not been given a specfic encoding to use lets carry the encoding over |
71
|
|
|
// to the new Str object. |
72
|
|
|
if ($encoding === null && $string instanceof Str) |
73
|
|
|
{ |
74
|
|
|
$encoding = $string->getEncoding(); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
// Str will throw exceptions if the provided $string is not string like. |
78
|
|
|
$this->str = new Str($string, $encoding); |
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Magic method to automatically turn the builder back into a scalar string. |
83
|
|
|
* |
84
|
|
|
* @see http://php.net/manual/en/language.oop5.magic.php#object.tostring |
85
|
|
|
* |
86
|
|
|
* @return string |
87
|
|
|
*/ |
88
|
|
|
public function __toString() |
89
|
|
|
{ |
90
|
|
|
return (string)$this->str; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Appends a copy of the specified string to this instance. |
95
|
|
|
* |
96
|
|
|
* @param string|Str $string The string to append. |
97
|
|
|
* |
98
|
|
|
* @return static |
99
|
|
|
*/ |
100
|
|
|
public function append($string) |
101
|
|
|
{ |
102
|
|
|
// Grab the current encoding |
103
|
|
|
$encoding = $this->str->getEncoding(); |
104
|
|
|
|
105
|
|
|
if ($string instanceof Str) |
106
|
|
|
{ |
107
|
|
|
// Ensure the encoding's match of both strings |
108
|
|
|
if ($string->getEncoding() !== $encoding) |
109
|
|
|
{ |
110
|
|
|
throw new MisMatchedEncodingException(); |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
$toBeAppended = $string; |
114
|
|
|
} |
115
|
|
|
else |
116
|
|
|
{ |
117
|
|
|
// Ensure the incoming string is string like... Str will throw |
118
|
|
|
// exceptions if not. We also make the assumption that any "scalar" |
119
|
|
|
// strings are in the same encoding as the internal Str object. |
120
|
|
|
$toBeAppended = new Str($string, $encoding); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
// Create the new Str object |
124
|
|
|
$this->str = new Str($this->str.$toBeAppended, $encoding); |
125
|
|
|
|
126
|
|
|
// Return ourselves to enable method chaining. |
127
|
|
|
return $this; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Appends the string returned by vsprintf given the $format and $args. |
132
|
|
|
* |
133
|
|
|
* For details on the syntax of the $format string: |
134
|
|
|
* @see http://php.net/manual/en/function.sprintf.php |
135
|
|
|
* |
136
|
|
|
* @param string|Str $format The format string is composed of zero or more |
137
|
|
|
* directives: ordinary characters (excluding %) |
138
|
|
|
* that are copied directly to the result, and |
139
|
|
|
* conversion specifications. |
140
|
|
|
* |
141
|
|
|
* @param array $args The arguments that will be inserted |
142
|
|
|
* into the $format string. |
143
|
|
|
* |
144
|
|
|
* @return static |
145
|
|
|
*/ |
146
|
|
|
public function appendFormat($format, $args) |
147
|
|
|
{ |
148
|
|
|
return $this->append(vsprintf((string)$format, $args)); |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Appends the default line terminator to the end of the current Builder. |
153
|
|
|
* |
154
|
|
|
* @param string|Str $string Optional, a string to append before |
155
|
|
|
* the line terminator. |
156
|
|
|
* |
157
|
|
|
* @param string|Str $type The line terminator to append, |
158
|
|
|
* defaults to LINE FEED. |
159
|
|
|
* |
160
|
|
|
* @return static |
161
|
|
|
*/ |
162
|
|
|
public function appendLine($string = '', $type = "\n") |
163
|
|
|
{ |
164
|
|
|
return $this->append($string)->append($type); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Removes all characters from the current Builder instance. |
169
|
|
|
* |
170
|
|
|
* @return static |
171
|
|
|
*/ |
172
|
|
|
public function clear() |
173
|
|
|
{ |
174
|
|
|
$this->str = new Str(''); |
175
|
|
|
|
176
|
|
|
return $this; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Implements Icecave\Parity\SubClassComparableInterface compare method. |
181
|
|
|
* |
182
|
|
|
* @see https://git.io/vVxSz |
183
|
|
|
* |
184
|
|
|
* @param object $value The object to compare. |
185
|
|
|
* |
186
|
|
|
* @return integer The result of the comparison. |
187
|
|
|
*/ |
188
|
|
|
public function compare($value) |
189
|
|
|
{ |
190
|
|
|
return strcmp((string)$value, (string)$this); |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Returns a value indicating whether this instance is equal to another. |
195
|
|
|
* |
196
|
|
|
* @param object $value The object to compare. |
197
|
|
|
* |
198
|
|
|
* @return boolean |
199
|
|
|
*/ |
200
|
|
|
public function equals($value) |
201
|
|
|
{ |
202
|
|
|
return Parity::isEqualTo($this, $value); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Inserts a string into this instance at the specified character position. |
207
|
|
|
* |
208
|
|
|
* @param int $index The index at which to insert the substring. |
209
|
|
|
* |
210
|
|
|
* @param string|Str $string The substring to insert. |
211
|
|
|
* |
212
|
|
|
* @return static |
213
|
|
|
*/ |
214
|
|
|
public function insert($index, $string) |
215
|
|
|
{ |
216
|
|
|
// NOTE: This could be slightly confusing as the parameters |
217
|
|
|
// are back to front. I guess I could change the Str version... |
218
|
|
|
|
219
|
|
|
$this->str = $this->str->insert((string)$string, $index); |
220
|
|
|
|
221
|
|
|
return $this; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* Removes the specified range of characters from this instance. |
226
|
|
|
* |
227
|
|
|
* @param int $startIndex The zero-based position in this instance |
228
|
|
|
* where removal begins. |
229
|
|
|
* |
230
|
|
|
* @param int $length The number of characters to remove. |
231
|
|
|
* |
232
|
|
|
* @return static |
233
|
|
|
*/ |
234
|
|
|
public function remove($startIndex, $length) |
235
|
|
|
{ |
236
|
|
|
$start = UTF8::substr |
237
|
|
|
( |
238
|
|
|
(string)$this->str, |
239
|
|
|
0, |
240
|
|
|
$startIndex, |
241
|
|
|
$this->str->getEncoding() |
242
|
|
|
); |
243
|
|
|
|
244
|
|
|
$end = UTF8::substr |
245
|
|
|
( |
246
|
|
|
(string)$this->str, |
247
|
|
|
$startIndex + $length, |
248
|
|
|
$this->str->getLength(), |
249
|
|
|
$this->str->getEncoding() |
250
|
|
|
); |
251
|
|
|
|
252
|
|
|
$this->str = new Str($start.$end); |
253
|
|
|
|
254
|
|
|
return $this; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Replaces all occurrences of $old in this instance with $new. |
259
|
|
|
* |
260
|
|
|
* @param string|Str $old The string to replace. |
261
|
|
|
* |
262
|
|
|
* @param string|Str $new The string that replaces $old. |
263
|
|
|
* |
264
|
|
|
* @return static |
265
|
|
|
*/ |
266
|
|
|
public function replace($old, $new) |
267
|
|
|
{ |
268
|
|
|
$this->str = $this->str->replace((string)$old, (string)$new); |
269
|
|
|
|
270
|
|
|
return $this; |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
|