Browse Source

Tested seeking

labels
J. King 6 years ago
parent
commit
9fba89ebda
  1. 20
      lib/UTF8String.php
  2. 60
      tests/cases/TestCodec.php

20
lib/UTF8String.php

@ -20,7 +20,7 @@ class UTF8String {
return $this->posByte;
}
public function posChar(): int {
public function posChr(): int {
return $this->posChar;
}
@ -107,29 +107,33 @@ class UTF8String {
*
* If $distance is negative, the operation will be performed in reverse
*
* If the end (or beginning) of the string was reached before the end of the operation, false is returned
* If the end (or beginning) of the string was reached before the end of the operation, the remaining number of requested characters is returned
*/
public function seek(int $distance): bool {
public function seek(int $distance): int {
if ($distance > 0) {
if ($this->posByte == strlen($this->string)) {
// if we're already at the end of the string, we can't go further
return $distance;
}
do {
// get the next code point; this automatically increments the character position
$p = $this->nextOrd();
} while (--$distance && $p !== false); // stop after we have skipped the desired number of characters, or reached EOF
return !$distance;
return $distance;
} elseif ($distance < 0) {
$distance = abs($distance);
if (!$this->posByte) {
// if we're already at the start of the string, we can't go further back
return false;
return $distance;
}
$distance = abs($distance);
do {
$this->sync($this->posByte - 1);
// manually decrement the character position
$this->posChar--;
} while (--$distance && $this->posByte);
return !$distance;
return $distance;
} else {
return true;
return 0;
}
}

60
tests/cases/TestCodec.php

@ -41,20 +41,72 @@ class TestConf extends \PHPUnit\Framework\TestCase {
/**
* @dataProvider provideStrings
* @covers \MensBeam\UTF8\UTF8String::seek
* @covers \MensBeam\UTF8\UTF8String::sync
* @covers \MensBeam\UTF8\UTF8String::posChar
*/
public function testSTepBackThroughAString(string $input, array $points) {
$s = new UTF8String($input);
$a = 0;
while (($p1 = $s->nextOrd() ?? 0xFFFD) !== false) {
$this->assertTrue($s->seek(-1));
$this->assertSame(0, $s->seek(-1));
$p2 = $s->nextOrd() ?? 0xFFFD;
$this->assertSame($p1, $p2, "Mismatch at character position $a");
$this->assertSame(++$a, $s->posChar(), "Character position should be $a");
$this->assertSame(++$a, $s->posChr(), "Character position should be $a");
}
}
/**
* @covers \MensBeam\UTF8\UTF8String::seek
* @covers \MensBeam\UTF8\UTF8String::posChr
* @covers \MensBeam\UTF8\UTF8String::posByte
*/
public function testSeekThroughAString() {
/*
Char 0 U+007A (1 byte) Offset 0
Char 1 U+00A2 (2 bytes) Offset 1
Char 2 U+6C34 (3 bytes) Offset 3
Char 3 U+1D11E (4 bytes) Offset 6
Char 4 U+F8FF (3 bytes) Offset 10
Char 5 U+10FFFD (4 bytes) Offset 13
Char 6 U+FFFE (3 bytes) Offset 17
End of string at char 7, offset 20
*/
$input = "\x7A\xC2\xA2\xE6\xB0\xB4\xF0\x9D\x84\x9E\xEF\xA3\xBF\xF4\x8F\xBF\xBD\xEF\xBF\xBE";
$s = new UTF8String($input);
$this->assertSame(0, $s->posChr());
$this->assertSame(0, $s->posByte());
$this->assertSame(0, $s->seek(0));
$this->assertSame(0, $s->posChr());
$this->assertSame(0, $s->posByte());
$this->assertSame(1, $s->seek(-1));
$this->assertSame(0, $s->posChr());
$this->assertSame(0, $s->posByte());
$this->assertSame(0, $s->seek(1));
$this->assertSame(1, $s->posChr());
$this->assertSame(1, $s->posByte());
$this->assertSame(0, $s->seek(2));
$this->assertSame(3, $s->posChr());
$this->assertSame(6, $s->posByte());
$this->assertSame(0, $s->seek(4));
$this->assertSame(7, $s->posChr());
$this->assertSame(20, $s->posByte());
$this->assertSame(1, $s->seek(1));
$this->assertSame(7, $s->posChr());
$this->assertSame(20, $s->posByte());
$this->assertSame(0, $s->seek(-3));
$this->assertSame(4, $s->posChr());
$this->assertSame(10, $s->posByte());
$this->assertSame(6, $s->seek(-10));
$this->assertSame(0, $s->posChr());
$this->assertSame(0, $s->posByte());
}
public function provideStrings() {
return [

Loading…
Cancel
Save