Connection.php 22KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  1. <?php
  2. /**
  3. * Hoa
  4. *
  5. *
  6. * @license
  7. *
  8. * New BSD License
  9. *
  10. * Copyright © 2007-2017, Hoa community. All rights reserved.
  11. *
  12. * Redistribution and use in source and binary forms, with or without
  13. * modification, are permitted provided that the following conditions are met:
  14. * * Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * * Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * * Neither the name of the Hoa nor the names of its contributors may be
  20. * used to endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  24. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  25. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
  27. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  30. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  31. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  32. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33. * POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. namespace Hoa\Socket\Connection;
  36. use Hoa\Consistency;
  37. use Hoa\Socket;
  38. use Hoa\Stream;
  39. /**
  40. * Class \Hoa\Socket\Connection.
  41. *
  42. * Abstract connection, useful for client and server.
  43. *
  44. * @copyright Copyright © 2007-2017 Hoa community
  45. * @license New BSD License
  46. */
  47. abstract class Connection
  48. extends Stream
  49. implements Stream\IStream\In,
  50. Stream\IStream\Out,
  51. Stream\IStream\Pathable,
  52. \Iterator
  53. {
  54. /**
  55. * Read data out-of-band.
  56. *
  57. * @const int
  58. */
  59. const READ_OUT_OF_BAND = STREAM_OOB;
  60. /**
  61. * Read data but do not consume them.
  62. *
  63. * @const int
  64. */
  65. const READ_PEEK = STREAM_PEEK;
  66. /**
  67. * Socket.
  68. *
  69. * @var \Hoa\Socket
  70. */
  71. protected $_socket = null;
  72. /**
  73. * Timeout.
  74. *
  75. * @var int
  76. */
  77. protected $_timeout = 30;
  78. /**
  79. * Flag.
  80. *
  81. * @var int
  82. */
  83. protected $_flag = 0;
  84. /**
  85. * Context ID.
  86. *
  87. * @var string
  88. */
  89. protected $_context = null;
  90. /**
  91. * Node name.
  92. *
  93. * @var string
  94. */
  95. protected $_nodeName = 'Hoa\Socket\Node';
  96. /**
  97. * Current node.
  98. *
  99. * @var \Hoa\Socket\Node
  100. */
  101. protected $_node = null;
  102. /**
  103. * List of nodes (connections) when selecting.
  104. *
  105. * @var array
  106. */
  107. protected $_nodes = [];
  108. /**
  109. * Whether the stream is quiet.
  110. *
  111. * @var bool
  112. */
  113. protected $_quiet = false;
  114. /**
  115. * Whether the stream is mute.
  116. *
  117. * @var bool
  118. */
  119. protected $_mute = false;
  120. /**
  121. * Whether the stream is disconnected.
  122. *
  123. * @var bool
  124. */
  125. protected $_disconnect = true;
  126. /**
  127. * Whether we should consider remote address or not.
  128. *
  129. * @var bool
  130. */
  131. protected $_remote = false;
  132. /**
  133. * Remote address.
  134. *
  135. * @var string
  136. */
  137. protected $_remoteAddress = null;
  138. /**
  139. * Temporize selected connections when selecting.
  140. *
  141. * @var array
  142. */
  143. protected $_iterator = [];
  144. /**
  145. * Start a connection.
  146. *
  147. * @param string $socket Socket URI.
  148. * @param int $timeout Timeout.
  149. * @param int $flag Flag, see the child::* constants.
  150. * @param string $context Context ID (please, see the
  151. * \Hoa\Stream\Context class).
  152. */
  153. public function __construct($socket, $timeout, $flag, $context = null)
  154. {
  155. // Children could setSocket() before __construct.
  156. if (null !== $socket) {
  157. $this->setSocket($socket);
  158. }
  159. $this->setTimeout($timeout);
  160. $this->setFlag($flag);
  161. $this->setContext($context);
  162. return;
  163. }
  164. /**
  165. * Connect.
  166. *
  167. * @return \Hoa\Socket\Connection
  168. */
  169. public function connect()
  170. {
  171. parent::__construct(
  172. $this->getSocket()->__toString(),
  173. $this->getContext()
  174. );
  175. $this->_disconnect = false;
  176. return $this;
  177. }
  178. /**
  179. * Select connections.
  180. *
  181. * @return \Hoa\Socket\Connection
  182. */
  183. abstract public function select();
  184. /**
  185. * Consider another connection when selecting connection.
  186. *
  187. * @param \Hoa\Socket\Connection $other Other connection.
  188. * @return \Hoa\Socket\Connection
  189. */
  190. abstract public function consider(Connection $other);
  191. /**
  192. * Check if the current node belongs to a specific server.
  193. *
  194. * @param \Hoa\Socket\Connection $connection Connection.
  195. * @return bool
  196. */
  197. abstract public function is(Connection $connection);
  198. /**
  199. * Get iterator values.
  200. *
  201. * @return array
  202. */
  203. protected function &getIteratorValues()
  204. {
  205. return $this->_iterator;
  206. }
  207. /**
  208. * Set the current selected connection.
  209. *
  210. * @return resource
  211. */
  212. protected function _current()
  213. {
  214. $current = current($this->getIteratorValues());
  215. $this->_setStream($current);
  216. return $current;
  217. }
  218. /**
  219. * Set and get the current selected connection.
  220. *
  221. * @return \Hoa\Socket\Node
  222. */
  223. //abstract public function current();
  224. /**
  225. * Get the current selected connection index.
  226. *
  227. * @return int
  228. */
  229. public function key()
  230. {
  231. return key($this->getIteratorValues());
  232. }
  233. /**
  234. * Advance the internal pointer of the connection iterator and return the
  235. * current selected connection.
  236. *
  237. * @return mixed
  238. */
  239. public function next()
  240. {
  241. return next($this->getIteratorValues());
  242. }
  243. /**
  244. * Rewind the internal iterator pointer and the first connection.
  245. *
  246. * @return mixed
  247. */
  248. public function rewind()
  249. {
  250. return reset($this->getIteratorValues());
  251. }
  252. /**
  253. * Check if there is a current connection after calls to the rewind() or the
  254. * next() methods.
  255. *
  256. * @return bool
  257. */
  258. public function valid()
  259. {
  260. $iteratorValues = &$this->getIteratorValues();
  261. if (empty($iteratorValues)) {
  262. return false;
  263. }
  264. $key = key($iteratorValues);
  265. $return = (bool) next($iteratorValues);
  266. prev($iteratorValues);
  267. if (false === $return) {
  268. end($iteratorValues);
  269. if ($key === key($iteratorValues)) {
  270. $return = true;
  271. } else {
  272. $iteratorValues = [];
  273. }
  274. }
  275. return $return;
  276. }
  277. /**
  278. * Disable further receptions.
  279. *
  280. * @return bool
  281. */
  282. public function quiet()
  283. {
  284. return $this->_quiet =
  285. stream_socket_shutdown($this->getStream(), STREAM_SHUT_RD);
  286. }
  287. /**
  288. * Disable further transmissions.
  289. *
  290. * @return bool
  291. */
  292. public function mute()
  293. {
  294. return $this->_mute =
  295. stream_socket_shutdown($this->getStream(), STREAM_SHUT_WR);
  296. }
  297. /**
  298. * Disable further receptions and transmissions, i.e. disconnect.
  299. *
  300. * @return bool
  301. */
  302. public function quietAndMute()
  303. {
  304. return $this->_disconnect =
  305. stream_socket_shutdown($this->getStream(), STREAM_SHUT_RDWR);
  306. }
  307. /**
  308. * Disconnect.
  309. *
  310. * @return void
  311. */
  312. public function disconnect()
  313. {
  314. $this->_disconnect = $this->close();
  315. return;
  316. }
  317. /**
  318. * Set socket.
  319. *
  320. * @param string $socketUri Socket URI.
  321. * @return \Hoa\Socket
  322. * @throws \Hoa\Socket\Exception
  323. */
  324. protected function setSocket($socketUri)
  325. {
  326. if (false === $pos = strpos($socketUri, '://')) {
  327. $socket = new Socket($socketUri);
  328. } else {
  329. $transport = substr($socketUri, 0, $pos);
  330. $factory = Socket\Transport::getFactory($transport);
  331. $socket = $factory($socketUri);
  332. if (!($socket instanceof Socket)) {
  333. throw new Socket\Exception(
  334. 'The transport registered for scheme “%s” is not valid: ' .
  335. 'It must return a valid Hoa\Socket\Socket instance.',
  336. 0,
  337. $transport
  338. );
  339. }
  340. }
  341. $old = $this->_socket;
  342. $this->_socket = $socket;
  343. return $old;
  344. }
  345. /**
  346. * Set timeout.
  347. *
  348. * @param int $timeout Timeout.
  349. * @return int
  350. */
  351. protected function setTimeout($timeout)
  352. {
  353. $old = $this->_timeout;
  354. $this->_timeout = $timeout;
  355. return $old;
  356. }
  357. /**
  358. * Set flag.
  359. *
  360. * @param int $flag Flag.
  361. * @return int
  362. */
  363. protected function setFlag($flag)
  364. {
  365. $old = $this->_flag;
  366. $this->_flag = $flag;
  367. return $old;
  368. }
  369. /**
  370. * Set context.
  371. *
  372. * @param string $context Context ID.
  373. * @return string
  374. */
  375. protected function setContext($context)
  376. {
  377. $old = $this->_context;
  378. $this->_context = $context;
  379. return $old;
  380. }
  381. /**
  382. * Set node name.
  383. *
  384. * @param string $node Node name.
  385. * @return string
  386. */
  387. public function setNodeName($node)
  388. {
  389. $old = $this->_nodeName;
  390. $this->_nodeName = $node;
  391. return $old;
  392. }
  393. /**
  394. * Whether we should consider remote address or not.
  395. *
  396. * @param bool $consider Should we consider remote address or not.
  397. * @return bool
  398. */
  399. public function considerRemoteAddress($consider)
  400. {
  401. $old = $this->_remote;
  402. $this->_remote = $consider;
  403. return $old;
  404. }
  405. /**
  406. * Enable or disable encryption.
  407. *
  408. * @param bool $enable Whether enable encryption.
  409. * @param int $type Type of encryption (please, see
  410. * children ENCRYPTION_* constants).
  411. * @param resource $sessionStream Seed the stream with settings from
  412. * this session stream.
  413. * @return bool
  414. */
  415. public function enableEncryption(
  416. $enable,
  417. $type = null,
  418. $sessionStream = null
  419. ) {
  420. $currentNode = $this->getCurrentNode();
  421. if (null === $currentNode) {
  422. return false;
  423. }
  424. if (null === $type &&
  425. null === $type = $currentNode->getEncryptionType()) {
  426. return stream_socket_enable_crypto($this->getStream(), $enable);
  427. }
  428. $currentNode->setEncryptionType($type);
  429. if (null === $sessionStream) {
  430. return stream_socket_enable_crypto(
  431. $this->getStream(),
  432. $enable,
  433. $type
  434. );
  435. }
  436. return stream_socket_enable_crypto(
  437. $this->getStream(),
  438. $enable,
  439. $type,
  440. $sessionStream
  441. );
  442. }
  443. /**
  444. * Check if the connection is encrypted or not.
  445. *
  446. * @return mixed
  447. */
  448. public function isEncrypted()
  449. {
  450. $currentNode = $this->getCurrentNode();
  451. if (null === $currentNode) {
  452. return false;
  453. }
  454. return null !== $currentNode->getEncryptionType();
  455. }
  456. /**
  457. * Get socket.
  458. *
  459. * @return \Hoa\Socket
  460. */
  461. public function getSocket()
  462. {
  463. return $this->_socket;
  464. }
  465. /**
  466. * Get timeout.
  467. *
  468. * @return int
  469. */
  470. public function getTimeout()
  471. {
  472. return $this->_timeout;
  473. }
  474. /**
  475. * Get flag.
  476. *
  477. * @return int
  478. */
  479. public function getFlag()
  480. {
  481. return $this->_flag;
  482. }
  483. /**
  484. * Get context.
  485. *
  486. * @return string
  487. */
  488. public function getContext()
  489. {
  490. return $this->_context;
  491. }
  492. /**
  493. * Get node name.
  494. *
  495. * @return string
  496. */
  497. public function getNodeName()
  498. {
  499. return $this->_nodeName;
  500. }
  501. /**
  502. * Get node ID.
  503. *
  504. * @param resource $resource Resource.
  505. * @return string
  506. */
  507. protected function getNodeId($resource)
  508. {
  509. return md5((int) $resource);
  510. }
  511. /**
  512. * Get current node.
  513. *
  514. * @return \Hoa\Socket\Node
  515. */
  516. public function getCurrentNode()
  517. {
  518. return $this->_node;
  519. }
  520. /**
  521. * Get nodes list.
  522. *
  523. * @return array
  524. */
  525. public function getNodes()
  526. {
  527. return $this->_nodes;
  528. }
  529. /**
  530. * Check if the stream is quiet.
  531. *
  532. * @return bool
  533. */
  534. public function isQuiet()
  535. {
  536. return $this->_quiet;
  537. }
  538. /**
  539. * Check if the stream is mute.
  540. *
  541. * @return bool
  542. */
  543. public function isMute()
  544. {
  545. return $this->_mute;
  546. }
  547. /**
  548. * Check if the stream is disconnected.
  549. *
  550. * @return bool
  551. */
  552. public function isDisconnected()
  553. {
  554. return false !== $this->_disconnect;
  555. }
  556. /**
  557. * Check if we should consider remote address or not.
  558. *
  559. * @return bool
  560. */
  561. public function isRemoteAddressConsidered()
  562. {
  563. return $this->_remote;
  564. }
  565. /**
  566. * Get remote address.
  567. *
  568. * @return string
  569. */
  570. public function getRemoteAddress()
  571. {
  572. return $this->_remoteAddress;
  573. }
  574. /**
  575. * Read n characters.
  576. * Warning: if this method returns false, it means that the buffer is empty.
  577. * You should use the Hoa\Stream::setStreamBlocking(true) method.
  578. *
  579. * @param int $length Length.
  580. * @param int $flags Flags.
  581. * @return string
  582. * @throws \Hoa\Socket\Exception
  583. */
  584. public function read($length, $flags = 0)
  585. {
  586. if (null === $this->getStream()) {
  587. throw new Socket\Exception(
  588. 'Cannot read because socket is not established, ' .
  589. 'i.e. not connected.',
  590. 1
  591. );
  592. }
  593. if (0 > $length) {
  594. throw new Socket\Exception(
  595. 'Length must be greater than 0, given %d.',
  596. 2,
  597. $length
  598. );
  599. }
  600. if (true === $this->isEncrypted()) {
  601. return fread($this->getStream(), $length);
  602. }
  603. if (false === $this->isRemoteAddressConsidered()) {
  604. return stream_socket_recvfrom($this->getStream(), $length, $flags);
  605. }
  606. $out = stream_socket_recvfrom(
  607. $this->getStream(),
  608. $length,
  609. $flags,
  610. $address
  611. );
  612. $this->_remoteAddress = !empty($address) ? $address : null;
  613. return $out;
  614. }
  615. /**
  616. * Alias of $this->read().
  617. *
  618. * @param int $length Length.
  619. * @return string
  620. */
  621. public function readString($length)
  622. {
  623. return $this->read($length);
  624. }
  625. /**
  626. * Read a character.
  627. * It is equivalent to $this->read(1).
  628. *
  629. * @return string
  630. */
  631. public function readCharacter()
  632. {
  633. return $this->read(1);
  634. }
  635. /**
  636. * Read a boolean.
  637. *
  638. * @return bool
  639. */
  640. public function readBoolean()
  641. {
  642. return (bool) $this->read(1);
  643. }
  644. /**
  645. * Read an integer.
  646. *
  647. * @param int $length Length.
  648. * @return int
  649. */
  650. public function readInteger($length = 1)
  651. {
  652. return (int) $this->read($length);
  653. }
  654. /**
  655. * Read a float.
  656. *
  657. * @param int $length Length.
  658. * @return float
  659. */
  660. public function readFloat($length = 1)
  661. {
  662. return (float) $this->read($length);
  663. }
  664. /**
  665. * Read an array.
  666. * Alias of the $this->scanf() method.
  667. *
  668. * @param string $format Format (see printf's formats).
  669. * @return array
  670. */
  671. public function readArray($format = null)
  672. {
  673. return $this->scanf($format);
  674. }
  675. /**
  676. * Read a line.
  677. *
  678. * @return string
  679. */
  680. public function readLine()
  681. {
  682. if (true === $this->isEncrypted()) {
  683. return rtrim(fgets($this->getStream(), 1 << 15), "\n");
  684. }
  685. return stream_get_line($this->getStream(), 1 << 15, "\n");
  686. }
  687. /**
  688. * Read all, i.e. read as much as possible.
  689. *
  690. * @param int $offset Offset (not used).
  691. * @return string
  692. */
  693. public function readAll($offset = -1)
  694. {
  695. return stream_get_contents($this->getStream());
  696. }
  697. /**
  698. * Parse input from a stream according to a format.
  699. *
  700. * @param string $format Format (see printf's formats).
  701. * @return array
  702. */
  703. public function scanf($format)
  704. {
  705. return sscanf($this->readAll(), $format);
  706. }
  707. /**
  708. * Write n characters.
  709. *
  710. * @param string $string String.
  711. * @param int $length Length.
  712. * @return mixed
  713. * @throws \Hoa\Socket\Exception
  714. * @throws \Hoa\Socket\Exception\BrokenPipe
  715. */
  716. public function write($string, $length)
  717. {
  718. if (null === $this->getStream()) {
  719. throw new Socket\Exception(
  720. 'Cannot write because socket is not established, ' .
  721. 'i.e. not connected.',
  722. 3
  723. );
  724. }
  725. if (0 > $length) {
  726. throw new Socket\Exception(
  727. 'Length must be greater than 0, given %d.',
  728. 4,
  729. $length
  730. );
  731. }
  732. if (strlen($string) > $length) {
  733. $string = substr($string, 0, $length);
  734. }
  735. if (true === $this->isEncrypted()) {
  736. $out = fwrite($this->getStream(), $string, $length);
  737. } else {
  738. if (false === $this->isRemoteAddressConsidered() ||
  739. null === $remote = $this->getRemoteAddress()) {
  740. $out = @stream_socket_sendto($this->getStream(), $string);
  741. } else {
  742. $out = @stream_socket_sendto(
  743. $this->getStream(),
  744. $string,
  745. 0,
  746. $remote
  747. );
  748. }
  749. }
  750. if (-1 === $out) {
  751. throw new Socket\Exception\BrokenPipe(
  752. 'Pipe is broken, cannot write data.',
  753. 5
  754. );
  755. }
  756. return $out;
  757. }
  758. /**
  759. * Write a string.
  760. *
  761. * @param string $string String.
  762. * @return mixed
  763. */
  764. public function writeString($string)
  765. {
  766. $string = (string) $string;
  767. return $this->write($string, strlen($string));
  768. }
  769. /**
  770. * Write a character.
  771. *
  772. * @param string $char Character.
  773. * @return mixed
  774. */
  775. public function writeCharacter($char)
  776. {
  777. return $this->write((string) $char[0], 1);
  778. }
  779. /**
  780. * Write a boolean.
  781. *
  782. * @param bool $boolean Boolean.
  783. * @return mixed
  784. */
  785. public function writeBoolean($boolean)
  786. {
  787. return $this->write((string) (bool) $boolean, 1);
  788. }
  789. /**
  790. * Write an integer.
  791. *
  792. * @param int $integer Integer.
  793. * @return mixed
  794. */
  795. public function writeInteger($integer)
  796. {
  797. $integer = (string) (int) $integer;
  798. return $this->write($integer, strlen($integer));
  799. }
  800. /**
  801. * Write a float.
  802. *
  803. * @param float $float Float.
  804. * @return mixed
  805. */
  806. public function writeFloat($float)
  807. {
  808. $float = (string) (float) $float;
  809. return $this->write($float, strlen($float));
  810. }
  811. /**
  812. * Write a line.
  813. *
  814. * @param string $line Line.
  815. * @return mixed
  816. */
  817. public function writeLine($line)
  818. {
  819. if (false === $n = strpos($line, "\n")) {
  820. return $this->write($line . "\n", strlen($line) + 1);
  821. }
  822. ++$n;
  823. return $this->write(substr($line, 0, $n), $n);
  824. }
  825. /**
  826. * Write an array.
  827. *
  828. * @param array $array Array.
  829. * @return mixed
  830. */
  831. public function writeArray(array $array)
  832. {
  833. $array = serialize($array);
  834. return $this->write($array, strlen($array));
  835. }
  836. /**
  837. * Write all, i.e. as much as possible.
  838. *
  839. * @param string $string String.
  840. * @return mixed
  841. */
  842. public function writeAll($string)
  843. {
  844. return $this->write($string, strlen($string));
  845. }
  846. /**
  847. * Truncate a file to a given length.
  848. *
  849. * @param int $size Size.
  850. * @return bool
  851. */
  852. public function truncate($size)
  853. {
  854. return false;
  855. }
  856. /**
  857. * Test for end-of-file.
  858. *
  859. * @return bool
  860. */
  861. public function eof()
  862. {
  863. return feof($this->getStream());
  864. }
  865. /**
  866. * Get filename component of path.
  867. *
  868. * @return string
  869. */
  870. public function getBasename()
  871. {
  872. return basename($this->getSocket()->__toString());
  873. }
  874. /**
  875. * Get directory name component of path.
  876. *
  877. * @return string
  878. */
  879. public function getDirname()
  880. {
  881. return dirname($this->getSocket()->__toString());
  882. }
  883. }
  884. /**
  885. * Flex entity.
  886. */
  887. Consistency::flexEntity('Hoa\Socket\Connection\Connection');