summaryrefslogtreecommitdiff
path: root/lib/Archive/ArchiveInternals.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Archive/ArchiveInternals.h')
-rw-r--r--lib/Archive/ArchiveInternals.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/lib/Archive/ArchiveInternals.h b/lib/Archive/ArchiveInternals.h
new file mode 100644
index 00000000000..dde83583c9a
--- /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 "!<arch>\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<std::string> 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<MemberInfo> members; ///< Info about member files
+ Archive::SymTab* symtab; ///< User's symbol table
+
+ /// @}
+ };
+}
+
+#endif
+
+// vim: sw=2 ai