-
Notifications
You must be signed in to change notification settings - Fork 499
Adding the ARJ (Archived by Robert Jung) format #994
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…upporting 'store' for single file archives. Multi-file archives and all compression algorithms still require implementations.
|
Thanks for this! Not sure why windows only tests are failing for this PR and I'm currently window machineless |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for the ARJ archive format to SharpCompress. The implementation includes readers, headers, and factory classes for handling ARJ archives.
Key Changes
- Added ARJ format support with reader and header parsing functionality
- Registered ARJ factory in the factory system
- Added test cases for ARJ archive reading
- Updated package dependency from Microsoft.NET.ILLink.Tasks 8.0.17 to 8.0.21
- Updated error message to include ARJ in supported formats list
Reviewed Changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| src/SharpCompress/Readers/Arj/ArjReader.cs | New ARJ reader implementation for reading ARJ archives |
| src/SharpCompress/Common/Arj/Headers/*.cs | ARJ header parsing classes for main, local, and base headers |
| src/SharpCompress/Common/Arj/ArjEntry.cs | ARJ entry implementation representing files in ARJ archives |
| src/SharpCompress/Common/Arj/ArjFilePart.cs | File part implementation for ARJ entries |
| src/SharpCompress/Common/Arj/ArjVolume.cs | Volume implementation for ARJ archives |
| src/SharpCompress/Factories/ArjFactory.cs | Factory implementation for ARJ format detection and reader creation |
| src/SharpCompress/Factories/Factory.cs | Registered ARJ factory in the static factory system |
| src/SharpCompress/Common/ArchiveType.cs | Added Arj to the ArchiveType enumeration |
| src/SharpCompress/Readers/ReaderFactory.cs | Updated error message to include Arj in supported formats |
| tests/SharpCompress.Test/Arj/ArjReaderTests.cs | Test class for ARJ reader functionality |
| tests/TestArchives/Archives/Arj.store.arj | Test archive file for ARJ format validation |
| src/SharpCompress/packages.lock.json | Updated Microsoft.NET.ILLink.Tasks to version 8.0.21 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| using SharpCompress.Common.Zip; | ||
| using SharpCompress.Common.Zip.Headers; |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These Zip-related using directives appear to be unnecessary. The ArjReader doesn't reference any Zip types in its implementation. These should be removed to avoid confusion and unnecessary dependencies.
| using SharpCompress.Common.Zip; | |
| using SharpCompress.Common.Zip.Headers; |
|
|
||
| private void ProcessArchive(string archiveName) | ||
| { | ||
| // Process a given archive by its name |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Call to 'System.IO.Path.Combine'.
| // Process a given archive by its name | |
| // Process a given archive by its name | |
| if (Path.IsPathRooted(archiveName) || archiveName != Path.GetFileName(archiveName)) | |
| { | |
| throw new ArgumentException("Invalid archive name: must be a simple file name.", nameof(archiveName)); | |
| } |
| return Array.Empty<byte>(); | ||
|
|
||
| byte[] crc = new byte[4]; | ||
| read = stream.Read(crc, 0, 4); |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to read is useless, since its value is never read.
| read = stream.Read(crc, 0, 4); | |
| if (stream.Read(crc, 0, 4) < 4) | |
| throw new EndOfStreamException("Unexpected end of stream while reading header CRC."); |
| } | ||
|
|
||
| byte headerSize = headerBytes[offset++]; | ||
| byte archiverVersionNumber = headerBytes[offset++]; |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to archiverVersionNumber is useless, since its value is never read.
| byte archiverVersionNumber = headerBytes[offset++]; | |
| offset++; |
|
|
||
| byte headerSize = headerBytes[offset++]; | ||
| byte archiverVersionNumber = headerBytes[offset++]; | ||
| byte minVersionToExtract = headerBytes[offset++]; |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to minVersionToExtract is useless, since its value is never read.
| byte minVersionToExtract = headerBytes[offset++]; | |
| offset++; // Skip minVersionToExtract, value not used |
| byte archiverVersionNumber = headerBytes[offset++]; | ||
| byte minVersionToExtract = headerBytes[offset++]; | ||
| HostOS hostOS = (HostOS)headerBytes[offset++]; | ||
| byte arjFlags = headerBytes[offset++]; |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to arjFlags is useless, since its value is never read.
| byte arjFlags = headerBytes[offset++]; | |
| offset++; |
| byte minVersionToExtract = headerBytes[offset++]; | ||
| HostOS hostOS = (HostOS)headerBytes[offset++]; | ||
| byte arjFlags = headerBytes[offset++]; | ||
| CompressionMethod compressionMethod = CompressionMethodFromByte(headerBytes[offset++]); |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to compressionMethod is useless, since its value is never read.
| CompressionMethod compressionMethod = CompressionMethodFromByte(headerBytes[offset++]); |
| HostOS hostOS = (HostOS)headerBytes[offset++]; | ||
| byte arjFlags = headerBytes[offset++]; | ||
| CompressionMethod compressionMethod = CompressionMethodFromByte(headerBytes[offset++]); | ||
| FileType fileType = FileTypeFromByte(headerBytes[offset++]); |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to fileType is useless, since its value is never read.
| FileType fileType = FileTypeFromByte(headerBytes[offset++]); |
| protected override IEnumerable<ArjEntry> GetEntries(Stream stream) | ||
| { | ||
| var headerReader = new ArjMainHeader(new ArchiveEncoding()); | ||
| var mainHeader = headerReader.Read(stream); |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to mainHeader is useless, since its value is never read.
| var mainHeader = headerReader.Read(stream); | |
| headerReader.Read(stream); |
| catch | ||
| { | ||
| DateTime = DateTime.MinValue; | ||
| } |
Copilot
AI
Oct 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generic catch clause.
| catch | |
| { | |
| DateTime = DateTime.MinValue; | |
| } | |
| catch (ArgumentOutOfRangeException) | |
| { | |
| DateTime = DateTime.MinValue; | |
| } | |
| catch (ArgumentException) | |
| { | |
| DateTime = DateTime.MinValue; | |
| } |
|
#1000 might fix things |
|
all tests pass on my windows box; but I see some obvious fixes that I need to make, will have to amend the PR. |
|
I'll keep an eye out for your fixes! |
Refactored TestBase to support archives with mixed compression algorithms.Merge branch 'adamhathcock:master' into master
|
@adamhathcock , still all tests pass on my windows box, the error seems to be unrelated to my changes. |
|
Thanks! |
Initial implementation of the ARJ (Archived by Robert Jung) format, supporting 'store' for single file archives. Multi-file archives and all compression algorithms still require implementations.