Skip to content

Commit

Permalink
Implement Cursor::amend
Browse files Browse the repository at this point in the history
  • Loading branch information
kafkiansky committed Feb 7, 2025
1 parent c90a25f commit b0c3cc8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,23 @@ var_dump($items); // [x, y]
$cursor->reset(); // by resetting it.
$cursor->seek(Seek::start(0)); // or seeking.
```

### Amend

Useful for operations such as compression to avoid creating a new buffer.

```php
<?php

declare(strict_types=1);

require_once __DIR__.'/vendor/autoload.php';

use Thesis\ByteCursor\Cursor;
use Thesis\ByteCursor\Seek;

$cursor = Cursor::empty();
$cursor->write('secret');
$cursor->seek(Seek::start(0));
$cursor->amend(snappy_compress(...)); // no need to seek, amend automatically moves the cursor to the end
```
22 changes: 22 additions & 0 deletions src/Cursor.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,28 @@ public function __toString(): string
return $this->buffer;
}

/**
* @param callable(non-empty-string): non-empty-string $fix
* @param ?positive-int $len
*/
public function amend(callable $fix, ?int $len = null): void
{
$len ??= \strlen($this->buffer);

Check warning on line 221 in src/Cursor.php

View workflow job for this annotation

GitHub Actions / check / infection

Escaped Mutant for Mutator "AssignCoalesce": @@ @@ */ public function amend(callable $fix, ?int $len = null): void { - $len ??= \strlen($this->buffer); + $len = \strlen($this->buffer); if ($len > \strlen($this->buffer)) { throw new \UnexpectedValueException(\sprintf('Len of amend "%d" is longer than available buffer.', $len)); }
if ($len > \strlen($this->buffer)) {
throw new \UnexpectedValueException(\sprintf('Len of amend "%d" is longer than available buffer.', $len));
}

$v = substr($this->buffer, $this->position, $len);

Check warning on line 226 in src/Cursor.php

View workflow job for this annotation

GitHub Actions / check / infection

Escaped Mutant for Mutator "UnwrapSubstr": @@ @@ if ($len > \strlen($this->buffer)) { throw new \UnexpectedValueException(\sprintf('Len of amend "%d" is longer than available buffer.', $len)); } - $v = substr($this->buffer, $this->position, $len); + $v = $this->buffer; if ($v !== '') { $v = $fix($v); $this->buffer = substr($this->buffer, 0, $this->position);
if ($v !== '') {
$v = $fix($v);

$this->buffer = substr($this->buffer, 0, $this->position);

Check warning on line 230 in src/Cursor.php

View workflow job for this annotation

GitHub Actions / check / infection

Escaped Mutant for Mutator "DecrementInteger": @@ @@ $v = substr($this->buffer, $this->position, $len); if ($v !== '') { $v = $fix($v); - $this->buffer = substr($this->buffer, 0, $this->position); + $this->buffer = substr($this->buffer, -1, $this->position); $this->buffer .= $v; $this->buffer .= substr($this->buffer, $this->position + \strlen($v), \strlen($this->buffer)); $this->position = \strlen($this->buffer);

Check warning on line 230 in src/Cursor.php

View workflow job for this annotation

GitHub Actions / check / infection

Escaped Mutant for Mutator "IncrementInteger": @@ @@ $v = substr($this->buffer, $this->position, $len); if ($v !== '') { $v = $fix($v); - $this->buffer = substr($this->buffer, 0, $this->position); + $this->buffer = substr($this->buffer, 1, $this->position); $this->buffer .= $v; $this->buffer .= substr($this->buffer, $this->position + \strlen($v), \strlen($this->buffer)); $this->position = \strlen($this->buffer);
$this->buffer .= $v;

Check warning on line 231 in src/Cursor.php

View workflow job for this annotation

GitHub Actions / check / infection

Escaped Mutant for Mutator "Assignment": @@ @@ if ($v !== '') { $v = $fix($v); $this->buffer = substr($this->buffer, 0, $this->position); - $this->buffer .= $v; + $this->buffer = $v; $this->buffer .= substr($this->buffer, $this->position + \strlen($v), \strlen($this->buffer)); $this->position = \strlen($this->buffer); }
$this->buffer .= substr($this->buffer, $this->position + \strlen($v), \strlen($this->buffer));
$this->position = \strlen($this->buffer);
}
}

/**
* @return non-negative-int
*/
Expand Down
11 changes: 11 additions & 0 deletions tests/CursorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,15 @@ public function testReset(): void
self::assertCount(0, $cursor);
self::assertSame(0, $cursor->position());
}

public function testAmend(): void
{
$cursor = Cursor::empty();
$cursor->write('before compression');
$cursor->seek(Seek::start(0));
$cursor->amend(static fn(string $v): string => 'aftrcompr');
$cursor->write('xyz');
self::assertSame(\count($cursor), $cursor->position());
self::assertSame('aftrcomprxyz', $cursor->reset());
}
}

0 comments on commit b0c3cc8

Please sign in to comment.