1<?php
2/**
3* Abstract superclass for all scanner status implementations
4*
5* @license http://www.opensource.org/licenses/mit-license.php The MIT License
6* @copyright Copyright 2010-2014 PhpCss Team
7*/
8namespace PhpCss\Scanner {
9
10  /**
11   * Abstract superclass for all scanner status implementations
12   *
13   * It defines the API and provides basic logic to match patterns.
14   */
15  abstract class Status {
16
17    /**
18    * Try to get token in buffer at offset position.
19    *
20    * @param string $buffer
21    * @param integer $offset
22    * @return Token
23    */
24    abstract public function getToken(string $buffer, int $offset): ?Token;
25
26    /**
27    * Check if token ends status
28    *
29    * @param Token $token
30    * @return bool
31    */
32    abstract public function isEndToken(Token $token): bool;
33
34    /**
35    * Get new (sub)status if needed.
36    *
37    * @param Token $token
38    * @return Status|NULL
39    */
40    abstract public function getNewStatus(Token $token): ?Status;
41
42    /**
43    * Checks if the given offset position matches the pattern.
44    *
45    * @param string $buffer
46    * @param integer $offset
47    * @param string $pattern
48    * @return string|NULL
49    */
50    protected function matchPattern(string $buffer, int $offset, string $pattern): ?string {
51      $found = preg_match(
52        $pattern, $buffer, $match, PREG_OFFSET_CAPTURE, $offset
53      );
54      if (
55        $found &&
56        isset($match[0][1]) &&
57        $match[0][1] === $offset
58      ) {
59        return $match[0][0];
60      }
61      return NULL;
62    }
63
64    protected function matchPatterns(string $buffer, int $offset, array $patterns): ?Token {
65      foreach ($patterns as $type => $pattern) {
66        $tokenString = $this->matchPattern(
67          $buffer, $offset, $pattern
68        );
69        if (!empty($tokenString)) {
70          return new Token(
71            $type, $tokenString, $offset
72          );
73        }
74      }
75      return NULL;
76    }
77
78    protected function matchCharacters(string $buffer, int $offset, array $chars): ?Token {
79      if (isset($buffer[$offset])) {
80        $char = $buffer[$offset];
81        foreach ($chars as $type => $expectedChar) {
82          if ($char === $expectedChar) {
83            return new Token($type, $char, $offset);
84          }
85        }
86      }
87      return NULL;
88    }
89  }
90}
91