Skip to content

Commit

Permalink
fix trailing null characters (\0) from tag
Browse files Browse the repository at this point in the history
  • Loading branch information
Ganesh Tiwari(gtiwari333) committed Nov 21, 2023
1 parent f6d848b commit 997e515
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
20 changes: 19 additions & 1 deletion Source/com/drew/lang/SequentialReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,9 @@ public StringValue getNullTerminatedStringValue(int maxLengthBytes, Charset char

/**
* Returns the sequence of bytes punctuated by a <code>\0</code> value.
*
* It will place the cursor after the first occurrence of <code>\0</code>.
* <br/>
* Use <code>getNullTerminatedStringAndSkipToNextPosition</code> if you want the cursor to move moved at the end of <code>maxLengthBytes</code>.
* @param maxLengthBytes The maximum number of bytes to read. If a <code>\0</code> byte is not reached within this limit,
* the returned array will be <code>maxLengthBytes</code> long.
* @return The read byte array, excluding the null terminator.
Expand All @@ -386,4 +388,20 @@ public byte[] getNullTerminatedBytes(int maxLengthBytes) throws IOException
System.arraycopy(buffer, 0, bytes, 0, length);
return bytes;
}


/**
* Read until the null terminated byte and automatically move the end of the requested position.
* @param maxLengthBytes
* @param charset
* @return
* @throws IOException
*/
public StringValue getNullTerminatedStringAndSkipToNextPosition(int maxLengthBytes, Charset charset) throws IOException {
byte[] bytes = this.getNullTerminatedBytes(maxLengthBytes);
if (bytes.length < maxLengthBytes - 1) {
this.trySkip(maxLengthBytes - bytes.length - 1);
}
return new StringValue(bytes, charset);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ public static NikonPictureControl1Directory read(byte[] bytes) throws IOExceptio

NikonPictureControl1Directory directory = new NikonPictureControl1Directory();

directory.setObject(TAG_PICTURE_CONTROL_VERSION, reader.getStringValue(4, Charsets.UTF_8));
directory.setObject(TAG_PICTURE_CONTROL_NAME, reader.getStringValue(20, Charsets.UTF_8));
directory.setObject(TAG_PICTURE_CONTROL_BASE, reader.getStringValue(20, Charsets.UTF_8));
directory.setString(TAG_PICTURE_CONTROL_VERSION, reader.getNullTerminatedStringAndSkipToNextPosition(4, Charsets.UTF_8).toString());
directory.setString(TAG_PICTURE_CONTROL_NAME, reader.getNullTerminatedStringAndSkipToNextPosition(20, Charsets.UTF_8).toString());
directory.setString(TAG_PICTURE_CONTROL_BASE, reader.getNullTerminatedStringAndSkipToNextPosition(20, Charsets.UTF_8).toString());
reader.skip(4);
directory.setObject(TAG_PICTURE_CONTROL_ADJUST, reader.getUInt8());
directory.setObject(TAG_PICTURE_CONTROL_QUICK_ADJUST, reader.getUInt8());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ public static NikonPictureControl2Directory read(byte[] bytes) throws IOExceptio

NikonPictureControl2Directory directory = new NikonPictureControl2Directory();

directory.setString(TAG_PICTURE_CONTROL_VERSION, reader.getStringValue(4, Charsets.UTF_8).toString());
directory.setString(TAG_PICTURE_CONTROL_NAME, reader.getStringValue(20, Charsets.UTF_8).toString());
directory.setString(TAG_PICTURE_CONTROL_BASE, reader.getStringValue(20, Charsets.UTF_8).toString());
directory.setString(TAG_PICTURE_CONTROL_VERSION, reader.getNullTerminatedStringAndSkipToNextPosition(4, Charsets.UTF_8).toString());
directory.setString(TAG_PICTURE_CONTROL_NAME, reader.getNullTerminatedStringAndSkipToNextPosition(20, Charsets.UTF_8).toString());
directory.setString(TAG_PICTURE_CONTROL_BASE, reader.getNullTerminatedStringAndSkipToNextPosition(20, Charsets.UTF_8).toString());

reader.skip(4);
directory.setObject(TAG_PICTURE_CONTROL_ADJUST, reader.getByte());
Expand Down
29 changes: 22 additions & 7 deletions Tests/com/drew/lang/SequentialAccessTestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -241,24 +241,39 @@ public void testGetNullTerminatedString() throws IOException
}

@Test
public void testGetNullTerminatedStringCursorPositionTest() throws IOException
{
public void testGetNullTerminatedStringCursorPositionTest() throws IOException {
byte NULL = 0x00;
byte[] bytes = new byte[]{0x41, 0x42, NULL, NULL, NULL, 0x43, 0x44, NULL, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}; //AB\0\0\0CD\0ABCDEF
SequentialReader reader = createReader(bytes);

// try to read first five values
assertEquals("AB", reader.getNullTerminatedString(5, Charsets.UTF_8));
/*
tried to read first five values
*/
assertEquals("AB", reader.getNullTerminatedString(5, Charsets.UTF_8).toString());

// the cursor is after B (third) position
/*
the cursor is after B (third) position
*/
assertEquals(reader.getPosition(), 3);
reader.skip(2);

assertEquals("CD", reader.getNullTerminatedString(3, Charsets.UTF_8));
assertEquals("CD", reader.getNullTerminatedString(3, Charsets.UTF_8).toString());

assertEquals(reader.getPosition(), 8);
//no need to skip to next position. since there's only one \0 character after "CD"
assertEquals("ABCDEF", reader.getNullTerminatedString(6, Charsets.UTF_8));

assertEquals("ABCDEF", reader.getNullTerminatedString(6, Charsets.UTF_8).toString());
}

@Test
public void testGetNullTerminatedStringAndSkipToNextPosition() throws IOException {
byte NULL = 0x00;
byte[] bytes = new byte[]{0x41, 0x42, NULL, NULL, NULL, 0x43, 0x44, NULL, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
SequentialReader reader = createReader(bytes);

assertEquals("AB", reader.getNullTerminatedStringAndSkipToNextPosition(5, Charsets.UTF_8).toString());
assertEquals("CD", reader.getNullTerminatedStringAndSkipToNextPosition(3, Charsets.UTF_8).toString());
assertEquals("ABCDEF", reader.getNullTerminatedStringAndSkipToNextPosition(6, Charsets.UTF_8).toString());
}

@Test
Expand Down

0 comments on commit 997e515

Please sign in to comment.