Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
214 lines (188 sloc) 5.446 kb
<?php
class BinTreeNodeWriter
{
private $output;
/** @var $key KeyStream */
private $key;
public function resetKey()
{
$this->key = null;
}
public function setKey($key)
{
$this->key = $key;
}
public function StartStream($domain, $resource)
{
$attributes = array();
$attributes["to"] = $domain;
$attributes["resource"] = $resource;
$this->writeListStart(count($attributes) * 2 + 1);
$this->output .= "\x01";
$this->writeAttributes($attributes);
return "WA" . $this->writeInt8(1) . $this->writeInt8(5) . $this->flushBuffer();
}
/**
* @param ProtocolNode $node
* @param bool $encrypt
*
* @return string
*/
public function write($node, $encrypt = true)
{
if ($node == null) {
$this->output .= "\x00";
} else {
$this->writeInternal($node);
}
return $this->flushBuffer($encrypt);
}
/**
* @param ProtocolNode $node
*/
protected function writeInternal($node)
{
$len = 1;
if ($node->getAttributes() != null) {
$len += count($node->getAttributes()) * 2;
}
if (count($node->getChildren()) > 0) {
$len += 1;
}
if (strlen($node->getData()) > 0) {
$len += 1;
}
$this->writeListStart($len);
$this->writeString($node->getTag());
$this->writeAttributes($node->getAttributes());
if (strlen($node->getData()) > 0) {
$this->writeBytes($node->getData());
}
if ($node->getChildren()) {
$this->writeListStart(count($node->getChildren()));
foreach ($node->getChildren() as $child) {
$this->writeInternal($child);
}
}
}
protected function parseInt24($data)
{
$ret = ord(substr($data, 0, 1)) << 16;
$ret |= ord(substr($data, 1, 1)) << 8;
$ret |= ord(substr($data, 2, 1)) << 0;
return $ret;
}
protected function flushBuffer($encrypt = true)
{
$size = strlen($this->output);
$data = $this->output;
if ($this->key != null && $encrypt) {
$bsize = $this->getInt24($size);
//encrypt
$data = $this->key->EncodeMessage($data, $size, 0, $size);
$len = strlen($data);
$bsize[0] = chr((8 << 4) | (($len & 16711680) >> 16));
$bsize[1] = chr(($len & 65280) >> 8);
$bsize[2] = chr($len & 255);
$size = $this->parseInt24($bsize);
}
$ret = $this->writeInt24($size) . $data;
$this->output = '';
return $ret;
}
protected function getInt24($length)
{
$ret = '';
$ret .= chr((($length & 0xf0000) >> 16));
$ret .= chr((($length & 0xff00) >> 8));
$ret .= chr(($length & 0xff));
return $ret;
}
protected function writeToken($token)
{
if ($token < 0xf5) {
$this->output .= chr($token);
} elseif ($token <= 0x1f4) {
$this->output .= "\xfe" . chr($token - 0xf5);
}
}
protected function writeJid($user, $server)
{
$this->output .= "\xfa";
if (strlen($user) > 0) {
$this->writeString($user);
} else {
$this->writeToken(0);
}
$this->writeString($server);
}
protected function writeInt8($v)
{
$ret = chr($v & 0xff);
return $ret;
}
protected function writeInt16($v)
{
$ret = chr(($v & 0xff00) >> 8);
$ret .= chr(($v & 0x00ff) >> 0);
return $ret;
}
protected function writeInt24($v)
{
$ret = chr(($v & 0xff0000) >> 16);
$ret .= chr(($v & 0x00ff00) >> 8);
$ret .= chr(($v & 0x0000ff) >> 0);
return $ret;
}
protected function writeBytes($bytes)
{
$len = strlen($bytes);
if ($len >= 0x100) {
$this->output .= "\xfd";
$this->output .= $this->writeInt24($len);
} else {
$this->output .= "\xfc";
$this->output .= $this->writeInt8($len);
}
$this->output .= $bytes;
}
protected function writeString($tag)
{
$intVal = -1;
$subdict = false;
if (TokenMap::TryGetToken($tag, $subdict, $intVal)) {
if ($subdict) {
$this->writeToken(236);
}
$this->writeToken($intVal);
return;
}
$index = strpos($tag, '@');
if ($index) {
$server = substr($tag, $index + 1);
$user = substr($tag, 0, $index);
$this->writeJid($user, $server);
} else {
$this->writeBytes($tag);
}
}
protected function writeAttributes($attributes)
{
if ($attributes) {
foreach ($attributes as $key => $value) {
$this->writeString($key);
$this->writeString($value);
}
}
}
protected function writeListStart($len)
{
if ($len == 0) {
$this->output .= "\x00";
} elseif ($len < 256) {
$this->output .= "\xf8" . chr($len);
} else {
$this->output .= "\xf9" . $this->writeInt16($len);
}
}
}
Jump to Line
Something went wrong with that request. Please try again.