1//===- Archive.h - ar archive file format -----------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file declares the ar archive file format class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_OBJECT_ARCHIVE_H
15#define LLVM_OBJECT_ARCHIVE_H
16
17#include "llvm/Object/Binary.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/DataTypes.h"
20
21namespace llvm {
22namespace object {
23
24class Archive : public Binary {
25  virtual void anchor();
26public:
27  class Child {
28    const Archive *Parent;
29    StringRef Data;
30
31  public:
32    Child(const Archive *p, StringRef d) : Parent(p), Data(d) {}
33
34    bool operator ==(const Child &other) const {
35      return (Parent == other.Parent) && (Data.begin() == other.Data.begin());
36    }
37
38    bool operator <(const Child &other) const {
39      return Data.begin() < other.Data.begin();
40    }
41
42    Child getNext() const;
43    error_code getName(StringRef &Result) const;
44    int getLastModified() const;
45    int getUID() const;
46    int getGID() const;
47    int getAccessMode() const;
48    ///! Return the size of the archive member without the header or padding.
49    uint64_t getSize() const;
50
51    MemoryBuffer *getBuffer() const;
52    error_code getAsBinary(OwningPtr<Binary> &Result) const;
53  };
54
55  class child_iterator {
56    Child child;
57  public:
58    child_iterator() : child(Child(0, StringRef())) {}
59    child_iterator(const Child &c) : child(c) {}
60    const Child* operator->() const {
61      return &child;
62    }
63
64    bool operator==(const child_iterator &other) const {
65      return child == other.child;
66    }
67
68    bool operator!=(const child_iterator &other) const {
69      return !(*this == other);
70    }
71
72    bool operator <(const child_iterator &other) const {
73      return child < other.child;
74    }
75
76    child_iterator& operator++() {  // Preincrement
77      child = child.getNext();
78      return *this;
79    }
80  };
81
82  class Symbol {
83    const Archive *Parent;
84    uint32_t SymbolIndex;
85    uint32_t StringIndex; // Extra index to the string.
86
87  public:
88    bool operator ==(const Symbol &other) const {
89      return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
90    }
91
92    Symbol(const Archive *p, uint32_t symi, uint32_t stri)
93      : Parent(p)
94      , SymbolIndex(symi)
95      , StringIndex(stri) {}
96    error_code getName(StringRef &Result) const;
97    error_code getMember(child_iterator &Result) const;
98    Symbol getNext() const;
99  };
100
101  class symbol_iterator {
102    Symbol symbol;
103  public:
104    symbol_iterator(const Symbol &s) : symbol(s) {}
105    const Symbol *operator->() const {
106      return &symbol;
107    }
108
109    bool operator==(const symbol_iterator &other) const {
110      return symbol == other.symbol;
111    }
112
113    bool operator!=(const symbol_iterator &other) const {
114      return !(*this == other);
115    }
116
117    symbol_iterator& operator++() {  // Preincrement
118      symbol = symbol.getNext();
119      return *this;
120    }
121  };
122
123  Archive(MemoryBuffer *source, error_code &ec);
124
125  child_iterator begin_children(bool skip_internal = true) const;
126  child_iterator end_children() const;
127
128  symbol_iterator begin_symbols() const;
129  symbol_iterator end_symbols() const;
130
131  // Cast methods.
132  static inline bool classof(Archive const *v) { return true; }
133  static inline bool classof(Binary const *v) {
134    return v->isArchive();
135  }
136
137private:
138  child_iterator SymbolTable;
139  child_iterator StringTable;
140};
141
142}
143}
144
145#endif
146