dde83583c9a4d480616d427047303926afe9faf0
[oota-llvm.git] / lib / Archive / ArchiveInternals.h
1 //===-- 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
26 namespace 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