diff --git a/src/Strings/Multibyte/OmniString.php b/src/Strings/Multibyte/OmniString.php index d658675..ba70c7b 100644 --- a/src/Strings/Multibyte/OmniString.php +++ b/src/Strings/Multibyte/OmniString.php @@ -1,68 +1,68 @@ value = $value; - $this->setEncoding($encoding ?? "UTF-8"); + $this->setEncoding($encoding ?: "UTF-8"); } /// /// Magic methods /// public function __toString() : string { return $this->value; } /// /// Helper methods /// public function pad( int $padLength = 0, string $padString = ' ', int $padType = STR_PAD_RIGHT ) : string { return (new StringPad) ->setInput($this->value) ->setEncoding($this->encoding) ->setPadLength($padLength) ->setPadString($padString) ->setPadType($padType) ->pad(); } /** * @return string */ public function getValue () : string { return $this->value; } /** * @param string $value */ public function setValue (string $value) { $this->value = $value; } } diff --git a/src/Strings/Multibyte/StringPad.php b/src/Strings/Multibyte/StringPad.php index 4cded7b..41c8de5 100644 --- a/src/Strings/Multibyte/StringPad.php +++ b/src/Strings/Multibyte/StringPad.php @@ -1,213 +1,213 @@ input = $input; $this->padLength = $padLength; $this->padString = $padString; $this->setPadType($padType); - $this->setEncoding($encoding ?? mb_internal_encoding()); + $this->setEncoding($encoding ?: mb_internal_encoding()); } /// /// Getters and setters /// public function getInput () : string { return $this->input; } public function setInput (string $input) : StringPad { $this->input = $input; return $this; } public function getPadLength () : int { return $this->padLength; } public function setPadLength (int $padLength) : StringPad { $this->padLength = $padLength; return $this; } public function getPadString () : string { return $this->padString; } public function setPadString (string $padString) : StringPad { $this->padString = $padString; return $this; } public function getPadType () : int { return $this->padType; } public function setPadType (int $padType) : StringPad { if (!self::isValidPadType($padType)) { throw new InvalidArgumentException; } $this->padType = $padType; return $this; } /// /// Helper methods to get and set /// public function setBothPad () : StringPad { $this->padType = STR_PAD_BOTH; return $this; } public function setLeftPad () : StringPad { $this->padType = STR_PAD_LEFT; return $this; } public function setRightPad () : StringPad { $this->padType = STR_PAD_RIGHT; return $this; } public static function isValidPadType (int $padType) : bool { return $padType >= 0 && $padType <= 2; } /// /// Pad methods /// public function pad () : string { $this->computeLengths(); return $this->getLeftPad() . $this->input . $this->getRightPad(); } private function getLeftPad () : string { if (!$this->hasPaddingBefore()) { return ''; } $length = (int)floor($this->targetLength); return mb_substr($this->repeatedString, 0, $length, $this->encoding); } private function getRightPad () : string { if (!$this->hasPaddingAfter()) { return ''; } $length = (int)ceil($this->targetLength); return mb_substr($this->repeatedString, 0, $length, $this->encoding); } private function computeLengths () : void { $this->targetLength = $this->computeNeededPadLength(); $this->repeatedString = $this->computeRepeatedString(); } private function computeRepeatedString () : string { // Inspired by Ronald Ulysses Swanson method // https://stackoverflow.com/a/27194169/1930997 // who followed the str_pad PHP implementation. $strToRepeatLength = mb_strlen($this->padString, $this->encoding); $repeatTimes = (int)ceil($this->targetLength / $strToRepeatLength); // Safe if used with valid Unicode sequences (any charset). return str_repeat($this->padString, max(0, $repeatTimes)); } private function computeNeededPadLength () : float { $length = $this->padLength - mb_strlen($this->input, $this->encoding); if ($this->hasPaddingBeforeAndAfter()) { return $length / 2; } return $length; } private function hasPaddingBefore () : bool { return $this->padType === STR_PAD_LEFT || $this->padType === STR_PAD_BOTH; } private function hasPaddingAfter () : bool { return $this->padType === STR_PAD_RIGHT || $this->padType === STR_PAD_BOTH; } private function hasPaddingBeforeAndAfter () : bool { return $this->padType === STR_PAD_BOTH || ($this->padType === STR_PAD_LEFT && $this->padType === STR_PAD_RIGHT) ; } } diff --git a/src/Strings/Multibyte/StringUtilities.php b/src/Strings/Multibyte/StringUtilities.php index dfdab68..e3491ac 100644 --- a/src/Strings/Multibyte/StringUtilities.php +++ b/src/Strings/Multibyte/StringUtilities.php @@ -1,46 +1,46 @@ setInput($input) ->setPadLength($padLength) ->setPadString($padString) ->setPadType($padType) - ->setEncoding($encoding) + ->setEncoding($encoding ?: mb_internal_encoding()) ->pad(); } public static function isSupportedEncoding (string $encoding) : bool { foreach (mb_list_encodings() as $supportedEncoding) { if ($encoding === $supportedEncoding) { return true; } } return false; } } diff --git a/tests/Strings/Multibyte/StringUtilitiesTest.php b/tests/Strings/Multibyte/StringUtilitiesTest.php index fc88a0f..3ba3d37 100644 --- a/tests/Strings/Multibyte/StringUtilitiesTest.php +++ b/tests/Strings/Multibyte/StringUtilitiesTest.php @@ -1,69 +1,75 @@ assertEquals($expected, $paddedString); } + public function testPadWithDefaultArguments () : void { + $this->assertEquals("foo ", StringUtilities::pad("foo", 4)); + $this->assertEquals("foo_", StringUtilities::pad("foo", 4, '_')); + $this->assertEquals("_foo", StringUtilities::pad("foo", 4, '_', STR_PAD_LEFT)); + } + public function testSupportedEncoding () : void { $this->assertTrue(StringUtilities::isSupportedEncoding("UTF-8")); $this->assertFalse(StringUtilities::isSupportedEncoding("notexisting")); } /// /// Data providers /// public function providePadding () : iterable { // Tests from http://3v4l.org/UnXTF // http://web.archive.org/web/20150711100913/http://3v4l.org/UnXTF yield ['àèòàFOOàèòà', "FOO", 11, "àèò", STR_PAD_BOTH]; yield ['àèòFOOàèòà', "FOO", 10, "àèò", STR_PAD_BOTH]; yield ['àèòBAAZàèòà', "BAAZ", 11, "àèò", STR_PAD_BOTH]; yield ['àèòBAAZàèò', "BAAZ", 10, "àèò", STR_PAD_BOTH]; yield ['FOOBAR', "FOOBAR", 6, "àèò", STR_PAD_BOTH]; yield ['FOOBAR', "FOOBAR", 1, "àèò", STR_PAD_BOTH]; yield ['FOOBAR', "FOOBAR", 0, "àèò", STR_PAD_BOTH]; yield ['FOOBAR', "FOOBAR", -10, "àèò", STR_PAD_BOTH]; yield ['àèòàèòàèFOO', "FOO", 11, "àèò", STR_PAD_LEFT]; yield ['àèòàèòàFOO', "FOO", 10, "àèò", STR_PAD_LEFT]; yield ['àèòàèòàBAAZ', "BAAZ", 11, "àèò", STR_PAD_LEFT]; yield ['àèòàèòBAAZ', "BAAZ", 10, "àèò", STR_PAD_LEFT]; yield ['FOOBAR', "FOOBAR", 6, "àèò", STR_PAD_LEFT]; yield ['FOOBAR', "FOOBAR", 1, "àèò", STR_PAD_LEFT]; yield ['FOOBAR', "FOOBAR", 0, "àèò", STR_PAD_LEFT]; yield ['FOOBAR', "FOOBAR", -10, "àèò", STR_PAD_LEFT]; yield ['FOOàèòàèòàè', "FOO", 11, "àèò", STR_PAD_RIGHT]; yield ['FOOàèòàèòà', "FOO", 10, "àèò", STR_PAD_RIGHT]; yield ['BAAZàèòàèòà', "BAAZ", 11, "àèò", STR_PAD_RIGHT]; yield ['BAAZàèòàèò', "BAAZ", 10, "àèò", STR_PAD_RIGHT]; yield ['FOOBAR', "FOOBAR", 6, "àèò", STR_PAD_RIGHT]; yield ['FOOBAR', "FOOBAR", 1, "àèò", STR_PAD_RIGHT]; yield ['FOOBAR', "FOOBAR", 0, "àèò", STR_PAD_RIGHT]; yield ['FOOBAR', "FOOBAR", -10, "àèò", STR_PAD_RIGHT]; } }