[llvm] [z/OS] Add z/OS archive reading support (PR #187110)
Uyiosa Iyekekpolor via llvm-commits
llvm-commits at lists.llvm.org
Tue May 5 19:52:28 PDT 2026
================
@@ -368,6 +377,122 @@ Expected<uint64_t> BigArchiveMemberHeader::getSize() const {
return *SizeOrErr + alignTo(*NameLenOrErr, 2);
}
+template <std::size_t N>
+StringRef ebcdicFieldToASCII(const char (&Field)[N],
+ SmallVectorImpl<char> &Dst) {
+ Dst.clear();
+ StringRef Src = StringRef(Field, N);
+ ConverterEBCDIC::convertToUTF8(Src, Dst);
+ return StringRef(Dst.data(), Dst.size()).rtrim(" ");
+}
+
+ZOSArchiveMemberHeader::ZOSArchiveMemberHeader(const Archive *Parent,
+ const char *RawHeaderPtr,
+ uint64_t Size, Error *Err)
+ : ArchiveMemberHeader(Parent, RawHeaderPtr, Size, Err) {
+ ErrorAsOutParameter ErrAsOutParam(Err);
+ setMemberHeaderStrings(Err, Size);
+}
+
+Expected<uint64_t> ZOSArchiveMemberHeader::getSize() const {
+ SmallString<64> Dst;
+ return getArchiveMemberDecField(
+ "size", ebcdicFieldToASCII(ArMemHdr->Size, Dst), Parent, this);
+}
+
+Expected<StringRef> ZOSArchiveMemberHeader::getRawName() const {
+ return StringRef(RawMemberName);
+}
+
+Expected<StringRef> ZOSArchiveMemberHeader::getName(uint64_t Size) const {
+ return StringRef(MemberName);
+}
+
+StringRef ZOSArchiveMemberHeader::getRawAccessMode() const {
+ return StringRef(AccessMode);
+}
+
+StringRef ZOSArchiveMemberHeader::getRawLastModified() const {
+ return StringRef(LastModified);
+}
+
+StringRef ZOSArchiveMemberHeader::getRawUID() const { return StringRef(UID); }
+
+StringRef ZOSArchiveMemberHeader::getRawGID() const { return StringRef(GID); }
+
+void ZOSArchiveMemberHeader::setMemberHeaderStrings(Error *Err, uint64_t Size) {
+ SmallString<64> Dst;
+ uint64_t Offset =
+ reinterpret_cast<const char *>(ArMemHdr) - Parent->getData().data();
+
+ // Set RawMemberName
+ StringRef RawNameRef = ebcdicFieldToASCII(ArMemHdr->Name, Dst);
+ if (RawNameRef.empty() || RawNameRef[0] == ' ') {
+ *Err = malformedError("name contains a leading space for archive member "
+ "header at offset " +
+ Twine(Offset));
+ return;
+ }
+ RawMemberName.append(RawNameRef);
+
+ // Set MemberName.
+ if (RawNameRef.starts_with("#1/")) {
+ Expected<StringRef> NameOrErr = ArchiveMemberHeader::getName(Size);
+ if (!NameOrErr) {
+ *Err = NameOrErr.takeError();
+ return;
+ }
+ StringRef Name = NameOrErr.get();
+ Dst.clear();
+ ConverterEBCDIC::convertToUTF8(Name, Dst);
+ MemberName.append(Dst.str());
+ } else {
+ MemberName = RawMemberName;
+ }
+
+ // LastModified
+ StringRef LastModifiedRef = ebcdicFieldToASCII(ArMemHdr->LastModified, Dst);
+ if (LastModifiedRef.empty()) {
+ *Err =
+ malformedError("LastModified field is empty or contains only spaces in "
----------------
uyoyo0 wrote:
Thanks, I just added a test case for this
https://github.com/llvm/llvm-project/pull/187110
More information about the llvm-commits
mailing list