private byte[] readUntilNullTerm(long index, int charLen) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		long curPos = index;
		for (; Long.compareUnsigned(curPos, index) >= 0; curPos += charLen) {
			// loop while we haven't wrapped the index value around to 0
			if ((long) baos.size() + charLen >= MAX_SANE_BUFFER) {
				// gracefully handle hitting the limit of the ByteArrayOutputStream before it fails
				throw new EOFException("Run-on unterminated string at 0x%s..0x%s".formatted(
					Long.toUnsignedString(index, 16), Long.toUnsignedString(curPos, 16)));
			}
			try {
				byte[] bytes = readByteArray(curPos, charLen);
				if (isNullTerm(bytes, 0, charLen)) {
					return baos.toByteArray();
				}
				baos.write(bytes);
			}
			catch (IOException e) {
				if (baos.size() == 0) {
					// failed trying to read the first byte
					throw new EOFException("Attempted to read string at 0x%s"
							.formatted(Long.toUnsignedString(index, 16)));
				}
				break; // fall thru to throw new EOF(unterminate string)
			}
		}
		// we've wrapped around the end of a 64bit address space and curPos is less than starting position
		throw new EOFException("Unterminated string at 0x%s..0x%s"
				.formatted(Long.toUnsignedString(index, 16), Long.toUnsignedString(curPos, 16)));
	}
Reads an unsigned int32 value, and returns it as a java int (instead of a java long).
<p>
If the value is outside the range of 0..Integer.MAX_VALUE, an InvalidDataException is thrown.
<p>
Useful for reading uint32 values that are going to be used in java to allocate arrays or
other similar cases where the value must be a java integer.
   
@param dc {@link BigEndianDataConverter BE} or {@link LittleEndianDataConverter LE}
@return the uint32 value read from the stream, if it fits into the range [0..MAX_VALUE] 
of a java integer 
@throws IOException if there was an error reading
@throws InvalidDataException if value can not be held in a java integer
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/BinaryReader.java