[String] bytesAt() and codePointsAt()

This commit is contained in:
Gregor Harlan 2019-10-09 21:59:50 +02:00 committed by Nicolas Grekas
parent 9d9d095962
commit f8d2faa0b8
9 changed files with 142 additions and 6 deletions

View File

@ -225,6 +225,16 @@ abstract class AbstractString implements \JsonSerializable
return $this->slice(0, $i);
}
/**
* @return int[]
*/
public function bytesAt(int $offset): array
{
$str = $this->slice($offset, 1);
return '' === $str->string ? [] : array_values(unpack('C*', $str->string));
}
/**
* @return static
*/

View File

@ -159,11 +159,14 @@ abstract class AbstractUnicodeString extends AbstractString
return $str;
}
public function codePoint(int $offset = 0): ?int
/**
* @return int[]
*/
public function codePointsAt(int $offset): array
{
$str = $offset ? $this->slice($offset, 1) : $this;
$str = $this->slice($offset, 1);
return '' === $str->string ? null : mb_ord($str->string);
return '' === $str->string ? [] : array_map('mb_ord', preg_split('//u', $str->string, -1, PREG_SPLIT_NO_EMPTY));
}
public function folded(bool $compat = true): parent

View File

@ -43,11 +43,11 @@ class ByteString extends AbstractString
return new static(substr($string, 0, $length));
}
public function byteCode(int $offset = 0): ?int
public function bytesAt(int $offset): array
{
$str = $offset ? $this->slice($offset, 1) : $this;
$str = $this->string[$offset] ?? '';
return '' === $str->string ? null : \ord($str->string);
return '' === $str ? [] : [\ord($str)];
}
public function append(string ...$suffix): parent

View File

@ -75,6 +75,13 @@ class CodePointString extends AbstractUnicodeString
return $chunks;
}
public function codePointsAt(int $offset): array
{
$str = $offset ? $this->slice($offset, 1) : $this;
return '' === $str->string ? [] : [mb_ord($str->string)];
}
public function endsWith($suffix): bool
{
if ($suffix instanceof AbstractString) {

View File

@ -34,6 +34,27 @@ abstract class AbstractAsciiTestCase extends TestCase
$this->assertTrue($instance->isEmpty());
}
/**
* @dataProvider provideBytesAt
*/
public function testBytesAt(array $expected, string $string, int $offset, int $form = null)
{
$instance = static::createFromString($string);
$instance = $form ? $instance->normalize($form) : $instance;
$this->assertSame($expected, $instance->bytesAt($offset));
}
public static function provideBytesAt(): array
{
return [
[[], '', 0],
[[], 'a', 1],
[[0x62], 'abc', 1],
[[0x63], 'abcde', -3],
];
}
/**
* @dataProvider provideWrap
*/

View File

@ -34,6 +34,40 @@ abstract class AbstractUnicodeTestCase extends AbstractAsciiTestCase
];
}
public static function provideBytesAt(): array
{
return array_merge(
parent::provideBytesAt(),
[
[[0xC3, 0xA4], 'Späßchen', 2],
[[0xC3, 0x9F], 'Späßchen', -5],
]
);
}
/**
* @dataProvider provideCodePointsAt
*/
public function testCodePointsAt(array $expected, string $string, int $offset, int $form = null)
{
$instance = static::createFromString($string);
$instance = $form ? $instance->normalize($form) : $instance;
$this->assertSame($expected, $instance->codePointsAt($offset));
}
public static function provideCodePointsAt(): array
{
return [
[[], '', 0],
[[], 'a', 1],
[[0x53], 'Späßchen', 0],
[[0xE4], 'Späßchen', 2],
[[0xDF], 'Späßchen', -5],
[[0x260E], '☢☎❄', 1],
];
}
public static function provideLength(): array
{
return [

View File

@ -21,6 +21,19 @@ class ByteStringTest extends AbstractAsciiTestCase
return new ByteString($string);
}
public static function provideBytesAt(): array
{
return array_merge(
parent::provideBytesAt(),
[
[[0xC3], 'Späßchen', 2],
[[0x61], "Spa\u{0308}ßchen", 2],
[[0xCC], "Spa\u{0308}ßchen", 3],
[[0xE0], 'नमस्ते', 6],
]
);
}
public static function provideLength(): array
{
return array_merge(

View File

@ -31,4 +31,28 @@ class CodePointStringTest extends AbstractUnicodeTestCase
]
);
}
public static function provideBytesAt(): array
{
return array_merge(
parent::provideBytesAt(),
[
[[0x61], "Spa\u{0308}ßchen", 2],
[[0xCC, 0x88], "Spa\u{0308}ßchen", 3],
[[0xE0, 0xA5, 0x8D], 'नमस्ते', 3],
]
);
}
public static function provideCodePointsAt(): array
{
return array_merge(
parent::provideCodePointsAt(),
[
[[0x61], "Spa\u{0308}ßchen", 2],
[[0x0308], "Spa\u{0308}ßchen", 3],
[[0x094D], 'नमस्ते', 3],
]
);
}
}

View File

@ -90,6 +90,30 @@ class UnicodeStringTest extends AbstractUnicodeTestCase
);
}
public static function provideBytesAt(): array
{
return array_merge(
parent::provideBytesAt(),
[
[[0xC3, 0xA4], "Spa\u{0308}ßchen", 2],
[[0x61, 0xCC, 0x88], "Spa\u{0308}ßchen", 2, UnicodeString::NFD],
[[0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D], 'नमस्ते', 2],
]
);
}
public static function provideCodePointsAt(): array
{
return array_merge(
parent::provideCodePointsAt(),
[
[[0xE4], "Spa\u{0308}ßchen", 2],
[[0x61, 0x0308], "Spa\u{0308}ßchen", 2, UnicodeString::NFD],
[[0x0938, 0x094D], 'नमस्ते', 2],
]
);
}
public static function provideLower(): array
{
return array_merge(