1<?php 2 3namespace MediaWiki\Rest\HeaderParser; 4 5/** 6 * @internal 7 */ 8class HeaderParserBase { 9 /** 10 * @var string The input string being processed 11 */ 12 protected $input; 13 14 /** 15 * @var int The position within $input 16 */ 17 protected $pos; 18 19 /** 20 * @var int The length of $input 21 */ 22 protected $inputLength; 23 24 /** 25 * Set the input, and derived convenience properties 26 * 27 * @param string $input 28 */ 29 protected function setInput( $input ) { 30 $this->input = $input; 31 $this->pos = 0; 32 $this->inputLength = strlen( $input ); 33 } 34 35 /** 36 * Consume a specified string, or throw an exception. 37 * 38 * @param string $s 39 * @throws HeaderParserError 40 */ 41 protected function consumeString( $s ) { 42 if ( $this->pos >= $this->inputLength ) { 43 $this->error( "Expected \"$s\" but got end of string" ); 44 } 45 if ( substr_compare( $this->input, $s, $this->pos, strlen( $s ) ) === 0 ) { 46 $this->pos += strlen( $s ); 47 } else { 48 $this->error( "Expected \"$s\"" ); 49 } 50 } 51 52 /** 53 * Skip whitespace at the input position (OWS) 54 */ 55 protected function skipWhitespace() { 56 $this->pos += strspn( $this->input, " \t", $this->pos ); 57 } 58 59 /** 60 * Throw an exception to indicate a parse error 61 * 62 * @param string $message 63 * @throws HeaderParserError 64 */ 65 protected function error( $message ) { 66 throw new HeaderParserError( "$message at {$this->pos}" ); 67 } 68 69 /** 70 * Consume a specified number of digits, or throw an exception 71 * 72 * @param int $numDigits 73 * @return string 74 * @throws HeaderParserError 75 */ 76 protected function consumeFixedDigits( $numDigits ) { 77 $digits = substr( $this->input, $this->pos, $numDigits ); 78 if ( strlen( $digits ) !== $numDigits || !preg_match( '/^[0-9]*$/', $digits ) ) { 79 $this->error( "expected $numDigits digits" ); 80 } 81 $this->pos += $numDigits; 82 return $digits; 83 } 84 85 /** 86 * If the position is not at the end of the input string, raise an error, 87 * complaining of trailing characters. 88 * 89 * @throws HeaderParserError 90 */ 91 protected function assertEnd() { 92 if ( $this->pos !== $this->inputLength ) { 93 $this->error( "trailing characters" ); 94 } 95 } 96} 97