1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* soluble-japha / PHPJavaBridge driver client. |
7
|
|
|
* |
8
|
|
|
* Refactored version of phpjababridge's Java.inc file compatible |
9
|
|
|
* with php java bridge 6.2 |
10
|
|
|
* |
11
|
|
|
* |
12
|
|
|
* @credits http://php-java-bridge.sourceforge.net/pjb/ |
13
|
|
|
* |
14
|
|
|
* @see http://github.com/belgattitude/soluble-japha |
15
|
|
|
* |
16
|
|
|
* @author Jost Boekemeier |
17
|
|
|
* @author Vanvelthem Sébastien (refactoring and fixes from original implementation) |
18
|
|
|
* @license MIT |
19
|
|
|
* |
20
|
|
|
* The MIT License (MIT) |
21
|
|
|
* Copyright (c) 2014-2017 Jost Boekemeier |
22
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
23
|
|
|
* of this software and associated documentation files (the "Software"), to deal |
24
|
|
|
* in the Software without restriction, including without limitation the rights |
25
|
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
26
|
|
|
* copies of the Software, and to permit persons to whom the Software is |
27
|
|
|
* furnished to do so, subject to the following conditions: |
28
|
|
|
* |
29
|
|
|
* The above copyright notice and this permission notice shall be included in |
30
|
|
|
* all copies or substantial portions of the Software. |
31
|
|
|
* |
32
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
33
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
34
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
35
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
36
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
37
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
38
|
|
|
* THE SOFTWARE. |
39
|
|
|
*/ |
40
|
|
|
|
41
|
|
|
namespace Soluble\Japha\Bridge\Driver\Pjb62; |
42
|
|
|
|
43
|
|
|
use Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException; |
44
|
|
|
use Soluble\Japha\Bridge\Exception\ConnectionException; |
45
|
|
|
|
46
|
|
|
class Protocol |
47
|
|
|
{ |
48
|
|
|
/** |
49
|
|
|
* @var Client |
50
|
|
|
*/ |
51
|
|
|
public $client; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @var string|null |
55
|
|
|
*/ |
56
|
|
|
public $webContext; |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @var string |
60
|
|
|
*/ |
61
|
|
|
public $serverName; |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* @var SimpleHttpHandler|HttpTunnelHandler|SocketHandler |
65
|
|
|
*/ |
66
|
|
|
public $handler; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* @var SocketHandler |
70
|
|
|
*/ |
71
|
|
|
protected $socketHandler; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* @var array |
75
|
|
|
*/ |
76
|
|
|
protected $host; |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @var string |
80
|
|
|
*/ |
81
|
|
|
protected $java_hosts; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @var string |
85
|
|
|
*/ |
86
|
|
|
protected $java_servlet; |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* @var int |
90
|
|
|
*/ |
91
|
|
|
public $java_recv_size; |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* @var int |
95
|
|
|
*/ |
96
|
|
|
public $java_send_size; |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @var string |
100
|
|
|
*/ |
101
|
|
|
protected $internal_encoding; |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* @param Client $client |
105
|
|
|
* @param string $java_hosts |
106
|
|
|
* @param string $java_servlet |
107
|
|
|
* @param int $java_recv_size |
108
|
|
|
* @param int $java_send_size |
109
|
|
|
*/ |
110
|
26 |
|
public function __construct(Client $client, $java_hosts, $java_servlet, $java_recv_size, $java_send_size) |
111
|
|
|
{ |
112
|
26 |
|
$this->client = $client; |
113
|
26 |
|
$this->internal_encoding = $client->getParam(Client::PARAM_JAVA_INTERNAL_ENCODING); |
114
|
26 |
|
$this->java_hosts = $java_hosts; |
115
|
26 |
|
$this->java_servlet = $java_servlet; |
116
|
26 |
|
$this->java_recv_size = $java_recv_size; |
117
|
26 |
|
$this->java_send_size = $java_send_size; |
118
|
26 |
|
$this->setHost($java_hosts); |
119
|
26 |
|
$this->handler = $this->createHandler(); |
120
|
24 |
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* @return Client |
124
|
|
|
*/ |
125
|
26 |
|
public function getClient(): Client |
126
|
|
|
{ |
127
|
26 |
|
return $this->client; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @return string |
132
|
|
|
*/ |
133
|
26 |
|
public function getOverrideHosts(): string |
134
|
|
|
{ |
135
|
26 |
|
if (array_key_exists('X_JAVABRIDGE_OVERRIDE_HOSTS', $_ENV)) { |
136
|
|
|
$override = $_ENV['X_JAVABRIDGE_OVERRIDE_HOSTS']; |
137
|
|
|
if (null !== $override && $override !== '/') { |
138
|
|
|
return $override; |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
|
142
|
26 |
|
return Pjb62Driver::getJavaBridgeHeader('X_JAVABRIDGE_OVERRIDE_HOSTS_REDIRECT', $_SERVER); |
143
|
|
|
} |
144
|
|
|
|
145
|
8 |
|
public function setSocketHandler(SocketHandler $socketHandler): void |
146
|
|
|
{ |
147
|
8 |
|
$this->socketHandler = $socketHandler; |
148
|
8 |
|
} |
149
|
|
|
|
150
|
8 |
|
/** |
151
|
|
|
* @throws BrokenConnectionException |
152
|
8 |
|
*/ |
153
|
|
|
public function getSocketHandler(): SocketHandler |
154
|
|
|
{ |
155
|
|
|
if ($this->socketHandler === null) { |
156
|
8 |
|
throw new BrokenConnectionException('No SocketHandler defined'); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
return $this->socketHandler; |
160
|
|
|
} |
161
|
|
|
|
162
|
26 |
|
/** |
163
|
|
|
* @param string $java_hosts |
164
|
26 |
|
*/ |
165
|
|
|
public function setHost(string $java_hosts): void |
166
|
26 |
|
{ |
167
|
26 |
|
$hosts = explode(';', $java_hosts); |
168
|
26 |
|
//$hosts = explode(";", JAVA_HOSTS); |
|
|
|
|
169
|
|
|
$host = explode(':', $hosts[0]); |
170
|
26 |
|
while (count($host) < 3) { |
171
|
|
|
array_unshift($host, ''); |
172
|
|
|
} |
173
|
26 |
|
if (substr($host[1], 0, 2) === '//') { |
174
|
26 |
|
$host[1] = substr($host[1], 2); |
175
|
|
|
} |
176
|
|
|
$this->host = $host; |
177
|
|
|
} |
178
|
|
|
|
179
|
26 |
|
/** |
180
|
|
|
* @return array |
181
|
26 |
|
*/ |
182
|
|
|
public function getHost(): array |
183
|
|
|
{ |
184
|
|
|
return $this->host; |
185
|
|
|
} |
186
|
|
|
|
187
|
26 |
|
/** |
188
|
|
|
* @return SimpleHttpHandler|HttpTunnelHandler |
189
|
26 |
|
*/ |
190
|
26 |
|
public function createHttpHandler() |
191
|
26 |
|
{ |
192
|
|
|
$overrideHosts = $this->getOverrideHosts(); |
193
|
|
|
$ssl = ''; |
194
|
|
|
if ($overrideHosts) { |
195
|
|
|
$s = $overrideHosts; |
196
|
|
|
if ((strlen($s) > 2) && ($s[1] === ':')) { |
197
|
|
|
if ($s[0] === 's') { |
198
|
|
|
$ssl = 'ssl://'; |
199
|
|
|
} |
200
|
|
|
$s = substr($s, 2); |
201
|
|
|
} |
202
|
|
|
$webCtx = strpos($s, '//'); |
203
|
|
|
if ($webCtx) { |
204
|
|
|
$host = substr($s, 0, $webCtx); |
205
|
|
|
} else { |
206
|
|
|
$host = $s; |
207
|
|
|
} |
208
|
|
|
$idx = strpos($host, ':'); |
209
|
|
|
if ($idx) { |
210
|
|
|
if ($webCtx) { |
211
|
|
|
$port = substr($host, $idx + 1, $webCtx); |
212
|
|
|
} else { |
213
|
|
|
$port = substr($host, $idx + 1); |
214
|
|
|
} |
215
|
|
|
$host = substr($host, 0, $idx); |
216
|
|
|
} else { |
217
|
|
|
$port = '8080'; |
218
|
|
|
} |
219
|
|
|
if ($webCtx) { |
220
|
|
|
$webCtx = substr($s, $webCtx + 1); |
221
|
26 |
|
} |
222
|
26 |
|
$this->webContext = $webCtx; |
223
|
|
|
} else { |
224
|
|
|
$hostVec = $this->getHost(); |
225
|
26 |
|
if ($ssl = $hostVec[0]) { |
226
|
26 |
|
$ssl .= '://'; |
227
|
|
|
} |
228
|
|
|
$host = $hostVec[1]; |
229
|
|
|
$port = $hostVec[2]; |
230
|
26 |
|
} |
231
|
26 |
|
$this->serverName = "${ssl}${host}:$port"; |
232
|
|
|
|
233
|
|
|
if ((array_key_exists('X_JAVABRIDGE_REDIRECT', $_SERVER)) || |
234
|
|
|
(array_key_exists('HTTP_X_JAVABRIDGE_REDIRECT', $_SERVER))) { |
235
|
26 |
|
return new SimpleHttpHandler($this, $ssl, $host, $port, $this->java_servlet, $this->java_recv_size, $this->java_send_size); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return new HttpTunnelHandler($this, $ssl, $host, $port, $this->java_servlet, $this->java_recv_size, $this->java_send_size); |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* @param string $channelName With format <host:port>. If host is omitted, '127.0.0.1' by default |
243
|
|
|
* |
244
|
|
|
* @throws ConnectionException |
245
|
|
|
* @throws Exception\IOException |
246
|
|
|
*/ |
247
|
|
|
public function createSimpleHandler(string $channelName): SocketHandler |
248
|
|
|
{ |
249
|
|
|
if (is_numeric($channelName)) { |
|
|
|
|
250
|
|
|
$host = '127.0.0.1'; |
251
|
|
|
$port = $channelName; |
252
|
|
|
} else { |
253
|
|
|
list($host, $port) = explode(':', $channelName); |
254
|
|
|
} |
255
|
|
|
$timeout = in_array($host, ['localhost', '127.0.0.1']) ? 5 : 20; |
256
|
|
|
$peer = pfsockopen($host, $port, $errno, $errstr, $timeout); |
257
|
|
|
if (!$peer) { |
|
|
|
|
258
|
|
|
throw new ConnectionException( |
259
|
|
|
sprintf( |
260
|
|
|
'No Java server at %s:%s. Error message: %s (errno: %s)', |
261
|
|
|
$host, |
262
|
|
|
$port, |
263
|
|
|
$errstr, |
264
|
|
|
$errno |
265
|
|
|
) |
266
|
|
|
); |
267
|
|
|
} |
268
|
|
|
|
269
|
26 |
|
stream_set_timeout($peer, -1); |
270
|
26 |
|
$handler = new SocketHandler($this, new SocketChannelP($peer, $host, $this->java_recv_size, $this->java_send_size)); |
271
|
|
|
$compatibility = PjbProxyClient::getInstance()->getCompatibilityOption($this->client); |
272
|
26 |
|
$this->write("\177$compatibility"); |
273
|
|
|
$this->serverName = "$host:$port"; |
274
|
|
|
|
275
|
|
|
return $handler; |
276
|
|
|
} |
277
|
|
|
|
278
|
26 |
|
public function java_get_simple_channel(): ?string |
279
|
|
|
{ |
280
|
26 |
|
$java_hosts = $this->java_hosts; |
281
|
|
|
$java_servlet = $this->java_servlet; |
282
|
|
|
|
283
|
26 |
|
return ($java_hosts && (!$java_servlet || ($java_servlet === 'Off'))) ? $java_hosts : null; |
284
|
|
|
} |
285
|
|
|
|
286
|
|
|
public function createHandler() |
287
|
|
|
{ |
288
|
|
|
if (!Pjb62Driver::getJavaBridgeHeader('X_JAVABRIDGE_OVERRIDE_HOSTS', $_SERVER) && |
289
|
113 |
|
//((function_exists('java_get_default_channel') && ($defaultChannel = java_get_default_channel())) || |
|
|
|
|
290
|
113 |
|
($defaultChannel = $this->java_get_simple_channel())) { |
291
|
|
|
return $this->createSimpleHandler($defaultChannel); |
292
|
|
|
} else { |
293
|
|
|
return $this->createHttpHandler(); |
294
|
|
|
} |
295
|
|
|
} |
296
|
|
|
|
297
|
114 |
|
public function redirect(): void |
298
|
|
|
{ |
299
|
|
|
$this->handler->redirect(); |
300
|
|
|
} |
301
|
|
|
|
302
|
129 |
|
/** |
303
|
129 |
|
* @return string |
304
|
129 |
|
*/ |
305
|
|
|
public function read(int $size): string |
306
|
129 |
|
{ |
307
|
|
|
return $this->handler->read($size); |
308
|
|
|
} |
309
|
|
|
|
310
|
129 |
|
public function sendData(): void |
311
|
129 |
|
{ |
312
|
|
|
if ($this->client->sendBuffer !== null) { |
313
|
|
|
$this->handler->write($this->client->sendBuffer); |
314
|
|
|
$this->client->sendBuffer = null; |
315
|
20 |
|
} |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
public function flush(): void |
319
|
|
|
{ |
320
|
20 |
|
$this->sendData(); |
321
|
7 |
|
} |
322
|
|
|
|
323
|
|
|
public function getKeepAlive(): string |
324
|
|
|
{ |
325
|
114 |
|
return $this->handler->getKeepAlive(); |
326
|
113 |
|
} |
327
|
|
|
|
328
|
|
|
public function keepAlive(): void |
329
|
|
|
{ |
330
|
|
|
$this->handler->keepAlive(); |
331
|
|
|
} |
332
|
|
|
|
333
|
114 |
|
public function handle(): void |
334
|
114 |
|
{ |
335
|
|
|
$this->client->handleRequests(); |
336
|
|
|
} |
337
|
|
|
|
338
|
114 |
|
/** |
339
|
114 |
|
* @param string $data |
340
|
113 |
|
*/ |
341
|
113 |
|
public function write($data): void |
342
|
|
|
{ |
343
|
|
|
$this->client->sendBuffer .= $data; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
public function finish(): void |
347
|
|
|
{ |
348
|
|
|
$this->flush(); |
349
|
24 |
|
$this->handle(); |
350
|
24 |
|
$this->redirect(); |
351
|
24 |
|
} |
352
|
24 |
|
|
353
|
24 |
|
/* |
354
|
24 |
|
* @param string $name java class name, i.e java.math.BigInteger |
355
|
24 |
|
*/ |
356
|
|
|
|
357
|
|
|
public function referenceBegin($name): void |
358
|
|
|
{ |
359
|
24 |
|
$this->client->sendBuffer .= $this->client->preparedToSendBuffer; |
360
|
24 |
|
$this->client->preparedToSendBuffer = null; |
361
|
24 |
|
$signature = sprintf('<H p="1" v="%s">', $name); |
362
|
24 |
|
$this->write($signature); |
363
|
24 |
|
$signature[6] = '2'; |
364
|
24 |
|
$this->client->currentArgumentsFormat = $signature; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
public function referenceEnd(): void |
368
|
|
|
{ |
369
|
|
|
$format = '</H>'; |
370
|
|
|
$this->client->currentArgumentsFormat .= $format; |
371
|
72 |
|
$this->write($format); |
372
|
72 |
|
$this->finish(); |
373
|
72 |
|
$this->client->currentCacheKey = null; |
374
|
72 |
|
} |
375
|
72 |
|
|
376
|
72 |
|
/** |
377
|
72 |
|
* @param string $name java class name i.e java.math.BigInteger |
378
|
|
|
*/ |
379
|
|
|
public function createObjectBegin($name): void |
380
|
|
|
{ |
381
|
72 |
|
$this->client->sendBuffer .= $this->client->preparedToSendBuffer; |
382
|
72 |
|
$this->client->preparedToSendBuffer = null; |
383
|
72 |
|
$signature = sprintf('<K p="1" v="%s">', $name); |
384
|
72 |
|
$this->write($signature); |
385
|
71 |
|
$signature[6] = '2'; |
386
|
71 |
|
$this->client->currentArgumentsFormat = $signature; |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
public function createObjectEnd(): void |
390
|
|
|
{ |
391
|
|
|
$format = '</K>'; |
392
|
|
|
$this->client->currentArgumentsFormat .= $format; |
393
|
|
|
$this->write($format); |
394
|
24 |
|
$this->finish(); |
395
|
24 |
|
$this->client->currentCacheKey = null; |
396
|
24 |
|
} |
397
|
24 |
|
|
398
|
24 |
|
/** |
399
|
|
|
* @param int $object object id |
400
|
|
|
* @param string $method method name |
401
|
|
|
*/ |
402
|
24 |
|
public function propertyAccessBegin($object, $method): void |
403
|
24 |
|
{ |
404
|
24 |
|
$this->client->sendBuffer .= $this->client->preparedToSendBuffer; |
405
|
24 |
|
$this->client->preparedToSendBuffer = null; |
406
|
24 |
|
$this->write(sprintf('<G p="1" v="%x" m="%s">', $object, $method)); |
407
|
24 |
|
$this->client->currentArgumentsFormat = "<G p=\"2\" v=\"%x\" m=\"${method}\">"; |
408
|
|
|
} |
409
|
|
|
|
410
|
|
|
public function propertyAccessEnd(): void |
411
|
|
|
{ |
412
|
|
|
$format = '</G>'; |
413
|
|
|
$this->client->currentArgumentsFormat .= $format; |
414
|
|
|
$this->write($format); |
415
|
106 |
|
$this->finish(); |
416
|
106 |
|
$this->client->currentCacheKey = null; |
417
|
106 |
|
} |
418
|
106 |
|
|
419
|
106 |
|
/** |
420
|
|
|
* @param int $object_id object id |
421
|
|
|
* @param string $method method name |
422
|
|
|
*/ |
423
|
106 |
|
public function invokeBegin($object_id, $method): void |
424
|
106 |
|
{ |
425
|
106 |
|
$this->client->sendBuffer .= $this->client->preparedToSendBuffer; |
426
|
106 |
|
$this->client->preparedToSendBuffer = null; |
427
|
106 |
|
$this->write(sprintf('<Y p="1" v="%x" m="%s">', $object_id, $method)); |
428
|
106 |
|
$this->client->currentArgumentsFormat = "<Y p=\"2\" v=\"%x\" m=\"${method}\">"; |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
public function invokeEnd(): void |
432
|
|
|
{ |
433
|
|
|
$format = '</Y>'; |
434
|
|
|
$this->client->currentArgumentsFormat .= $format; |
435
|
|
|
$this->write($format); |
436
|
|
|
$this->finish(); |
437
|
|
|
$this->client->currentCacheKey = null; |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
public function resultBegin(): void |
441
|
|
|
{ |
442
|
|
|
$this->client->sendBuffer .= $this->client->preparedToSendBuffer; |
443
|
|
|
$this->client->preparedToSendBuffer = null; |
444
|
|
|
$this->write('<R>'); |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
public function resultEnd(): void |
448
|
|
|
{ |
449
|
85 |
|
$this->client->currentCacheKey = null; |
450
|
85 |
|
$this->write('</R>'); |
451
|
85 |
|
$this->flush(); |
452
|
85 |
|
} |
453
|
|
|
|
454
|
|
|
/** |
455
|
|
|
* @param string $name |
456
|
|
|
*/ |
457
|
|
|
public function writeString($name): void |
458
|
|
|
{ |
459
|
3 |
|
$format = '<S v="%s"/>'; |
460
|
3 |
|
$this->client->currentArgumentsFormat .= $format; |
461
|
3 |
|
$this->write(sprintf($format, htmlspecialchars($name, ENT_COMPAT, $this->internal_encoding))); |
462
|
3 |
|
} |
463
|
|
|
|
464
|
|
|
/** |
465
|
|
|
* @param bool $boolean |
466
|
|
|
*/ |
467
|
|
|
public function writeBoolean($boolean): void |
468
|
|
|
{ |
469
|
25 |
|
$format = '<T v="%s"/>'; |
470
|
25 |
|
$this->client->currentArgumentsFormat .= $format; |
471
|
|
|
$this->write(sprintf($format, $boolean)); |
472
|
|
|
} |
473
|
25 |
|
|
474
|
|
|
/** |
475
|
25 |
|
* @param int $l |
476
|
|
|
*/ |
477
|
|
|
public function writeLong($l): void |
478
|
|
|
{ |
479
|
|
|
$this->client->currentArgumentsFormat .= '<J v="%d"/>'; |
480
|
|
|
if ($l < 0) { |
481
|
|
|
$this->write(sprintf('<L v="%x" p="A"/>', -$l)); |
482
|
|
|
} else { |
483
|
|
|
$this->write(sprintf('<L v="%x" p="O"/>', $l)); |
484
|
|
|
} |
485
|
|
|
} |
486
|
|
|
|
487
|
|
|
/** |
488
|
|
|
* @param mixed $l |
489
|
|
|
*/ |
490
|
|
|
public function writeULong($l): void |
491
|
|
|
{ |
492
|
4 |
|
$format = '<L v="%x" p="O"/>'; |
493
|
4 |
|
$this->client->currentArgumentsFormat .= $format; |
494
|
4 |
|
$this->write(sprintf($format, $l)); |
495
|
4 |
|
} |
496
|
|
|
|
497
|
|
|
/** |
498
|
|
|
* @param float $d |
499
|
|
|
*/ |
500
|
|
|
public function writeDouble($d): void |
501
|
|
|
{ |
502
|
98 |
|
$format = '<D v="%.14e"/>'; |
503
|
98 |
|
$this->client->currentArgumentsFormat .= $format; |
504
|
98 |
|
$this->write(sprintf($format, $d)); |
505
|
98 |
|
} |
506
|
|
|
|
507
|
|
|
/** |
508
|
|
|
* @param string|int|null $object |
509
|
|
|
*/ |
510
|
|
|
public function writeObject($object): void |
511
|
|
|
{ |
512
|
|
|
$format = '<O v="%x"/>'; |
513
|
|
|
$this->client->currentArgumentsFormat .= $format; |
514
|
|
|
$this->write(sprintf($format, $object)); |
515
|
|
|
} |
516
|
|
|
|
517
|
|
|
/** |
518
|
1 |
|
* @param int $object |
519
|
1 |
|
* @param string $str |
520
|
|
|
*/ |
521
|
|
|
public function writeException($object, $str): void |
522
|
|
|
{ |
523
|
13 |
|
$this->write(sprintf('<E v="%x" m="%s"/>', $object, htmlspecialchars($str, ENT_COMPAT, $this->internal_encoding))); |
524
|
13 |
|
} |
525
|
|
|
|
526
|
|
|
public function writeCompositeBegin_a(): void |
527
|
|
|
{ |
528
|
14 |
|
$this->write('<X t="A">'); |
529
|
14 |
|
} |
530
|
|
|
|
531
|
|
|
public function writeCompositeBegin_h(): void |
532
|
|
|
{ |
533
|
|
|
$this->write('<X t="H">'); |
534
|
|
|
} |
535
|
|
|
|
536
|
10 |
|
public function writeCompositeEnd(): void |
537
|
10 |
|
{ |
538
|
|
|
$this->write('</X>'); |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* @param string $key |
543
|
|
|
*/ |
544
|
7 |
|
public function writePairBegin_s($key): void |
545
|
7 |
|
{ |
546
|
|
|
$this->write(sprintf('<P t="S" v="%s">', htmlspecialchars($key, ENT_COMPAT, 'ISO-8859-1'))); |
547
|
|
|
} |
548
|
|
|
|
549
|
|
|
/** |
550
|
|
|
* @param int $key |
551
|
|
|
*/ |
552
|
|
|
public function writePairBegin_n($key): void |
553
|
|
|
{ |
554
|
13 |
|
$this->write(sprintf('<P t="N" v="%x">', $key)); |
555
|
13 |
|
} |
556
|
|
|
|
557
|
|
|
public function writePairBegin(): void |
558
|
|
|
{ |
559
|
|
|
$this->write('<P>'); |
560
|
|
|
} |
561
|
|
|
|
562
|
107 |
|
public function writePairEnd(): void |
563
|
107 |
|
{ |
564
|
107 |
|
$this->write('</P>'); |
565
|
107 |
|
} |
566
|
|
|
|
567
|
|
|
/** |
568
|
|
|
* @param int $object |
569
|
|
|
*/ |
570
|
|
|
public function writeUnref($object): void |
571
|
|
|
{ |
572
|
1 |
|
$this->client->sendBuffer .= $this->client->preparedToSendBuffer; |
573
|
|
|
$this->client->preparedToSendBuffer = null; |
574
|
|
|
$this->write(sprintf('<U v="%x"/>', $object)); |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
/** |
578
|
|
|
* @return string |
579
|
|
|
*/ |
580
|
|
|
public function getServerName(): string |
581
|
|
|
{ |
582
|
|
|
return $this->serverName; |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
/** |
586
|
|
|
* @param int $code |
587
|
|
|
*/ |
588
|
|
|
public function writeExitCode($code): void |
589
|
|
|
{ |
590
|
|
|
$this->client->sendBuffer .= $this->client->preparedToSendBuffer; |
591
|
|
|
$this->client->preparedToSendBuffer = null; |
592
|
|
|
$this->write(sprintf('<Z v="%x"/>', 0xffffffff & $code)); |
593
|
|
|
} |
594
|
|
|
} |
595
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.