StringHashParser.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. <?php
  2. /**
  3. * Parses string hash files. File format is as such:
  4. *
  5. * DefaultKeyValue
  6. * KEY: Value
  7. * KEY2: Value2
  8. * --MULTILINE-KEY--
  9. * Multiline
  10. * value.
  11. *
  12. * Which would output something similar to:
  13. *
  14. * array(
  15. * 'ID' => 'DefaultKeyValue',
  16. * 'KEY' => 'Value',
  17. * 'KEY2' => 'Value2',
  18. * 'MULTILINE-KEY' => "Multiline\nvalue.\n",
  19. * )
  20. *
  21. * We use this as an easy to use file-format for configuration schema
  22. * files, but the class itself is usage agnostic.
  23. *
  24. * You can use ---- to forcibly terminate parsing of a single string-hash;
  25. * this marker is used in multi string-hashes to delimit boundaries.
  26. */
  27. class HTMLPurifier_StringHashParser
  28. {
  29. public $default = 'ID';
  30. /**
  31. * Parses a file that contains a single string-hash.
  32. */
  33. public function parseFile($file) {
  34. if (!file_exists($file)) return false;
  35. $fh = fopen($file, 'r');
  36. if (!$fh) return false;
  37. $ret = $this->parseHandle($fh);
  38. fclose($fh);
  39. return $ret;
  40. }
  41. /**
  42. * Parses a file that contains multiple string-hashes delimited by '----'
  43. */
  44. public function parseMultiFile($file) {
  45. if (!file_exists($file)) return false;
  46. $ret = array();
  47. $fh = fopen($file, 'r');
  48. if (!$fh) return false;
  49. while (!feof($fh)) {
  50. $ret[] = $this->parseHandle($fh);
  51. }
  52. fclose($fh);
  53. return $ret;
  54. }
  55. /**
  56. * Internal parser that acepts a file handle.
  57. * @note While it's possible to simulate in-memory parsing by using
  58. * custom stream wrappers, if such a use-case arises we should
  59. * factor out the file handle into its own class.
  60. * @param $fh File handle with pointer at start of valid string-hash
  61. * block.
  62. */
  63. protected function parseHandle($fh) {
  64. $state = false;
  65. $single = false;
  66. $ret = array();
  67. do {
  68. $line = fgets($fh);
  69. if ($line === false) break;
  70. $line = rtrim($line, "\n\r");
  71. if (!$state && $line === '') continue;
  72. if ($line === '----') break;
  73. if (strncmp('--#', $line, 3) === 0) {
  74. // Comment
  75. continue;
  76. } elseif (strncmp('--', $line, 2) === 0) {
  77. // Multiline declaration
  78. $state = trim($line, '- ');
  79. if (!isset($ret[$state])) $ret[$state] = '';
  80. continue;
  81. } elseif (!$state) {
  82. $single = true;
  83. if (strpos($line, ':') !== false) {
  84. // Single-line declaration
  85. list($state, $line) = explode(':', $line, 2);
  86. $line = trim($line);
  87. } else {
  88. // Use default declaration
  89. $state = $this->default;
  90. }
  91. }
  92. if ($single) {
  93. $ret[$state] = $line;
  94. $single = false;
  95. $state = false;
  96. } else {
  97. $ret[$state] .= "$line\n";
  98. }
  99. } while (!feof($fh));
  100. return $ret;
  101. }
  102. }
  103. // vim: et sw=4 sts=4