Number.php 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. <?php
  2. /**
  3. * Class Number
  4. *
  5. * @filesource Number.php
  6. * @created 26.11.2015
  7. * @package QRCode
  8. * @author Smiley <smiley@chillerlan.net>
  9. * @copyright 2015 Smiley
  10. * @license MIT
  11. */
  12. namespace chillerlan\QRCode\Data;
  13. use chillerlan\QRCode\QRCode;
  14. /**
  15. * Numeric mode: decimal digits 0 through 9
  16. */
  17. class Number extends QRDataAbstract{
  18. /**
  19. * @inheritdoc
  20. */
  21. protected $datamode = QRCode::DATA_NUMBER;
  22. /**
  23. * @inheritdoc
  24. */
  25. protected $lengthBits = [10, 12, 14];
  26. /**
  27. * @inheritdoc
  28. */
  29. protected function write(string $data){
  30. $i = 0;
  31. while($i + 2 < $this->strlen){
  32. $this->bitBuffer->put($this->parseInt(substr($data, $i, 3)), 10);
  33. $i += 3;
  34. }
  35. if($i < $this->strlen){
  36. if($this->strlen - $i === 1){
  37. $this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 1)), 4);
  38. }
  39. // @codeCoverageIgnoreStart
  40. elseif($this->strlen - $i === 2){
  41. $this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 2)), 7);
  42. }
  43. // @codeCoverageIgnoreEnd
  44. }
  45. }
  46. /**
  47. * @param string $string
  48. *
  49. * @return int
  50. * @throws \chillerlan\QRCode\Data\QRCodeDataException
  51. */
  52. protected function parseInt(string $string):int {
  53. $num = 0;
  54. $map = str_split('0123456789');
  55. $len = strlen($string);
  56. for($i = 0; $i < $len; $i++){
  57. $c = ord($string[$i]);
  58. if(!in_array($string[$i], $map, true)){
  59. throw new QRCodeDataException('illegal char: "'.$string[$i].'" ['.$c.']');
  60. }
  61. $c = $c - ord('0');
  62. $num = $num * 10 + $c;
  63. }
  64. return $num;
  65. }
  66. }