1 //===-- PathMappingList.cpp -------------------------------------*- 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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 #include "lldb/Core/Error.h"
14 #include "lldb/Core/Stream.h"
15 // Project includes
16 #include "lldb/Target/PathMappingList.h"
17 #include <string.h>
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 //----------------------------------------------------------------------
23 // PathMappingList constructor
24 //----------------------------------------------------------------------
25 PathMappingList::PathMappingList
26 (
27     ChangedCallback callback,
28     void *callback_baton
29 ) :
30     m_pairs (),
31     m_callback (callback),
32     m_callback_baton (callback_baton)
33 {
34 }
35 
36 
37 PathMappingList::PathMappingList (const PathMappingList &rhs) :
38     m_pairs (rhs.m_pairs),
39     m_callback (NULL),
40     m_callback_baton (NULL)
41 {
42 
43 }
44 
45 const PathMappingList &
46 PathMappingList::operator =(const PathMappingList &rhs)
47 {
48     if (this != &rhs)
49     {
50         m_pairs = rhs.m_pairs;
51         m_callback = NULL;
52         m_callback_baton = NULL;
53     }
54     return *this;
55 }
56 
57 
58 //----------------------------------------------------------------------
59 // Destructor
60 //----------------------------------------------------------------------
61 PathMappingList::~PathMappingList ()
62 {
63 }
64 
65 void
66 PathMappingList::Append (const ConstString &path,
67                          const ConstString &replacement,
68                          bool notify)
69 {
70     m_pairs.push_back(pair(path, replacement));
71     if (notify && m_callback)
72         m_callback (*this, m_callback_baton);
73 }
74 
75 void
76 PathMappingList::Insert (const ConstString &path,
77                          const ConstString &replacement,
78                          uint32_t index,
79                          bool notify)
80 {
81     iterator insert_iter;
82     if (index >= m_pairs.size())
83         insert_iter = m_pairs.end();
84     else
85         insert_iter = m_pairs.begin() + index;
86     m_pairs.insert(insert_iter, pair(path, replacement));
87     if (notify && m_callback)
88         m_callback (*this, m_callback_baton);
89 }
90 
91 bool
92 PathMappingList::Remove (off_t index, bool notify)
93 {
94     if (index >= m_pairs.size())
95         return false;
96 
97     iterator iter = m_pairs.begin() + index;
98     m_pairs.erase(iter);
99     if (notify && m_callback)
100         m_callback (*this, m_callback_baton);
101     return true;
102 }
103 
104 void
105 PathMappingList::Dump (Stream *s)
106 {
107     unsigned int numPairs = m_pairs.size();
108     unsigned int index;
109 
110     for (index = 0; index < numPairs; ++index)
111     {
112         s->Printf("[%d] \"%s\" -> \"%s\"\n",
113                   index, m_pairs[index].first.GetCString(), m_pairs[index].second.GetCString());
114     }
115 }
116 
117 void
118 PathMappingList::Clear (bool notify)
119 {
120     m_pairs.clear();
121     if (notify && m_callback)
122         m_callback (*this, m_callback_baton);
123 }
124 
125 size_t
126 PathMappingList::GetSize ()
127 {
128     return m_pairs.size();
129 }
130 
131 bool
132 PathMappingList::RemapPath (const ConstString &path, ConstString &new_path)
133 {
134     const_iterator pos, end = m_pairs.end();
135     for (pos = m_pairs.begin(); pos != end; ++pos)
136     {
137         const size_t prefixLen = pos->first.GetLength();
138 
139         if (::strncmp (pos->first.GetCString(), path.GetCString(), prefixLen) == 0)
140         {
141             std::string new_path_str (pos->second.GetCString());
142             new_path_str.append(path.GetCString() + prefixLen);
143             new_path.SetCString(new_path_str.c_str());
144             return true;
145         }
146     }
147     return false;
148 }
149 
150 bool
151 PathMappingList::Replace (const ConstString &path, const ConstString &new_path, bool notify)
152 {
153     uint32_t idx = FindIndexForPath (path);
154     if (idx < m_pairs.size())
155     {
156         m_pairs[idx].second = new_path;
157         if (notify && m_callback)
158             m_callback (*this, m_callback_baton);
159         return true;
160     }
161     return false;
162 }
163 
164 bool
165 PathMappingList::Remove (const ConstString &path, bool notify)
166 {
167     iterator pos = FindIteratorForPath (path);
168     if (pos != m_pairs.end())
169     {
170         m_pairs.erase (pos);
171         if (notify && m_callback)
172             m_callback (*this, m_callback_baton);
173         return true;
174     }
175     return false;
176 }
177 
178 PathMappingList::const_iterator
179 PathMappingList::FindIteratorForPath (const ConstString &path) const
180 {
181     const_iterator pos;
182     const_iterator begin = m_pairs.begin();
183     const_iterator end = m_pairs.end();
184 
185     for (pos = begin; pos != end; ++pos)
186     {
187         if (pos->first == path)
188             break;
189     }
190     return pos;
191 }
192 
193 PathMappingList::iterator
194 PathMappingList::FindIteratorForPath (const ConstString &path)
195 {
196     iterator pos;
197     iterator begin = m_pairs.begin();
198     iterator end = m_pairs.end();
199 
200     for (pos = begin; pos != end; ++pos)
201     {
202         if (pos->first == path)
203             break;
204     }
205     return pos;
206 }
207 
208 bool
209 PathMappingList::GetPathsAtIndex (uint32_t idx, ConstString &path, ConstString &new_path) const
210 {
211     if (idx < m_pairs.size())
212     {
213         path = m_pairs[idx].first;
214         new_path = m_pairs[idx].second;
215         return true;
216     }
217     return false;
218 }
219 
220 
221 
222 uint32_t
223 PathMappingList::FindIndexForPath (const ConstString &path) const
224 {
225     const_iterator pos;
226     const_iterator begin = m_pairs.begin();
227     const_iterator end = m_pairs.end();
228 
229     for (pos = begin; pos != end; ++pos)
230     {
231         if (pos->first == path)
232             return std::distance (begin, pos);
233     }
234     return UINT32_MAX;
235 }
236 
237