Skip to content

Commit 6eca8af

Browse files
committed
Fixing #3 (after only so many years)
1 parent cb4beec commit 6eca8af

4 files changed

Lines changed: 42 additions & 8 deletions

File tree

‎README.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ $parser = new \Fanatique\Parser\FixedLengthFileParser();
4545
// Set the chopping map (aka where to extract the fields)
4646
$parser->setChoppingMap([
4747
['field_name' => 'id', 'start' => 0, 'length' => 2],
48-
['field_name' => 'name', 'start' => 2, 'length' => 5],
48+
['field_name' => 'name', 'start' => 2, 'length' => 5, 'align' => 'left'],
4949
['field_name' => 'team', 'start' => 7, 'length' => 5],
5050
]);
5151

@@ -66,6 +66,7 @@ var_dump($parser->getContent());
6666

6767
`field_name` and `length` are required. `start` is optional — if omitted, it is
6868
calculated from the previous entry's `start + length`.
69+
`align` is optional and configures which padding spaces to trim: `'left'` (removes trailing), `'right'` (removes leading), or `'both'` (the default).
6970

7071
### Registering a pre-flight check
7172

‎example/parsing.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
// Set the chopping map (aka where to extract the fields)
2222
$parser->setChoppingMap([
2323
['field_name' => 'id', 'length' => 2],
24-
['field_name' => 'name', 'start' => 2, 'length' => 5],
24+
['field_name' => 'name', 'start' => 2, 'length' => 5, 'align' => 'left'],
2525
['field_name' => 'team', 'length' => 5], // start is the sum of name:start(2) plus name:length(5) = 7
2626
]);
2727

‎src/FixedLengthFileParser.php‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class FixedLengthFileParser implements ParserInterface
2525
* Arrays describing field_name, start, and length for each value
2626
* encoded in a line of the file to be parsed.
2727
*
28-
* @var array<int, array{field_name: string, start?: int, length: int}>
28+
* @var array<int, array{field_name: string, start?: int, length: int, align?: 'left'|'right'|'both'}>
2929
*/
3030
protected array $choppingMap = [];
3131

@@ -66,9 +66,10 @@ class FixedLengthFileParser implements ParserInterface
6666
*
6767
* Each entry must contain 'field_name' and 'length'. The 'start' key is
6868
* optional — if omitted, it is calculated from the previous entry's
69-
* start + length.
69+
* start + length. The 'align' key is optional and can be 'left', 'right',
70+
* or 'both' (default is 'both').
7071
*
71-
* @param array<int, array{field_name: string, start?: int, length: int}> $map
72+
* @param array<int, array{field_name: string, start?: int, length: int, align?: 'left'|'right'|'both'}> $map
7273
*/
7374
public function setChoppingMap(array $map): void
7475
{
@@ -167,9 +168,15 @@ protected function parseLine(string $buffer): array
167168
: $start + $this->choppingMap[$i]['length'];
168169

169170
$name = $this->choppingMap[$i]['field_name'];
170-
$currentLine[$name] = trim(
171-
substr($buffer, $start, $this->choppingMap[$i]['length'])
172-
);
171+
$rawValue = substr($buffer, $start, $this->choppingMap[$i]['length']);
172+
173+
$align = $this->choppingMap[$i]['align'] ?? 'both';
174+
175+
$currentLine[$name] = match ($align) {
176+
'left' => rtrim($rawValue),
177+
'right' => ltrim($rawValue),
178+
default => trim($rawValue),
179+
};
173180
}
174181

175182
// Apply callback if registered

‎tests/FixedLengthFileParserTest.php‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,4 +293,30 @@ public function testEmptyChoppingMapReturnsEmptyRows(): void
293293
$this->assertSame([], $row);
294294
}
295295
}
296+
public function testParseWithFieldAlignment(): void
297+
{
298+
$map = [
299+
['field_name' => 'left_aligned', 'length' => 10, 'align' => 'left'],
300+
['field_name' => 'right_aligned', 'length' => 10, 'align' => 'right'],
301+
['field_name' => 'default_align', 'length' => 10],
302+
];
303+
304+
$parser = new FixedLengthFileParser();
305+
$parser->setChoppingMap($map);
306+
307+
$tempFile = sys_get_temp_dir() . '/alignment_test.dat';
308+
file_put_contents($tempFile, " abc 123 xyz \n");
309+
310+
$parser->setFilePath($tempFile);
311+
$parser->parse();
312+
313+
$content = $parser->getContent();
314+
315+
$this->assertCount(1, $content);
316+
$this->assertSame(' abc', $content[0]['left_aligned']); // left removes right padding
317+
$this->assertSame('123 ', $content[0]['right_aligned']); // right removes left padding
318+
$this->assertSame('xyz', $content[0]['default_align']); // default removes both padding
319+
320+
unlink($tempFile);
321+
}
296322
}

0 commit comments

Comments
 (0)