PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/classes/ASNValue.class.php

https://github.com/leemcd56/Minecraft-PHP-Client-2
PHP | 169 lines | 124 code | 32 blank | 13 comment | 12 complexity | b43fc910f6ab3720002f0e1ec745295f MD5 | raw file
Possible License(s): WTFPL
  1. <?php
  2. //-----------------------------------------------------------------------------
  3. // ASNValue class by A.Oliinyk
  4. // contact@pumka.net
  5. //-----------------------------------------------------------------------------
  6. class ASNValue
  7. {
  8. const TAG_INTEGER = 0x02;
  9. const TAG_BITSTRING = 0x03;
  10. const TAG_SEQUENCE = 0x30;
  11. public $Tag;
  12. public $Value;
  13. function __construct($Tag=0x00, $Value='')
  14. {
  15. $this->Tag = $Tag;
  16. $this->Value = $Value;
  17. }
  18. function Encode()
  19. {
  20. //Write type
  21. $result = chr($this->Tag);
  22. //Write size
  23. $size = strlen($this->Value);
  24. if ($size < 127) {
  25. //Write size as is
  26. $result .= chr($size);
  27. }
  28. else {
  29. //Prepare length sequence
  30. $sizeBuf = self::IntToBin($size);
  31. //Write length sequence
  32. $firstByte = 0x80 + strlen($sizeBuf);
  33. $result .= chr($firstByte) . $sizeBuf;
  34. }
  35. //Write value
  36. $result .= $this->Value;
  37. return $result;
  38. }
  39. function Decode(&$Buffer)
  40. {
  41. //Read type
  42. $this->Tag = self::ReadByte($Buffer);
  43. //Read first byte
  44. $firstByte = self::ReadByte($Buffer);
  45. if ($firstByte < 127) {
  46. $size = $firstByte;
  47. }
  48. else if ($firstByte > 127) {
  49. $sizeLen = $firstByte - 0x80;
  50. //Read length sequence
  51. $size = self::BinToInt(self::ReadBytes($Buffer, $sizeLen));
  52. }
  53. else {
  54. throw new Exception("Invalid ASN length value");
  55. }
  56. $this->Value = self::ReadBytes($Buffer, $size);
  57. }
  58. protected static function ReadBytes(&$Buffer, $Length)
  59. {
  60. $result = substr($Buffer, 0, $Length);
  61. $Buffer = substr($Buffer, $Length);
  62. return $result;
  63. }
  64. protected static function ReadByte(&$Buffer)
  65. {
  66. return ord(self::ReadBytes($Buffer, 1));
  67. }
  68. protected static function BinToInt($Bin)
  69. {
  70. $len = strlen($Bin);
  71. $result = 0;
  72. for ($i=0; $i<$len; $i++) {
  73. $curByte = self::ReadByte($Bin);
  74. $result += $curByte << (($len-$i-1)*8);
  75. }
  76. return $result;
  77. }
  78. protected static function IntToBin($Int)
  79. {
  80. $result = '';
  81. do {
  82. $curByte = $Int % 256;
  83. $result .= chr($curByte);
  84. $Int = ($Int - $curByte) / 256;
  85. } while ($Int > 0);
  86. $result = strrev($result);
  87. return $result;
  88. }
  89. function SetIntBuffer($Value)
  90. {
  91. if (strlen($Value) > 1) {
  92. $firstByte = ord($Value{0});
  93. if ($firstByte & 0x80) { //first bit set
  94. $Value = chr(0x00) . $Value;
  95. }
  96. }
  97. $this->Value = $Value;
  98. }
  99. function GetIntBuffer()
  100. {
  101. $result = $this->Value;
  102. if (ord($result{0}) === 0x00) {
  103. $result = substr($result, 1);
  104. }
  105. return $result;
  106. }
  107. function SetInt($Value)
  108. {
  109. $Value = self::IntToBin($Value);
  110. $this->SetIntBuffer($Value);
  111. }
  112. function GetInt()
  113. {
  114. $result = $this->GetIntBuffer();
  115. $result = self::BinToInt($result);
  116. return $result;
  117. }
  118. function SetSequence($Values)
  119. {
  120. $result = '';
  121. foreach ($Values as $item) {
  122. $result .= $item->Encode();
  123. }
  124. $this->Value = $result;
  125. }
  126. function GetSequence()
  127. {
  128. $result = array();
  129. $seq = $this->Value;
  130. while (strlen($seq)) {
  131. $val = new ASNValue();
  132. $val->Decode($seq);
  133. $result[] = $val;
  134. }
  135. return $result;
  136. }
  137. }