Skip to content

Commit aae02d7

Browse files
committed
Updating documentation and tests a bit.
1 parent 4627e08 commit aae02d7

File tree

7 files changed

+117
-8
lines changed

7 files changed

+117
-8
lines changed

api/README.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ To include in a Maven project:
1010
<dependency>
1111
<groupId>net.sf.applecommander</groupId>
1212
<artifactId>applesingle-api</artifactId>
13-
<version>1.0.0</version>
13+
<version>1.2.0</version>
1414
</dependency>
1515
```
1616

@@ -19,7 +19,7 @@ To include in a Gradle project:
1919
```groovy
2020
dependencies {
2121
// ...
22-
compile "net.sf.applecommander:applesingle-api:1.0.0"
22+
compile "net.sf.applecommander:applesingle-api:1.2.0"
2323
// ...
2424
}
2525
```
@@ -58,3 +58,31 @@ as.save(file);
5858
```
5959

6060
The `save(...)` method can save to a `File`, `Path`, or an `OutputStream`.
61+
62+
## Entries
63+
64+
If the higher-level API is insufficient, the lower-level API does allow either tracking of the processing
65+
(see code for the `analyze` subcommand) or alternate processing of `Entry` objects (see the `filter`
66+
subcommand).
67+
68+
To tap into the `AppleSingleReader` events, add as many reporters as required. For example, the `analyze`
69+
command uses these to display the details of the AppleSingle file as it is read:
70+
71+
```java
72+
AppleSingleReader reader = AppleSingleReader.builder(fileData)
73+
.readAtReporter((start,chunk,desc) -> used.add(IntRange.of(start, start + chunk.length)))
74+
.readAtReporter((start,chunk,desc) -> dumper.dump(start, chunk, desc))
75+
.versionReporter(this::reportVersion)
76+
.numberOfEntriesReporter(this::reportNumberOfEntries)
77+
.entryReporter(this::reportEntry)
78+
.build();
79+
```
80+
81+
To work with the raw `Entry` objects, use the various `AppleSingle#asEntries` methods. For instance, the
82+
`filter` subcommand bypasses the `AppleSingle` object altogether to implement the filter:
83+
84+
```java
85+
List<Entry> entries = stdinFlag ? AppleSingle.asEntries(System.in) : AppleSingle.asEntries(inputFile);
86+
// ...
87+
AppleSingle.write(outputStream, newEntries);
88+
```

api/src/main/java/io/github/applecommander/applesingle/AppleSingle.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ public void save(Path path) throws IOException {
111111
}
112112
}
113113

114+
/**
115+
* Common write capability for an AppleSingle. Also can be used by external entities to
116+
* write a properly formatted AppleSingle file without the ProDOS assumptions of AppleSingle.
117+
*/
114118
public static void write(OutputStream outputStream, List<Entry> entries) throws IOException {
115119
final byte[] filler = new byte[16];
116120
ByteBuffer buf = ByteBuffer.allocate(26).order(ByteOrder.BIG_ENDIAN);

api/src/main/java/io/github/applecommander/applesingle/Entry.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import java.nio.ByteOrder;
77
import java.util.Objects;
88

9+
/**
10+
* Represents an AppleSingle entry.
11+
*/
912
public class Entry {
1013
public static final int BYTES = 12;
1114
private int entryId;

api/src/main/java/io/github/applecommander/applesingle/FileDatesInfo.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import java.util.function.IntSupplier;
77

88
public class FileDatesInfo {
9-
/** The number of seconds at the begining of the AppleSingle date epoch since the Unix epoch began. */
9+
/** The number of seconds at the beginning of the AppleSingle date epoch since the Unix epoch began. */
1010
public static final Instant EPOCH_INSTANT = Instant.parse("2000-01-01T00:00:00.00Z");
1111
/** Per the AppleSingle technical notes. */
1212
public static final int UNKNOWN_DATE = 0x80000000;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package io.github.applecommander.applesingle;
2+
3+
import org.junit.Test;
4+
import static org.junit.Assert.*;
5+
6+
import java.io.IOException;
7+
8+
public class AppleSingleReaderTest {
9+
@Test(expected = NullPointerException.class)
10+
public void testDoesNotAcceptNull() {
11+
AppleSingleReader.builder(null);
12+
}
13+
14+
@Test
15+
public void testReporters() throws IOException {
16+
Ticker versionCalled = new Ticker();
17+
Ticker numberOfEntriesCalled = new Ticker();
18+
Ticker entryReporterCalled = new Ticker();
19+
Ticker readAtCalled = new Ticker();
20+
// Intentionally calling ticker 2x to ensure events do get chained
21+
AppleSingleReader r = AppleSingleReader.builder(SAMPLE_FILE)
22+
.versionReporter(v -> versionCalled.tick())
23+
.versionReporter(v -> assertEquals(AppleSingle.VERSION_NUMBER2, v.intValue()))
24+
.versionReporter(v -> versionCalled.tick())
25+
.numberOfEntriesReporter(n -> numberOfEntriesCalled.tick())
26+
.numberOfEntriesReporter(n -> assertEquals(1, n.intValue()))
27+
.numberOfEntriesReporter(n -> numberOfEntriesCalled.tick())
28+
.readAtReporter((o,b,d) -> readAtCalled.tick())
29+
.readAtReporter((o,b,d) -> readAtCalled.tick())
30+
.entryReporter(e -> entryReporterCalled.tick())
31+
.entryReporter(e -> assertEquals("Hello, World!\n", new String(e.getData())))
32+
.entryReporter(e -> assertEquals(e.getEntryId(), EntryType.DATA_FORK.entryId))
33+
.entryReporter(e -> entryReporterCalled.tick())
34+
.build();
35+
// Executes on the reader
36+
AppleSingle.asEntries(r);
37+
// Validate
38+
assertEquals(2, versionCalled.count());
39+
assertEquals(2, numberOfEntriesCalled.count());
40+
assertEquals(2, entryReporterCalled.count());
41+
assertTrue(readAtCalled.count() >= 2);
42+
}
43+
44+
/**
45+
* AppleSingle file with a simple Data Fork and nothing else.
46+
* <br/>
47+
* <code>
48+
* $ echo "Hello, World!" | asu create --stdin-fork=data --filetype=txt --stdout | asu filter --include=1 --stdin --stdout | hexdump -C
49+
* 00000000 00 05 16 00 00 02 00 00 00 00 00 00 00 00 00 00 |................|
50+
* 00000010 00 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 |................|
51+
* 00000020 00 26 00 00 00 0e 48 65 6c 6c 6f 2c 20 57 6f 72 |.&....Hello, Wor|
52+
* 00000030 6c 64 21 0a |ld!.|
53+
* </code>
54+
*/
55+
public static final byte[] SAMPLE_FILE = {
56+
0x00, 0x05, 0x16, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
58+
0x00, 0x26, 0x00, 0x00, 0x00, 0x0e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72,
59+
0x6c, 0x64, 0x21, 0x0a
60+
};
61+
62+
public static class Ticker {
63+
private int count;
64+
65+
public void tick() {
66+
this.count++;
67+
}
68+
public int count() {
69+
return this.count;
70+
}
71+
}
72+
}

tools/asu/README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ For the included command-line utility, we are using `asu` for the name.
44
`as` is the GNU Assembler while `applesingle` is already on Macintoshes.
55
Hopefully that will prevent some confusion!
66

7-
Note that all runs are with the `asu` alias defined as `alias asu='java -jar build/libs/applesingle-1.0.0.jar'`
7+
Note that all runs are with the `asu` alias defined as `alias asu='java -jar build/libs/applesingle-1.2.0.jar'`
88
(adjust as necessary).
99

1010
## Basic usage
1111

1212
```shell
13-
$ asu
13+
$ asu --help
1414
Usage: asu [-hV] [--debug] [COMMAND]
1515

1616
AppleSingle utility
@@ -21,10 +21,12 @@ Options:
2121
-V, --version Print version information and exit.
2222

2323
Commands:
24-
help Displays help information about the specified command
25-
info Display information about an AppleSingle file
24+
analyze Perform an analysis on an AppleSingle file
2625
create Create an AppleSingle file
2726
extract Extract contents of an AppleSingle file
27+
filter Filter an AppleSingle file
28+
help Displays help information about the specified command
29+
info Display information about an AppleSingle file
2830
```
2931
3032
## Subcommand help

tools/asu/src/main/java/io/github/applecommander/applesingle/tools/asu/AnalyzeCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public Void call() throws IOException {
5454
List<IntRange> used = new ArrayList<>();
5555
HexDumper dumper = HexDumper.standard();
5656
AppleSingleReader reader = AppleSingleReader.builder(fileData)
57-
.readAtReporter((start,b,d) -> used.add(IntRange.of(start, start + b.length)))
57+
.readAtReporter((start,chunk,desc) -> used.add(IntRange.of(start, start + chunk.length)))
5858
.readAtReporter((start,chunk,desc) -> dumper.dump(start, chunk, desc))
5959
.versionReporter(this::reportVersion)
6060
.numberOfEntriesReporter(this::reportNumberOfEntries)

0 commit comments

Comments
 (0)