Program entry point: gxpand+ax\src\main.d 266 line
int main(string args)
Then u use "unpack". Program goes to 282 line
Enters into unpack function at line 184
void unpack(DirEntry input, string outputPath)
Then going into 192 line, because it is file.
Stream inputStream = new std.stream.File(input.name);
scope (exit) inputStream.close();
Enters into unpackFile function, which is located at line 141
void unpackFile(Stream input, string outputPath)
Next, going into branch at line 147
writeln("UnLZ ", outputPath);
Creating memory stream, and at line 152:
Starts main decoding function. Entering into gxLzDecode defined in file "\gxpand+ax\src\gx\lz.d" at line 305:
void gxLzDecode(Stream input, Stream output)
BinaryStream s = new BinaryStream(new EndianStream(input, Endian.LittleEndian));
uint inputSize = s.read!uint;
uint outputSize = s.read!uint;
ubyte inputArr = new ubyte[inputSize];
ubyte outputArr = lzDecode(inputArr);
enforce(outputArr.length == outputSize, "gxLzDecode: Invalid stream.");
Here we see, that new BinaryStream created based on file from filepath <input>.
Right from beginning of file, it reads two "uint" (unsigned integers but I don't know how many bytes).
First intended to be input size, and second intended to be output size.
And, right after them, reading input bytes with length = input size.
So, we see there is reading from BinaryStream instance, which is defined in file "\gxpand+ax\src\gx\binarystream.d"
And, there is method "read" at line 17, which is used for reading "uint":
When reading of uint occurs, then in this function program going into branch at line 29
But, source is instance of FilterStream, which is defined in library "std.stream" which included at line 2.
So, if you check reference, you will find here
class FilterStream: std.stream.Stream;
It means, that FilterStream inherits Stream, and some before
abstract class Stream: std.stream.InputStream, std.stream.OutputStream;
It means, that FilterStream inherits InputStream, and somewhere on same page inside description of InputStream:
abstract void read(out uint x);
Read a basic type or counted string.
Throw a ReadException if it could not be read. Outside of byte, ubyte, and char, the format is implementation-specific and should not be used except as opposite actions to write.
I don't want to test this program, and I don't run it at all. That's all just my guesses.
But, I don't think, that your files less than 8 bytes to make exception of reading two ints.
I guess, when program reads incorrect file size, which is much bigger than input file, and trying at line 312 of file "\gxpand+ax\src\gx\lz.d":
It fails. Because... From documentation:
abstract void readExact(void* buffer, size_t size);
Read exactly size bytes into the buffer.
Throws a ReadException if it is not correct.
P.S. I never ran it. It's just my guesses. I don't even know D language. This is some simple example how to understand someone else's code.