blob: dde83583c9a4d480616d427047303926afe9faf0 [file] [log] [blame]
Reid Spencer362cbf02004-11-06 08:51:45 +00001//===-- lib/Bytecode/ArchiveInternals.h -------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Reid Spencer and is distributed under the
6// University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Internal implementation header for LLVM Archive files.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LIB_BYTECODE_ARCHIVEINTERNALS_H
15#define LIB_BYTECODE_ARCHIVEINTERNALS_H
16
17#include "llvm/Bytecode/Archive.h"
18#include "llvm/System/TimeValue.h"
19
20#define ARFILE_MAGIC "!<arch>\n" ///< magic string
21#define ARFILE_MAGIC_LEN (sizeof(ARFILE_MAGIC)-1) ///< length of magic string
22#define ARFILE_SYMTAB_NAME "/" ///< name of symtab entry
23#define ARFILE_STRTAB_NAME "//" ///< name of strtab entry
24#define ARFILE_PAD '\n' ///< inter-file align padding
25
26namespace llvm {
27
28 /// The ArchiveMemberHeader structure is used internally for bytecode archives.
29 /// The header precedes each file member in the archive. This structure is
30 /// defined using character arrays for direct and correct interpretation
31 /// regardless of the endianess of the machine that produced it.
32 /// @brief Archive File Member Header
33 class ArchiveMemberHeader {
34 public:
35 void init() {
36 memset(name,' ',16);
37 memset(date,' ',12);
38 memset(uid,' ',6);
39 memset(gid,' ',6);
40 memset(mode,' ',8);
41 memset(size,' ',10);
42 fmag[0] = '`';
43 fmag[1] = '\n';
44 }
45 void setDate( int secondsSinceEpoch = 0 ) {
46 if (secondsSinceEpoch == 0) {
47 sys::TimeValue tv = sys::TimeValue::now();
48 uint64_t secs; uint32_t nanos;
49 tv.GetTimespecTime(secs,nanos);
50 secondsSinceEpoch = (int) secs;
51 }
52 char buffer[20];
53 sprintf(buffer,"%d", secondsSinceEpoch);
54 memcpy(date,buffer,strlen(buffer));
55 }
56
57 void setSize(size_t sz) {
58 char buffer[20];
59 sprintf(buffer, "%u", (unsigned)sz);
60 memcpy(size,buffer,strlen(buffer));
61 }
62
63 void setMode(int m) {
64 char buffer[20];
65 sprintf(buffer, "%o", m);
66 memcpy(mode,buffer,strlen(buffer));
67 }
68
69 void setUid(unsigned u) {
70 char buffer[20];
71 sprintf(buffer, "%u", u);
72 memcpy(uid,buffer,strlen(buffer));
73 }
74
75 void setGid(unsigned g) {
76 char buffer[20];
77 sprintf(buffer, "%u", g);
78 memcpy(gid,buffer,strlen(buffer));
79 }
80
81 bool setName(const std::string& nm) {
82 if (nm.length() > 0 && nm.length() <= 16) {
83 memcpy(name,nm.c_str(),nm.length());
84 for (int i = nm.length()+1; i < 16; i++ ) name[i] = ' ';
85 return true;
86 }
87 return false;
88 }
89
90 private:
91 char name[16]; ///< Name of the file member. The filename is terminated with '/'
92 ///< and blanks. The empty name (/ and 15 blanks) is for the
93 ///< symbol table. The special name "//" and 15 blanks is for
94 ///< the string table, used for long file names. It must be
95 ///< first in the archive.
96 char date[12]; ///< File date, decimal seconds since Epoch
97 char uid[6]; ///< user id in ASCII decimal
98 char gid[6]; ///< group id in ASCII decimal
99 char mode[8]; ///< file mode in ASCII octal
100 char size[10]; ///< file size in ASCII decimal
101 char fmag[2]; ///< Always contains ARFILE_MAGIC_TERMINATOR
102
103 };
104
105 /// The ArchiveInternals class is used to hold the content of the archive
106 /// while it is in memory. It also provides the bulk of the implementation for
107 /// the llvm:Archive class's interface.
108 class Archive::ArchiveInternals {
109 /// @name Types
110 /// @{
111 public:
112 typedef std::vector<std::string> StrTab;
113
114 /// This structure holds information for one member in the archive. It is
115 /// used temporarily while the contents of the archive are being
116 /// determined.
117 struct MemberInfo {
118 MemberInfo() {}
119 sys::Path path;
120 std::string name;
121 sys::Path::StatusInfo status;
122 StrTab symbols;
123 unsigned offset;
124 };
125
126 /// @}
127 /// @name Methods
128 /// @{
129 public:
130 /// @brief Add a file member to the archive.
131 void addFileMember(
132 const sys::Path& path, ///< The path to the file to be added
133 const std::string& name, ///< The name for the member
134 const StrTab* syms = 0 ///< The symbol table of the member
135 );
136
137 /// @brief Write the accumulated archive information to an archive file
138 void writeArchive();
139 void writeMember(const MemberInfo& member,std::ofstream& ARFile);
140 void writeSymbolTable(std::ofstream& ARFile);
141 void writeInteger(int num, std::ofstream& ARFile);
142
143 /// @}
144 /// @name Data
145 /// @{
146 private:
147 friend class Archive; ///< Parent class is a friend
148 sys::Path fname; ///< Path to the archive file
149 std::vector<MemberInfo> members; ///< Info about member files
150 Archive::SymTab* symtab; ///< User's symbol table
151
152 /// @}
153 };
154}
155
156#endif
157
158// vim: sw=2 ai