Skip to content

Commit f8d2faa

Browse files
gharlannicolas-grekas
authored andcommitted
[String] bytesAt() and codePointsAt()
1 parent 9d9d095 commit f8d2faa

File tree

9 files changed

+142
-6
lines changed

9 files changed

+142
-6
lines changed

src/Symfony/Component/String/AbstractString.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,16 @@ public function beforeLast($needle, bool $includeNeedle = false, int $offset = 0
225225
return $this->slice(0, $i);
226226
}
227227

228+
/**
229+
* @return int[]
230+
*/
231+
public function bytesAt(int $offset): array
232+
{
233+
$str = $this->slice($offset, 1);
234+
235+
return '' === $str->string ? [] : array_values(unpack('C*', $str->string));
236+
}
237+
228238
/**
229239
* @return static
230240
*/

src/Symfony/Component/String/AbstractUnicodeString.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,14 @@ public function camel(): parent
159159
return $str;
160160
}
161161

162-
public function codePoint(int $offset = 0): ?int
162+
/**
163+
* @return int[]
164+
*/
165+
public function codePointsAt(int $offset): array
163166
{
164-
$str = $offset ? $this->slice($offset, 1) : $this;
167+
$str = $this->slice($offset, 1);
165168

166-
return '' === $str->string ? null : mb_ord($str->string);
169+
return '' === $str->string ? [] : array_map('mb_ord', preg_split('//u', $str->string, -1, PREG_SPLIT_NO_EMPTY));
167170
}
168171

169172
public function folded(bool $compat = true): parent

src/Symfony/Component/String/ByteString.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ public static function fromRandom(int $length = 16): self
4343
return new static(substr($string, 0, $length));
4444
}
4545

46-
public function byteCode(int $offset = 0): ?int
46+
public function bytesAt(int $offset): array
4747
{
48-
$str = $offset ? $this->slice($offset, 1) : $this;
48+
$str = $this->string[$offset] ?? '';
4949

50-
return '' === $str->string ? null : \ord($str->string);
50+
return '' === $str ? [] : [\ord($str)];
5151
}
5252

5353
public function append(string ...$suffix): parent

src/Symfony/Component/String/CodePointString.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ public function chunk(int $length = 1): array
7575
return $chunks;
7676
}
7777

78+
public function codePointsAt(int $offset): array
79+
{
80+
$str = $offset ? $this->slice($offset, 1) : $this;
81+
82+
return '' === $str->string ? [] : [mb_ord($str->string)];
83+
}
84+
7885
public function endsWith($suffix): bool
7986
{
8087
if ($suffix instanceof AbstractString) {

src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,27 @@ public function testCreateFromEmptyString()
3434
$this->assertTrue($instance->isEmpty());
3535
}
3636

37+
/**
38+
* @dataProvider provideBytesAt
39+
*/
40+
public function testBytesAt(array $expected, string $string, int $offset, int $form = null)
41+
{
42+
$instance = static::createFromString($string);
43+
$instance = $form ? $instance->normalize($form) : $instance;
44+
45+
$this->assertSame($expected, $instance->bytesAt($offset));
46+
}
47+
48+
public static function provideBytesAt(): array
49+
{
50+
return [
51+
[[], '', 0],
52+
[[], 'a', 1],
53+
[[0x62], 'abc', 1],
54+
[[0x63], 'abcde', -3],
55+
];
56+
}
57+
3758
/**
3859
* @dataProvider provideWrap
3960
*/

src/Symfony/Component/String/Tests/AbstractUnicodeTestCase.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,40 @@ public function provideCreateFromCodePoint(): array
3434
];
3535
}
3636

37+
public static function provideBytesAt(): array
38+
{
39+
return array_merge(
40+
parent::provideBytesAt(),
41+
[
42+
[[0xC3, 0xA4], 'Späßchen', 2],
43+
[[0xC3, 0x9F], 'Späßchen', -5],
44+
]
45+
);
46+
}
47+
48+
/**
49+
* @dataProvider provideCodePointsAt
50+
*/
51+
public function testCodePointsAt(array $expected, string $string, int $offset, int $form = null)
52+
{
53+
$instance = static::createFromString($string);
54+
$instance = $form ? $instance->normalize($form) : $instance;
55+
56+
$this->assertSame($expected, $instance->codePointsAt($offset));
57+
}
58+
59+
public static function provideCodePointsAt(): array
60+
{
61+
return [
62+
[[], '', 0],
63+
[[], 'a', 1],
64+
[[0x53], 'Späßchen', 0],
65+
[[0xE4], 'Späßchen', 2],
66+
[[0xDF], 'Späßchen', -5],
67+
[[0x260E], '☢☎❄', 1],
68+
];
69+
}
70+
3771
public static function provideLength(): array
3872
{
3973
return [

src/Symfony/Component/String/Tests/ByteStringTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,19 @@ protected static function createFromString(string $string): AbstractString
2121
return new ByteString($string);
2222
}
2323

24+
public static function provideBytesAt(): array
25+
{
26+
return array_merge(
27+
parent::provideBytesAt(),
28+
[
29+
[[0xC3], 'Späßchen', 2],
30+
[[0x61], "Spa\u{0308}ßchen", 2],
31+
[[0xCC], "Spa\u{0308}ßchen", 3],
32+
[[0xE0], 'नमस्ते', 6],
33+
]
34+
);
35+
}
36+
2437
public static function provideLength(): array
2538
{
2639
return array_merge(

src/Symfony/Component/String/Tests/CodePointStringTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,28 @@ public static function provideLength(): array
3131
]
3232
);
3333
}
34+
35+
public static function provideBytesAt(): array
36+
{
37+
return array_merge(
38+
parent::provideBytesAt(),
39+
[
40+
[[0x61], "Spa\u{0308}ßchen", 2],
41+
[[0xCC, 0x88], "Spa\u{0308}ßchen", 3],
42+
[[0xE0, 0xA5, 0x8D], 'नमस्ते', 3],
43+
]
44+
);
45+
}
46+
47+
public static function provideCodePointsAt(): array
48+
{
49+
return array_merge(
50+
parent::provideCodePointsAt(),
51+
[
52+
[[0x61], "Spa\u{0308}ßchen", 2],
53+
[[0x0308], "Spa\u{0308}ßchen", 3],
54+
[[0x094D], 'नमस्ते', 3],
55+
]
56+
);
57+
}
3458
}

src/Symfony/Component/String/Tests/UnicodeStringTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,30 @@ public static function provideChunk(): array
9090
);
9191
}
9292

93+
public static function provideBytesAt(): array
94+
{
95+
return array_merge(
96+
parent::provideBytesAt(),
97+
[
98+
[[0xC3, 0xA4], "Spa\u{0308}ßchen", 2],
99+
[[0x61, 0xCC, 0x88], "Spa\u{0308}ßchen", 2, UnicodeString::NFD],
100+
[[0xE0, 0xA4, 0xB8, 0xE0, 0xA5, 0x8D], 'नमस्ते', 2],
101+
]
102+
);
103+
}
104+
105+
public static function provideCodePointsAt(): array
106+
{
107+
return array_merge(
108+
parent::provideCodePointsAt(),
109+
[
110+
[[0xE4], "Spa\u{0308}ßchen", 2],
111+
[[0x61, 0x0308], "Spa\u{0308}ßchen", 2, UnicodeString::NFD],
112+
[[0x0938, 0x094D], 'नमस्ते', 2],
113+
]
114+
);
115+
}
116+
93117
public static function provideLower(): array
94118
{
95119
return array_merge(

0 commit comments

Comments
 (0)