From 362cbf0d747154f2617f2cabe20187235dcaba60 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sat, 6 Nov 2004 08:51:45 +0000 Subject: First kinda/sorta working version of the Archive library. Reading is not yet supported but writing works. Way too early to review this. More to come git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17499 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Archive/ArchiveInternals.h | 158 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 lib/Archive/ArchiveInternals.h (limited to 'lib/Archive/ArchiveInternals.h') diff --git a/lib/Archive/ArchiveInternals.h b/lib/Archive/ArchiveInternals.h new file mode 100644 index 0000000..dde8358 --- /dev/null +++ b/lib/Archive/ArchiveInternals.h @@ -0,0 +1,158 @@ +//===-- lib/Bytecode/ArchiveInternals.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Reid Spencer and is distributed under the +// University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Internal implementation header for LLVM Archive files. +// +//===----------------------------------------------------------------------===// + +#ifndef LIB_BYTECODE_ARCHIVEINTERNALS_H +#define LIB_BYTECODE_ARCHIVEINTERNALS_H + +#include "llvm/Bytecode/Archive.h" +#include "llvm/System/TimeValue.h" + +#define ARFILE_MAGIC "!\n" ///< magic string +#define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string +#define ARFILE_SYMTAB_NAME "/" ///< name of symtab entry +#define ARFILE_STRTAB_NAME "//" ///< name of strtab entry +#define ARFILE_PAD '\n' ///< inter-file align padding + +namespace llvm { + + /// The ArchiveMemberHeader structure is used internally for bytecode archives. + /// The header precedes each file member in the archive. This structure is + /// defined using character arrays for direct and correct interpretation + /// regardless of the endianess of the machine that produced it. + /// @brief Archive File Member Header + class ArchiveMemberHeader { + public: + void init() { + memset(name,' ',16); + memset(date,' ',12); + memset(uid,' ',6); + memset(gid,' ',6); + memset(mode,' ',8); + memset(size,' ',10); + fmag[0] = '`'; + fmag[1] = '\n'; + } + void setDate( int secondsSinceEpoch = 0 ) { + if (secondsSinceEpoch == 0) { + sys::TimeValue tv = sys::TimeValue::now(); + uint64_t secs; uint32_t nanos; + tv.GetTimespecTime(secs,nanos); + secondsSinceEpoch = (int) secs; + } + char buffer[20]; + sprintf(buffer,"%d", secondsSinceEpoch); + memcpy(date,buffer,strlen(buffer)); + } + + void setSize(size_t sz) { + char buffer[20]; + sprintf(buffer, "%u", (unsigned)sz); + memcpy(size,buffer,strlen(buffer)); + } + + void setMode(int m) { + char buffer[20]; + sprintf(buffer, "%o", m); + memcpy(mode,buffer,strlen(buffer)); + } + + void setUid(unsigned u) { + char buffer[20]; + sprintf(buffer, "%u", u); + memcpy(uid,buffer,strlen(buffer)); + } + + void setGid(unsigned g) { + char buffer[20]; + sprintf(buffer, "%u", g); + memcpy(gid,buffer,strlen(buffer)); + } + + bool setName(const std::string& nm) { + if (nm.length() > 0 && nm.length() <= 16) { + memcpy(name,nm.c_str(),nm.length()); + for (int i = nm.length()+1; i < 16; i++ ) name[i] = ' '; + return true; + } + return false; + } + + private: + char name[16]; ///< Name of the file member. The filename is terminated with '/' + ///< and blanks. The empty name (/ and 15 blanks) is for the + ///< symbol table. The special name "//" and 15 blanks is for + ///< the string table, used for long file names. It must be + ///< first in the archive. + char date[12]; ///< File date, decimal seconds since Epoch + char uid[6]; ///< user id in ASCII decimal + char gid[6]; ///< group id in ASCII decimal + char mode[8]; ///< file mode in ASCII octal + char size[10]; ///< file size in ASCII decimal + char fmag[2]; ///< Always contains ARFILE_MAGIC_TERMINATOR + + }; + + /// The ArchiveInternals class is used to hold the content of the archive + /// while it is in memory. It also provides the bulk of the implementation for + /// the llvm:Archive class's interface. + class Archive::ArchiveInternals { + /// @name Types + /// @{ + public: + typedef std::vector StrTab; + + /// This structure holds information for one member in the archive. It is + /// used temporarily while the contents of the archive are being + /// determined. + struct MemberInfo { + MemberInfo() {} + sys::Path path; + std::string name; + sys::Path::StatusInfo status; + StrTab symbols; + unsigned offset; + }; + + /// @} + /// @name Methods + /// @{ + public: + /// @brief Add a file member to the archive. + void addFileMember( + const sys::Path& path, ///< The path to the file to be added + const std::string& name, ///< The name for the member + const StrTab* syms = 0 ///< The symbol table of the member + ); + + /// @brief Write the accumulated archive information to an archive file + void writeArchive(); + void writeMember(const MemberInfo& member,std::ofstream& ARFile); + void writeSymbolTable(std::ofstream& ARFile); + void writeInteger(int num, std::ofstream& ARFile); + + /// @} + /// @name Data + /// @{ + private: + friend class Archive; ///< Parent class is a friend + sys::Path fname; ///< Path to the archive file + std::vector members; ///< Info about member files + Archive::SymTab* symtab; ///< User's symbol table + + /// @} + }; +} + +#endif + +// vim: sw=2 ai -- cgit v1.1