Skip to content

Commit bd77491

Browse files
committed
Rewrite README with comprehensive documentation
Add detailed documentation including: - Feature overview and module descriptions - Maven installation instructions for all modules - Quick start examples for reading/writing values - Examples for byte[], ByteBuffer, ByteBuf, and unsigned types - Byte ordering explanation with visual examples - Complete API overview table - Development setup instructions with Maven toolchains Add validate_readme_examples.py to verify code examples compile and produce expected results using JBang.
1 parent 628de29 commit bd77491

3 files changed

Lines changed: 636 additions & 12 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,5 @@ build/
3535
.vscode/
3636

3737
### Mac OS ###
38-
.DS_Store
38+
.DS_Store
39+
/generated-examples/

README.md

Lines changed: 214 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,217 @@
1-
## ByteOps Utility Functions
1+
# ByteOps
22

3-
Utility functions for getting values from and setting values into collections of bytes, taking into account byte order and word order.
3+
[![License](https://img.shields.io/badge/License-EPL%202.0-blue.svg)](https://www.eclipse.org/legal/epl-2.0/)
44

5-
Supported "bytes":
6-
- `byte[]`
7-
- `java.nio.ByteBuffer`
8-
- `io.netty.buffer.ByteBuf`
5+
Utility functions for reading and writing primitive values from byte collections with explicit byte
6+
order and word order control.
97

10-
Supported variations:
11-
- Big-Endian
12-
- Little-Endian
13-
- Big-Endian + Low-High
14-
- Little-Endian + Low-High
8+
## Features
9+
10+
- **Multiple byte sources**: `byte[]`, `java.nio.ByteBuffer`, and Netty `ByteBuf`
11+
- **Four byte ordering variations**: Big-endian, little-endian, and word-swapped variants
12+
- **Unsigned type support**: Optional modules for jOOU and Eclipse Milo unsigned types
13+
- **Zero dependencies**: Core module has no runtime dependencies (besides JSpecify annotations)
14+
- **Java 11+**: Compatible with Java 11 and later
15+
16+
## Installation
17+
18+
Add the dependency to your `pom.xml`:
19+
20+
```xml
21+
<dependency>
22+
<groupId>com.digitalpetri.util</groupId>
23+
<artifactId>byteops</artifactId>
24+
<version>0.1.4-SNAPSHOT</version>
25+
</dependency>
26+
```
27+
28+
### Available Modules
29+
30+
| Module | Artifact ID | Description |
31+
|-----------------|--------------------|---------------------------------------------------------------------------------|
32+
| Core | `byteops` | `byte[]` and `ByteBuffer` support |
33+
| Netty | `byteops-netty` | Netty `ByteBuf` support |
34+
| Unsigned (jOOU) | `byteops-unsigned` | `UByte`, `UShort`, `UInteger`, `ULong` via [jOOU](https://github.com/jOOQ/jOOU) |
35+
| Unsigned (Milo) | `byteops-milo` | Unsigned types from [Eclipse Milo](https://github.com/eclipse/milo) |
36+
37+
## Quick Start
38+
39+
### Reading Values
40+
41+
```java
42+
import com.digitalpetri.util.byteops.ByteArrayByteOps;
43+
import com.digitalpetri.util.byteops.ByteOps;
44+
45+
// Get a ByteOps instance for your preferred byte ordering
46+
ByteOps<byte[]> ops = ByteArrayByteOps.BIG_ENDIAN;
47+
48+
byte[] data = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
49+
50+
short s = ops.getShort(data, 0); // 0x0001
51+
int i = ops.getInt(data, 0); // 0x00010203
52+
long l = ops.getLong(data, 0); // 0x0001020304050607L
53+
float f = ops.getFloat(data, 0); // Float.intBitsToFloat(0x00010203)
54+
double d = ops.getDouble(data, 0); // Double.longBitsToDouble(0x0001020304050607L)
55+
```
56+
57+
### Writing Values
58+
59+
```java
60+
ByteOps<byte[]> ops = ByteArrayByteOps.LITTLE_ENDIAN;
61+
62+
byte[] buffer = new byte[8];
63+
ops.setInt(buffer, 0, 0x01020304);
64+
ops.setInt(buffer, 4, 0x05060708);
65+
// buffer: [0x04, 0x03, 0x02, 0x01, 0x08, 0x07, 0x06, 0x05]
66+
```
67+
68+
### Working with Arrays
69+
70+
```java
71+
ByteOps<byte[]> ops = ByteArrayByteOps.BIG_ENDIAN;
72+
73+
// Read an array of ints (2 ints = 8 bytes)
74+
byte[] data = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
75+
int[] ints = ops.getIntArray(data, 0, 2); // [0x00010203, 0x04050607]
76+
77+
// Write an array of shorts
78+
byte[] buffer = new byte[4];
79+
ops.setShortArray(buffer, 0, new short[] {0x0102, 0x0304});
80+
// buffer: [0x01, 0x02, 0x03, 0x04]
81+
```
82+
83+
### With ByteBuffer
84+
85+
```java
86+
import com.digitalpetri.util.byteops.ByteBufferByteOps;
87+
import java.nio.ByteBuffer;
88+
89+
ByteOps<ByteBuffer> ops = ByteBufferByteOps.BIG_ENDIAN;
90+
91+
ByteBuffer buffer = ByteBuffer.allocate(8);
92+
ops.setLong(buffer, 0, 0x0102030405060708L);
93+
94+
long value = ops.getLong(buffer, 0); // 0x0102030405060708L
95+
```
96+
97+
### With Netty ByteBuf
98+
99+
```java
100+
import com.digitalpetri.util.byteops.netty.ByteBufByteOps;
101+
import io.netty.buffer.ByteBuf;
102+
import io.netty.buffer.Unpooled;
103+
104+
ByteOps<ByteBuf> ops = ByteBufByteOps.LITTLE_ENDIAN;
105+
106+
ByteBuf buf = Unpooled.buffer(8);
107+
buf.writeZero(8); // ensure writable bytes
108+
ops.setLong(buf, 0, 0x0102030405060708L);
109+
110+
long value = ops.getLong(buf, 0); // 0x0102030405060708L
111+
```
112+
113+
### Unsigned Types (jOOU)
114+
115+
```java
116+
import com.digitalpetri.util.byteops.unsigned.UnsignedByteOps;
117+
import org.joou.UInteger;
118+
119+
ByteOps<byte[]> baseOps = ByteArrayByteOps.BIG_ENDIAN;
120+
UnsignedByteOps<byte[]> ops = UnsignedByteOps.of(baseOps);
121+
122+
byte[] data = new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
123+
UInteger value = ops.getUInt(data, 0); // 4294967295 (not -1)
124+
```
125+
126+
## Byte Ordering
127+
128+
Four byte ordering variations are available for each implementation:
129+
130+
| Constant | Byte Order | Word Order |
131+
|--------------------------|------------|------------|
132+
| `BIG_ENDIAN` | Big | High-Low |
133+
| `LITTLE_ENDIAN` | Little | High-Low |
134+
| `BIG_ENDIAN_LOW_HIGH` | Big | Low-High |
135+
| `LITTLE_ENDIAN_LOW_HIGH` | Little | Low-High |
136+
137+
### Visual Example
138+
139+
For a 32-bit integer `0x01020304`:
140+
141+
```
142+
BIG_ENDIAN: [0x01, 0x02, 0x03, 0x04] (bytes: 1,2,3,4)
143+
LITTLE_ENDIAN: [0x04, 0x03, 0x02, 0x01] (bytes: 4,3,2,1)
144+
BIG_ENDIAN_LOW_HIGH: [0x03, 0x04, 0x01, 0x02] (words swapped: 3,4,1,2)
145+
LITTLE_ENDIAN_LOW_HIGH: [0x02, 0x01, 0x04, 0x03] (words swapped: 2,1,4,3)
146+
```
147+
148+
## API Overview
149+
150+
The `ByteOps<T>` interface provides:
151+
152+
### Single Value Operations
153+
154+
| Method | Size | Description |
155+
|-----------------------------|---------|--------------------------------|
156+
| `getBoolean` / `setBoolean` | 1 byte | `false` = 0, `true` = non-zero |
157+
| `getByte` / `setByte` | 1 byte | Signed byte |
158+
| `getShort` / `setShort` | 2 bytes | Signed 16-bit integer |
159+
| `getInt` / `setInt` | 4 bytes | Signed 32-bit integer |
160+
| `getLong` / `setLong` | 8 bytes | Signed 64-bit integer |
161+
| `getFloat` / `setFloat` | 4 bytes | IEEE 754 single-precision |
162+
| `getDouble` / `setDouble` | 8 bytes | IEEE 754 double-precision |
163+
164+
### Array Operations
165+
166+
- `get*Array` / `set*Array` - Primitive arrays (`boolean[]`, `byte[]`, `short[]`, etc.)
167+
- `getBoxed*Array` / `setBoxed*Array` - Boxed arrays (`Boolean[]`, `Byte[]`, `Short[]`, etc.)
168+
169+
## Development
170+
171+
### Requirements
172+
173+
- **JDK 17** is required to build (via Maven Toolchains)
174+
- **Target**: Java 11 bytecode
175+
176+
### Maven Toolchains Setup
177+
178+
Create or edit `~/.m2/toolchains.xml`:
179+
180+
```xml
181+
<?xml version="1.0" encoding="UTF-8"?>
182+
<toolchains>
183+
<toolchain>
184+
<type>jdk</type>
185+
<provides>
186+
<version>17</version>
187+
</provides>
188+
<configuration>
189+
<jdkHome>/path/to/your/jdk-17</jdkHome>
190+
</configuration>
191+
</toolchain>
192+
</toolchains>
193+
```
194+
195+
### Build Commands
196+
197+
```bash
198+
mvn clean package # Build all modules
199+
mvn test # Run tests
200+
mvn spotless:apply # Format code (Google Java Format)
201+
mvn spotless:check # Check code formatting
202+
```
203+
204+
### Project Structure
205+
206+
```
207+
byteops/
208+
├── byteops/ # Core module (byte[], ByteBuffer)
209+
├── byteops-netty/ # Netty ByteBuf support
210+
├── byteops-unsigned/ # jOOU unsigned types (UByte, UShort, UInteger, ULong)
211+
└── byteops-milo/ # Eclipse Milo unsigned types
212+
```
213+
214+
## License
215+
216+
This project is licensed under
217+
the [Eclipse Public License 2.0](https://www.eclipse.org/legal/epl-2.0/).

0 commit comments

Comments
 (0)