/** * Invoke match. Returns the handler's result for the first condition to * match the given value. If no condition matched and no default handler * was installed, an exception is raised. * * @param var $value * @return var * @throws lang.IllegalArgumentException */ public function __invoke($value) { if ($this->mapping) { $f = $this->mapping; $expr = $f($value); } else { $expr = $value; } if (null === $expr) { $type = null; } else { $type = gettype($expr); } if (isset($this->primitive[$type])) { return $this->primitive[$type]($value, $this); } else { foreach ($this->instance as $conditional) { if ($conditional->condition->matches($expr)) { $f = $conditional->handle; return $f($value, $this); } } } if ($this->otherwise) { $f = $this->otherwise; return $f($value, $this); } else { throw new IllegalArgumentException('Unhandled type ' . \xp::typeOf($expr)); } }
/** * Set a LogCategory for tracing communication * * @param util.log.LogCategory $cat pass NULL to stop tracing * @return void * @throws lang.IllegalArgumentException in case a of a type mismatch */ public function setTrace($cat) { if (null !== $cat && !$cat instanceof LogCategory) { throw new IllegalArgumentException('Expected a LogCategory, have ' . \xp::typeOf($cat)); } $this->cat = $cat; }
/** * Send a message * * @param peer.mail.Message message the Message object to send * @return bool success */ public function send($message) { // Sanity check: Is this a message? if (!$message instanceof Message) { throw new TransportException('Can only send messages (given: ' . xp::typeOf($message) . ')', new IllegalArgumentException('Parameter message is not a Message object')); } // Sanity check: Do we have at least one recipient? $to = ''; for ($i = 0, $s = sizeof($message->to); $i < $s; $i++) { if (!$message->to[$i] instanceof InternetAddress) { continue; } // Ignore! $to .= $message->to[$i]->toString($message->getCharset()) . ', '; } if (empty($to)) { throw new TransportException('No recipients defined (recipients[0]: ' . xp::typeOf($message->to[0]), new IllegalArgumentException('Recipient #0 is not an InternetAddress object')); } // Copy message and unset To / Subject. PHPs mail() function will add them // to the mail twice, otherwise $tmp = clone $message; unset($tmp->to); unset($tmp->subject); if (FALSE === mail(substr($to, 0, -2), QuotedPrintable::encode($message->getSubject(), $message->getCharset()), strtr($message->getBody(), array("\r\n" => "\n", "\r" => "\n")), rtrim($tmp->getHeaderString(), "\n"), $this->parameters)) { throw new TransportException('Could not send mail to ' . xp::stringOf($message->to[0]), new IOException('Call to mail() failed')); } return TRUE; }
/** * Constructor * * @param var stream either an io.streams.OutputStream or an io.Stream (BC) * @throws lang.IllegalArgumentException when types are not met */ public function __construct($stream) { $this->stream = deref($stream); if ($this->stream instanceof OutputStream) { // Already open } else { if ($this->stream instanceof Stream) { $this->stream->open(STREAM_MODE_WRITE); } else { throw new IllegalArgumentException('Expected either an io.streams.OutputStream or an io.Stream, have ' . xp::typeOf($this->stream)); } } if (self::$GD_USERSTREAMS_BUG) { $this->writer = function ($writer, $stream, $handle) { ob_start(); $r = $writer->output($handle); if ($r) { $stream->write(ob_get_contents()); } ob_end_clean(); return $r; }; } else { // Use output buffering with a callback method to capture the // image(gd|jpeg|png|...) functions' output. $this->writer = function ($writer, $stream, $handle) { ob_start(function ($data) use($stream) { $stream->write($data); }); $r = $writer->output($handle); ob_end_flush(); return $r; }; } }
/** * Constructor * * @param var $arg either an io.streams.OutputStream, an io.File or an io.Stream (BC) * @throws lang.IllegalArgumentException when types are not met */ public function __construct($arg) { if ($arg instanceof OutputStream) { $this->write($arg); } else { if ($arg instanceof File) { $this->write($arg->out()); } else { if ($arg instanceof Stream) { // BC $this->stream = $arg; $this->writer = function ($writer, $stream, $handle) { ob_start(); if ($r = $writer->output($handle)) { $stream->open(STREAM_MODE_WRITE); $stream->write(ob_get_contents()); $stream->close(); } ob_end_clean(); return $r; }; } else { throw new IllegalArgumentException('Expected either an io.streams.OutputStream or an io.File, have ' . \xp::typeOf($arg)); } } } }
/** * Checks all entries in an array for correct type * * @param string type * @param &array array * @throws lang.IllegalArgumentException */ protected function _assertSubtype($type, $array) { foreach (array_keys($array) as $key) { if ($type != xp::typeOf($array[$key])) { throw new IllegalArgumentException('Object (in array) not of expected type ' . $type . ', but ' . xp::typeOf($array[$key]) . ' with value ' . var_export($array[$key], 1)); } } }
/** * Creates a string representation of this handler * * @return string */ public function toString() { $s = sprintf("%s@{\n" . " [name ] %s\n" . " [identifier ] %s\n" . " [wrapper ] %s\n", nameof($this), $this->name, $this->identifier, $this->wrapper ? nameof($this->wrapper) : '(null)'); foreach (array_keys($this->values[HVAL_PERSISTENT]) as $key) { $s .= sprintf(" [%-20s] %s\n", $key, \xp::typeOf($this->values[$key])); } return $s . '}'; }
/** * Add a Mime Part * * @param peer.mail.MimePart part * @return peer.mail.MimePart the part added * @throws lang.IllegalArgumentException if part argument is not a peer.mail.MimePart */ public function addPart($part) { if (!$part instanceof MimePart) { throw new IllegalArgumentException('Parameter part is not a peer.mail.MimePart (given: ' . \xp::typeOf($part) . ')'); } $this->parts[] = $part; return $part; }
/** * Define handler for a given key * * @param var $key Either a string or an integer * @param function(?): var $function * @return self */ public function when($key, $function) { if (is_string($key) || is_int($key)) { $this->hash[$key] = self::$HANDLE->cast($function); } else { throw new IllegalArgumentException('Illegal key type ' . \xp::typeOf($key)); } return $this; }
/** * Box parameter into soap equivalent * * @param lang.Generic object * @return mixed * @throws lang.IllegalArgumentException if type is not supported */ public function box($object) { foreach ($this->handler as $handler => $t) { if (!$object instanceof $handler) { continue; } return call_user_func(array($this, 'box' . $handler), $object); } throw new IllegalArgumentException('Type ' . xp::typeOf($object) . ' is not supported.'); }
/** * Box parameter into soap equivalent * * @param lang.Generic object * @return mixed * @throws lang.IllegalArgumentException if type is not supported */ public function box($object) { foreach ($this->handler as $class => $handler) { if (!$object instanceof $class) { continue; } return call_user_func([$this, $handler], $object); } throw new \lang\IllegalArgumentException('Type ' . \xp::typeOf($object) . ' is not supported.'); }
/** * Initializes the attribute with default values, depending on $type * */ public function initialize() { // determine type from value if type is not set if (isset($this->_value)) { if (!isset($this->_type)) { $this->_type = xp::typeOf($this->_value); } if ($this->_type === 'integer') { $this->_type = 'int'; } if (in_array($this->_type, array('float', 'double'))) { $this->_type = 'real'; } if ($this->_type === 'bool') { $this->_type = 'boolean'; } $value = $this->_value; } else { $value = NULL; } // set type if defined if (isset($this->_type)) { switch ($this->_type) { case 'int': $this->set('value', new DiaInt($value)); break; case 'real': $this->set('value', new DiaReal($value)); break; case 'string': $this->set('value', new DiaString($value)); break; case 'boolean': $this->set('value', new DiaBoolean($value)); break; case 'enum': $this->set('value', new DiaEnum($value)); break; case 'point': $this->set('value', new DiaPoint($value)); break; case 'rectangle': $this->set('value', new DiaRectangle($value)); break; case 'font': $this->set('value', new DiaFont($value)); break; case 'color': $this->set('value', new DiaColor($value)); break; default: throw new IllegalArgumentException('Unkown type "' . $this->_type . '"'); } } }
/** * Constructor * * @param var stream either an io.streams.OutputStream or an io.Stream (BC) * @throws lang.IllegalArgumentException when types are not met */ public function __construct($stream) { $this->stream = deref($stream); if ($this->stream instanceof OutputStream) { // Already open } else { if ($this->stream instanceof Stream) { $this->stream->open(STREAM_MODE_WRITE); } else { throw new IllegalArgumentException('Expected either an io.streams.OutputStream or an io.Stream, have ' . xp::typeOf($this->stream)); } } }
/** * Constructor. Creates a new TextWriter on an underlying output * stream with a given charset. * * @param io.streams.OutputStream|io.Channel $arg The target * @param string $charset the charset the stream is encoded in. * @throws lang.IllegalArgumentException */ public function __construct($arg, $charset = \xp::ENCODING) { if ($arg instanceof OutputStream) { parent::__construct($arg); } else { if ($arg instanceof Channel) { parent::__construct($arg->out()); } else { throw new IllegalArgumentException('Given argument is neither an input stream, a channel nor a string: ' . \xp::typeOf($arg)); } } $this->charset = $charset; }
/** * Substract a TimeSpan * * @param util.TimeSpan... args * @return util.TimeSpan * @throws lang.IllegalStateException if the result would be a negative timespan */ public function substract() { foreach (func_get_args() as $span) { if (!$span instanceof self) { throw new IllegalArgumentException('Given argument is not a TimeSpan: ' . xp::typeOf($span)); } if ($span->_seconds > $this->_seconds) { throw new IllegalStateException('Cannot subtract ' . $span->toString() . ' from ' . $this->toString()); } $this->_seconds -= $span->_seconds; } return $this; }
/** * Invokes the underlying method represented by this Method object, * on the specified object with the specified parameters. * * Example: * <code> * $method= XPClass::forName('lang.Object')->getMethod('toString'); * * var_dump($method->invoke(new Object())); * </code> * * Example (passing arguments) * <code> * $method= XPClass::forName('lang.types.String')->getMethod('concat'); * * var_dump($method->invoke(new String('Hello'), array('World'))); * </code> * * Example (static invokation): * <code> * $method= XPClass::forName('util.log.Logger')->getMethod('getInstance'); * * var_dump($method->invoke(NULL)); * </code> * * @param lang.Object obj * @param var[] args default array() * @return var * @throws lang.IllegalArgumentException in case the passed object is not an instance of the declaring class * @throws lang.IllegalAccessException in case the method is not public or if it is abstract * @throws lang.reflect.TargetInvocationException for any exception raised from the invoked method */ public function invoke($obj, $args = array()) { if (NULL !== $obj && !$obj instanceof $this->_class) { throw new IllegalArgumentException(sprintf('Passed argument is not a %s class (%s)', xp::nameOf($this->_class), xp::typeOf($obj))); } // Check modifiers. If caller is an instance of this class, allow // protected method invocation (which the PHP reflection API does // not). $m = $this->_reflect->getModifiers(); if ($m & MODIFIER_ABSTRACT) { throw new IllegalAccessException(sprintf('Cannot invoke abstract %s::%s', $this->_class, $this->_reflect->getName())); } $public = $m & MODIFIER_PUBLIC; if (!$public && !$this->accessible) { $t = debug_backtrace(0); $decl = $this->_reflect->getDeclaringClass()->getName(); if ($m & MODIFIER_PROTECTED) { $allow = $t[1]['class'] === $decl || is_subclass_of($t[1]['class'], $decl); } else { $allow = $t[1]['class'] === $decl && self::$SETACCESSIBLE_AVAILABLE; } if (!$allow) { throw new IllegalAccessException(sprintf('Cannot invoke %s %s::%s from scope %s', Modifiers::stringOf($this->getModifiers()), $this->_class, $this->_reflect->getName(), $t[1]['class'])); } } // For non-public methods: Use setAccessible() / invokeArgs() combination // if possible, resort to __call() workaround. try { if ($public) { return $this->_reflect->invokeArgs($obj, (array) $args); } if (self::$SETACCESSIBLE_AVAILABLE) { $this->_reflect->setAccessible(TRUE); return $this->_reflect->invokeArgs($obj, (array) $args); } else { if ($m & MODIFIER_STATIC) { return call_user_func(array($this->_class, '__callStatic'), "" . $this->_reflect->getName(), $args); } else { return $obj->__call("" . $this->_reflect->getName(), $args); } } } catch (SystemExit $e) { throw $e; } catch (Throwable $e) { throw new TargetInvocationException($this->_class . '::' . $this->_reflect->getName(), $e); } catch (Exception $e) { throw new TargetInvocationException($this->_class . '::' . $this->_reflect->getName(), new XPException($e->getMessage())); } }
public function __construct(array $list = [], $accept = null) { $this->list = $list; if (null === $accept) { $this->accept = function ($list, $e) { throw new IllegalStateException('No accepting closure set'); }; } else { if ($accept instanceof \Closure) { $this->accept = $accept; } else { throw new IllegalArgumentException('Expecting either a closure or null, ' . \xp::typeOf($accept) . ' given'); } } }
/** * Processes a method invocation on a proxy instance and returns * the result. * * @param lang.reflect.Proxy $proxy * @param string $method the method name * @param var... $args an array of arguments * @return var * @throws util.DeferredInitializationException */ public function invoke($proxy, $method, $args) { if (null === $this->_instance) { try { $this->_instance = $this->initialize(); } catch (Throwable $e) { $this->_instance = null; throw new DeferredInitializationException($method, $e); } if (!is_object($this->_instance)) { throw new DeferredInitializationException($method, new ClassCastException('Initializer returned ' . \xp::typeOf($this->_instance))); } } return $this->_instance->{$method}(...$args); }
/** * Processes a method invocation on a proxy instance and returns * the result. * * @param lang.reflect.Proxy proxy * @param string method the method name * @param var* args an array of arguments * @return var * @throws util.DeferredInitializationException */ public function invoke($proxy, $method, $args) { if (NULL === $this->_instance) { try { $this->_instance = $this->initialize(); } catch (Throwable $e) { $this->_instance = NULL; throw new DeferredInitializationException($method, $e); } if (!$this->_instance instanceof Generic) { throw new DeferredInitializationException($method, XPClass::forName('lang.ClassCastException')->newInstance('Initializer returned ' . xp::typeOf($this->_instance))); } } return call_user_func_array(array($this->_instance, $method), $args); }
/** * Factory method * * @param var arg either an InputStream, File, or IOElement * @return self * @throws lang.IllegalArgumentException */ public static function of($arg) { if ($arg instanceof InputStream) { return new self($arg); } else { if ($arg instanceof File) { return create(new self($arg->getInputStream()))->withMediaType(MimeType::getByFileName($arg->getFileName()))->withContentLength($arg->getSize())->withLastModified(new Date($arg->lastModified())); } else { if ($arg instanceof IOElement) { return create(new self($arg->getInputStream()))->withMediaType(MimeType::getByFileName($arg->getURI()))->withContentLength($arg->getSize())->withLastModified($arg->lastModified()); } else { throw new IllegalArgumentException('Expected either an InputStream, File, or IOElement, have ' . xp::typeOf($arg)); } } } }
/** * Return XML representation of DiaComposite * * @return &xml.Node */ public function getNode() { $node = parent::getNode(); // TODO: the value should always be 'boolean'! if (isset($this->value)) { if (xp::typeOf($this->value) === 'boolean') { $node->setAttribute('val', $this->value ? 'true' : 'false'); } else { $node->setAttribute('val', $this->value === 'true' ? 'true' : 'false'); } } else { $node->setAttribute('val', 'false'); // default } return $node; }
/** * Constructor. Accepts the following types as argument: * <ul> * <li>A string containing the XML</li> * <li>A DomDocument object (as returned by domxml_open_mem, e.g.)</li> * <li>An xml.Tree object</li> * </ul> * * @param var arg * @throws lang.IllegalArgumentException * @throws xml.XMLFormatException in case the argument is a string and not valid XML */ public function __construct($arg) { if ($arg instanceof DOMDocument) { $this->context = new DOMXPath($arg); } else { if ($arg instanceof Tree) { $this->context = new DOMXPath($this->loadXML($arg->getDeclaration() . $arg->getSource(INDENT_NONE))); } else { if (is_string($arg)) { $this->context = new DOMXPath($this->loadXML($arg)); } else { throw new IllegalArgumentException('Unsupported parameter type ' . xp::typeOf($arg)); } } } }
/** * Update method * * @param util.Observable obs * @param var arg default NULL */ public function update($obs, $arg = null) { if (!$obs instanceof DBConnection) { throw new \lang\IllegalArgumentException('Argument 1 must be instanceof "rdbms.DBConnection", "' . \xp::typeOf($obs) . '" given.'); } if (!$arg instanceof DBEvent) { return; } // Store reference for later reuse if (null === $this->cat) { $this->setTrace(Logger::getInstance()->getCategory($this->name)); } if (null === $this->dsn) { $this->dsn = $obs->getDSN()->withoutPassword(); } $method = $arg->getName(); switch ($method) { case 'query': case 'open': $this->lastq = $this->typeOf($arg->getArgument()); // Fallthrough intentional // Fallthrough intentional case 'connect': if ('connect' == $method) { $this->lastq = $method; } $this->timer = new Timer(); $this->timer->start(); // Count some well-known SQL keywords $this->countFor($this->lastq); break; case 'connected': case 'queryend': // Protect against illegal order of events (should not occur) if (!$this->timer) { return; } $this->timer->stop(); $this->addElapsedTimeTo($method, $this->timer->elapsedTime()); if ($this->lastq) { $this->addElapsedTimeTo($this->lastq, $this->timer->elapsedTime()); $this->lastq = null; } $this->timer = null; break; } }
/** * Constructor * * @param var initial default NULL * @throws lang.IllegalArgumentException in case argument is of incorrect type. */ public function __construct($initial = null) { if (null === $initial) { // Intentionally empty } else { if (is_array($initial)) { $this->buffer = implode('', array_map([$this, 'asByte'], $initial)); } else { if (is_string($initial)) { $this->buffer = $initial; } else { throw new \lang\IllegalArgumentException('Expected either Byte[], char[], int[] or string but was ' . \xp::typeOf($initial)); } } } $this->size = strlen($this->buffer); }
/** * Creates a new timezone from a given name. * * @param string timezone name or NULL to use default timezone * @throws lang.IllegalArgumentException if timezone is unknown */ public function __construct($tz) { if (null === $tz) { $this->tz = timezone_open(date_default_timezone_get()); } else { if (is_string($tz)) { try { $this->tz = new \DateTimeZone($tz); } catch (\Throwable $e) { throw new IllegalArgumentException('Invalid timezone identifier given: ' . $e->getMessage()); } } else { if ($tz instanceof \DateTimeZone) { $this->tz = $tz; } else { throw new IllegalArgumentException('Expecting NULL, a string or a DateTimeZone instance, have ' . \xp::typeOf($tz)); } } } }
/** * Constructor * * @param var stream either an io.streams.InputStream or an io.Stream (BC) * @throws lang.IllegalArgumentException when types are not met */ public function __construct($stream) { $this->stream = deref($stream); if ($this->stream instanceof InputStream) { if ($this instanceof img·io·UriReader && !self::$GD_USERSTREAMS_BUG) { $this->reader = function ($reader, $stream) { return $reader->readImageFromUri(Streams::readableUri($stream)); }; } else { $this->reader = function ($reader, $stream) { $bytes = ''; while ($stream->available() > 0) { $bytes .= $stream->read(); } $stream->close(); return $reader->readImageFromString($bytes); }; } } else { if ($this->stream instanceof Stream) { if ($this instanceof img·io·UriReader && !self::$GD_USERSTREAMS_BUG) { $this->reader = function ($reader, $stream) { $stream->open(STREAM_MODE_READ); return $reader->readImageFromUri($stream->getURI()); }; } else { $this->reader = function ($reader, $stream) { $stream->open(STREAM_MODE_READ); $bytes = ''; do { $bytes .= $stream->read(); } while (!$stream->eof()); $stream->close(); return $reader->readImageFromString($bytes); }; } } else { throw new IllegalArgumentException('Expected either an io.streams.InputStream or an io.Stream, have ' . xp::typeOf($this->stream)); } } }
/** * Invokes the underlying method represented by this Method object, * on the specified object with the specified parameters. * * Example: * ```php * $method= XPClass::forName('lang.Object')->getMethod('toString'); * $str= $method->invoke(new Object()); * ``` * * Example (passing arguments) * ```php * $method= XPClass::forName('lang.types.String')->getMethod('concat'); * $str= $method->invoke(new String('Hello'), ['World']); * ``` * * Example (static invokation): * ```php * $method= XPClass::forName('util.log.Logger')->getMethod('getInstance'); * $log= $method->invoke(null); * ``` * * @param lang.Object $obj * @param var[] $args default [] * @return var * @throws lang.IllegalArgumentException in case the passed object is not an instance of the declaring class * @throws lang.IllegalAccessException in case the method is not public or if it is abstract * @throws lang.reflect.TargetInvocationException for any exception raised from the invoked method */ public function invoke($obj, $args = []) { if (null !== $obj && !$obj instanceof $this->_class) { throw new IllegalArgumentException(sprintf('Passed argument is not a %s class (%s)', XPClass::nameOf($this->_class), \xp::typeOf($obj))); } // Check modifiers. If caller is an instance of this class, allow // protected method invocation (which the PHP reflection API does // not). $m = $this->_reflect->getModifiers(); if ($m & MODIFIER_ABSTRACT) { throw new IllegalAccessException(sprintf('Cannot invoke abstract %s::%s', XPClass::nameOf($this->_class), $this->_reflect->getName())); } $public = $m & MODIFIER_PUBLIC; if (!$public && !$this->accessible) { $t = debug_backtrace(0, 2); $decl = $this->_reflect->getDeclaringClass()->getName(); if ($m & MODIFIER_PROTECTED) { $allow = $t[1]['class'] === $decl || is_subclass_of($t[1]['class'], $decl); } else { $allow = $t[1]['class'] === $decl; } if (!$allow) { throw new IllegalAccessException(sprintf('Cannot invoke %s %s::%s from scope %s', Modifiers::stringOf($this->getModifiers()), XPClass::nameOf($this->_class), $this->_reflect->getName(), $t[1]['class'])); } } try { if (!$public) { $this->_reflect->setAccessible(true); } return $this->_reflect->invokeArgs($obj, (array) $args); } catch (\lang\SystemExit $e) { throw $e; } catch (\lang\Throwable $e) { throw new TargetInvocationException(XPClass::nameOf($this->_class) . '::' . $this->_reflect->getName(), $e); } catch (\Exception $e) { throw new TargetInvocationException(XPClass::nameOf($this->_class) . '::' . $this->_reflect->getName(), new \lang\XPException($e->getMessage())); } catch (\Throwable $e) { throw new TargetInvocationException(XPClass::nameOf($this->_class) . '::' . $this->_reflect->getName(), new \lang\Error($e->getMessage())); } }
/** * Constructor * * @param var $arg either an io.streams.InputStream, an io.File or an io.Stream (BC) * @throws lang.IllegalArgumentException when types are not met */ public function __construct($arg) { if ($arg instanceof InputStream) { $this->read($arg); } else { if ($arg instanceof File) { $this->read($arg->in()); } else { if ($arg instanceof Stream) { // BC $this->stream = $arg; $this->reader = function ($reader, $stream) { $stream->open(STREAM_MODE_READ); $bytes = $stream->read($stream->size()); $stream->close(); return $reader->readImageFromString($bytes); }; } else { throw new IllegalArgumentException('Expected either an io.streams.InputStream or an io.File, have ' . \xp::typeOf($this->stream)); } } } }
/** * Recursivly serialize data to the given node. * * Scalar values are natively supported by the protocol, so we just encode * them as the spec tells us. As arrays and structs / hashes are the same * in PHP, and structs are the more powerful construct, we're always encoding * arrays as structs. * * XP objects are encoded as structs, having their FQDN stored in the member * __xp_class. * * @param xml.Node node * @param var data * @throws lang.IllegalArgumentException in case the data could not be serialized. */ protected function _marshall($data) { $value = new Node('value'); // Handle objects: // - util.Date objects are serialized as dateTime.iso8601 // - lang.types.Bytes object are serialized as base64 // - Provide a standard-way to serialize Object-derived classes if ($data instanceof Date) { $value->addChild(new Node('dateTime.iso8601', $data->toString('Ymd\\TH:i:s'))); return $value; } else { if ($data instanceof Bytes || $data instanceof \lang\types\Bytes) { $value->addChild(new Node('base64', base64_encode($data))); return $value; } else { if ($data instanceof \lang\Generic) { $n = $value->addChild(new Node('struct')); $n->addChild(Node::fromArray(['name' => '__xp_class', 'value' => ['string' => nameof($data)]], 'member')); foreach ($data->getClass()->getFields() as $field) { if ($field->getModifiers() & MODIFIER_STATIC) { continue; } $member = $n->addChild(new Node('member')); $member->addChild(new Node('name', $field->getName())); $member->addChild($this->_marshall($field->setAccessible(true)->get($data))); } return $value; } } } switch (\xp::typeOf($data)) { case 'integer': $value->addChild(new Node('int', $data)); break; case 'boolean': $value->addChild(new Node('boolean', (string) (int) $data)); break; case 'double': case 'float': $value->addChild(new Node('double', $data)); break; case 'array': if ($this->_isVector($data)) { $n = $value->addChild(new Node('array'))->addChild(new Node('data')); for ($i = 0, $s = sizeof($data); $i < $s; $i++) { $n->addChild($this->_marshall($data[$i])); } } else { $n = $value->addChild(new Node('struct')); foreach ($data as $name => $v) { $member = $n->addChild(new Node('member')); $member->addChild(new Node('name', $name)); $member->addChild($this->_marshall($v)); } } break; case 'string': $value->addChild(new Node('string', $data)); break; case 'NULL': $value->addChild(new Node('nil')); break; default: throw new \lang\IllegalArgumentException('Cannot serialize data of type "' . \xp::typeOf($data) . '"'); } return $value; }
/** * Invokes a given function with the given arguments. * * @param var $func * @param var[] $args * @return var * @throws lang.IllegalArgumentException in case the passed function is not an instance of this type * @throws lang.reflect.TargetInvocationException for any exception raised from the invoked function */ public function invoke($func, $args = []) { $closure = $this->verified($func, function ($m) use($func) { throw new IllegalArgumentException(sprintf('Passed argument is not of a %s type (%s): %s', $this->getName(), \xp::typeOf($func), $m)); }); try { return call_user_func_array($closure, $args); } catch (SystemExit $e) { throw $e; } catch (Throwable $e) { throw new \lang\reflect\TargetInvocationException($this->getName(), $e); } }