1 //===-- SBData.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 #include "lldb/API/SBData.h"
11 #include "lldb/API/SBError.h"
12 #include "lldb/API/SBStream.h"
13 
14 #include "lldb/Core/DataExtractor.h"
15 #include "lldb/Core/Log.h"
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
20 SBData::SBData ()
21 {
22 }
23 
24 SBData::SBData (const lldb::DataExtractorSP& data_sp) :
25     m_opaque_sp (data_sp)
26 {
27 }
28 
29 SBData::SBData(const SBData &rhs) :
30     m_opaque_sp (rhs.m_opaque_sp)
31 {
32 }
33 
34 const SBData &
35 SBData::operator = (const SBData &rhs)
36 {
37     if (this != &rhs)
38         m_opaque_sp = rhs.m_opaque_sp;
39     return *this;
40 }
41 
42 SBData::~SBData ()
43 {
44 }
45 
46 void
47 SBData::SetOpaque (const lldb::DataExtractorSP &data_sp)
48 {
49     m_opaque_sp = data_sp;
50 }
51 
52 lldb_private::DataExtractor *
53 SBData::get() const
54 {
55     return m_opaque_sp.get();
56 }
57 
58 lldb_private::DataExtractor *
59 SBData::operator->() const
60 {
61     return m_opaque_sp.operator->();
62 }
63 
64 lldb::DataExtractorSP &
65 SBData::operator*()
66 {
67     return m_opaque_sp;
68 }
69 
70 const lldb::DataExtractorSP &
71 SBData::operator*() const
72 {
73     return m_opaque_sp;
74 }
75 
76 bool
77 SBData::IsValid()
78 {
79     return m_opaque_sp.get() != NULL;
80 }
81 
82 uint8_t
83 SBData::GetAddressByteSize ()
84 {
85     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
86     uint8_t value = 0;
87     if (m_opaque_sp.get())
88         value = m_opaque_sp->GetAddressByteSize();
89     if (log)
90         log->Printf ("SBData::GetAddressByteSize () => "
91                      "(%i)", value);
92     return value;
93 }
94 
95 void
96 SBData::Clear ()
97 {
98     if (m_opaque_sp.get())
99         m_opaque_sp->Clear();
100 }
101 
102 size_t
103 SBData::GetByteSize ()
104 {
105     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
106     size_t value = 0;
107     if (m_opaque_sp.get())
108         value = m_opaque_sp->GetByteSize();
109     if (log)
110         log->Printf ("SBData::GetByteSize () => "
111                      "(%lu)", value);
112     return value;
113 }
114 
115 lldb::ByteOrder
116 SBData::GetByteOrder ()
117 {
118     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
119     lldb::ByteOrder value = eByteOrderInvalid;
120     if (m_opaque_sp.get())
121         value = m_opaque_sp->GetByteOrder();
122     if (log)
123         log->Printf ("SBData::GetByteOrder () => "
124                      "(%i)", value);
125     return value;
126 }
127 
128 float
129 SBData::GetFloat (lldb::SBError& error, uint32_t offset)
130 {
131     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
132     float value = 0;
133     if (!m_opaque_sp.get())
134     {
135         error.SetErrorString("no value to read from");
136     }
137     else
138     {
139         uint32_t old_offset = offset;
140         value = m_opaque_sp->GetFloat(&offset);
141         if (offset == old_offset)
142             error.SetErrorString("unable to read data");
143     }
144     if (log)
145         log->Printf ("SBData::GetFloat (error=%p,offset=%d) => "
146                      "(%f)", error.get(), offset, value);
147     return value;
148 }
149 
150 double
151 SBData::GetDouble (lldb::SBError& error, uint32_t offset)
152 {
153     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
154     double value = 0;
155     if (!m_opaque_sp.get())
156     {
157         error.SetErrorString("no value to read from");
158     }
159     else
160     {
161         uint32_t old_offset = offset;
162         value = m_opaque_sp->GetDouble(&offset);
163         if (offset == old_offset)
164             error.SetErrorString("unable to read data");
165     }
166     if (log)
167         log->Printf ("SBData::GetDouble (error=%p,offset=%d) => "
168                      "(%f)", error.get(), offset, value);
169     return value;
170 }
171 
172 long double
173 SBData::GetLongDouble (lldb::SBError& error, uint32_t offset)
174 {
175     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
176     long double value = 0;
177     if (!m_opaque_sp.get())
178     {
179         error.SetErrorString("no value to read from");
180     }
181     else
182     {
183         uint32_t old_offset = offset;
184         value = m_opaque_sp->GetLongDouble(&offset);
185         if (offset == old_offset)
186             error.SetErrorString("unable to read data");
187     }
188     if (log)
189         log->Printf ("SBData::GetLongDouble (error=%p,offset=%d) => "
190                      "(%Lf)", error.get(), offset, value);
191     return value;
192 }
193 
194 lldb::addr_t
195 SBData::GetAddress (lldb::SBError& error, uint32_t offset)
196 {
197     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
198     lldb::addr_t value = 0;
199     if (!m_opaque_sp.get())
200     {
201         error.SetErrorString("no value to read from");
202     }
203     else
204     {
205         uint32_t old_offset = offset;
206         value = m_opaque_sp->GetAddress(&offset);
207         if (offset == old_offset)
208             error.SetErrorString("unable to read data");
209     }
210     if (log)
211         log->Printf ("SBData::GetAddress (error=%p,offset=%d) => "
212                      "(%p)", error.get(), offset, (void*)value);
213     return value;
214 }
215 
216 uint8_t
217 SBData::GetUnsignedInt8 (lldb::SBError& error, uint32_t offset)
218 {
219     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
220     uint8_t value = 0;
221     if (!m_opaque_sp.get())
222     {
223         error.SetErrorString("no value to read from");
224     }
225     else
226     {
227         uint32_t old_offset = offset;
228         value = m_opaque_sp->GetU8(&offset);
229         if (offset == old_offset)
230             error.SetErrorString("unable to read data");
231     }
232     if (log)
233         log->Printf ("SBData::GetUnsignedInt8 (error=%p,offset=%d) => "
234                      "(%c)", error.get(), offset, value);
235     return value;
236 }
237 
238 uint16_t
239 SBData::GetUnsignedInt16 (lldb::SBError& error, uint32_t offset)
240 {
241     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
242     uint16_t value = 0;
243     if (!m_opaque_sp.get())
244     {
245         error.SetErrorString("no value to read from");
246     }
247     else
248     {
249         uint32_t old_offset = offset;
250         value = m_opaque_sp->GetU16(&offset);
251         if (offset == old_offset)
252             error.SetErrorString("unable to read data");
253     }
254     if (log)
255         log->Printf ("SBData::GetUnsignedInt16 (error=%p,offset=%d) => "
256                      "(%hd)", error.get(), offset, value);
257     return value;
258 }
259 
260 uint32_t
261 SBData::GetUnsignedInt32 (lldb::SBError& error, uint32_t offset)
262 {
263     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
264     uint32_t value = 0;
265     if (!m_opaque_sp.get())
266     {
267         error.SetErrorString("no value to read from");
268     }
269     else
270     {
271         uint32_t old_offset = offset;
272         value = m_opaque_sp->GetU32(&offset);
273         if (offset == old_offset)
274             error.SetErrorString("unable to read data");
275     }
276     if (log)
277         log->Printf ("SBData::GetUnsignedInt32 (error=%p,offset=%d) => "
278                      "(%d)", error.get(), offset, value);
279     return value;
280 }
281 
282 uint64_t
283 SBData::GetUnsignedInt64 (lldb::SBError& error, uint32_t offset)
284 {
285     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
286     uint64_t value = 0;
287     if (!m_opaque_sp.get())
288     {
289         error.SetErrorString("no value to read from");
290     }
291     else
292     {
293         uint32_t old_offset = offset;
294         value = m_opaque_sp->GetU64(&offset);
295         if (offset == old_offset)
296             error.SetErrorString("unable to read data");
297     }
298     if (log)
299         log->Printf ("SBData::GetUnsignedInt64 (error=%p,offset=%d) => "
300                      "(%lld)", error.get(), offset, value);
301     return value;
302 }
303 
304 int8_t
305 SBData::GetSignedInt8 (lldb::SBError& error, uint32_t offset)
306 {
307     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
308     int8_t value = 0;
309     if (!m_opaque_sp.get())
310     {
311         error.SetErrorString("no value to read from");
312     }
313     else
314     {
315         uint32_t old_offset = offset;
316         value = (int8_t)m_opaque_sp->GetMaxS64(&offset, 1);
317         if (offset == old_offset)
318             error.SetErrorString("unable to read data");
319     }
320     if (log)
321         log->Printf ("SBData::GetSignedInt8 (error=%p,offset=%d) => "
322                      "(%c)", error.get(), offset, value);
323     return value;
324 }
325 
326 int16_t
327 SBData::GetSignedInt16 (lldb::SBError& error, uint32_t offset)
328 {
329     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
330     int16_t value = 0;
331     if (!m_opaque_sp.get())
332     {
333         error.SetErrorString("no value to read from");
334     }
335     else
336     {
337         uint32_t old_offset = offset;
338         value = (int16_t)m_opaque_sp->GetMaxS64(&offset, 2);
339         if (offset == old_offset)
340             error.SetErrorString("unable to read data");
341     }
342     if (log)
343         log->Printf ("SBData::GetSignedInt16 (error=%p,offset=%d) => "
344                      "(%hd)", error.get(), offset, value);
345     return value;
346 }
347 
348 int32_t
349 SBData::GetSignedInt32 (lldb::SBError& error, uint32_t offset)
350 {
351     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
352     int32_t value = 0;
353     if (!m_opaque_sp.get())
354     {
355         error.SetErrorString("no value to read from");
356     }
357     else
358     {
359         uint32_t old_offset = offset;
360         value = (int32_t)m_opaque_sp->GetMaxS64(&offset, 4);
361         if (offset == old_offset)
362             error.SetErrorString("unable to read data");
363     }
364     if (log)
365         log->Printf ("SBData::GetSignedInt32 (error=%p,offset=%d) => "
366                      "(%d)", error.get(), offset, value);
367     return value;
368 }
369 
370 int64_t
371 SBData::GetSignedInt64 (lldb::SBError& error, uint32_t offset)
372 {
373     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
374     int64_t value = 0;
375     if (!m_opaque_sp.get())
376     {
377         error.SetErrorString("no value to read from");
378     }
379     else
380     {
381         uint32_t old_offset = offset;
382         value = (int64_t)m_opaque_sp->GetMaxS64(&offset, 8);
383         if (offset == old_offset)
384             error.SetErrorString("unable to read data");
385     }
386     if (log)
387         log->Printf ("SBData::GetSignedInt64 (error=%p,offset=%d) => "
388                      "(%lld)", error.get(), offset, value);
389     return value;
390 }
391 
392 const char*
393 SBData::GetString (lldb::SBError& error, uint32_t offset)
394 {
395     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
396     const char* value = 0;
397     if (!m_opaque_sp.get())
398     {
399         error.SetErrorString("no value to read from");
400     }
401     else
402     {
403         uint32_t old_offset = offset;
404         value = m_opaque_sp->GetCStr(&offset);
405         if (offset == old_offset || (value == NULL))
406             error.SetErrorString("unable to read data");
407     }
408     if (log)
409         log->Printf ("SBData::GetString (error=%p,offset=%d) => "
410                      "(%p)", error.get(), offset, value);
411     return value;
412 }
413 
414 bool
415 SBData::GetDescription (lldb::SBStream &description, lldb::addr_t base_addr)
416 {
417     if (m_opaque_sp)
418     {
419         description.ref();
420         m_opaque_sp->Dump(description.get(),
421                           0,
422                           lldb::eFormatBytesWithASCII,
423                           1,
424                           m_opaque_sp->GetByteSize(),
425                           16,
426                           base_addr,
427                           0,
428                           0);
429     }
430     else
431         description.Printf ("No Value");
432 
433     return true;
434 }
435 
436 size_t
437 SBData::ReadRawData (lldb::SBError& error,
438                      uint32_t offset,
439                      void *buf,
440                      size_t size)
441 {
442     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
443     void* ok = NULL;
444     if (!m_opaque_sp.get())
445     {
446         error.SetErrorString("no value to read from");
447     }
448     else
449     {
450         uint32_t old_offset = offset;
451         ok = m_opaque_sp->GetU8(&offset, buf, size);
452         if ((offset == old_offset) || (ok == NULL))
453             error.SetErrorString("unable to read data");
454     }
455     if (log)
456         log->Printf ("SBData::ReadRawData (error=%p,offset=%d,buf=%p,size=%lu) => "
457                      "(%p)", error.get(), offset, buf, size, ok);
458     return ok ? size : 0;
459 }
460 
461 void
462 SBData::SetData(lldb::SBError& error,
463                 const void *buf,
464                 size_t size,
465                 lldb::ByteOrder endian,
466                 uint8_t addr_size)
467 {
468     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
469     if (!m_opaque_sp.get())
470         m_opaque_sp.reset(new DataExtractor(buf, size, endian, addr_size));
471     else
472         m_opaque_sp->SetData(buf, size, endian);
473     if (log)
474         log->Printf ("SBData::SetData (error=%p,buf=%p,size=%lu,endian=%d,addr_size=%c) => "
475                      "(%p)", error.get(), buf, size, endian, addr_size, m_opaque_sp.get());
476 }
477 
478 bool
479 SBData::Append(const SBData& rhs)
480 {
481     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
482     bool value = false;
483     if (m_opaque_sp.get() && rhs.m_opaque_sp.get())
484         value = m_opaque_sp.get()->Append(*rhs.m_opaque_sp);
485     if (log)
486         log->Printf ("SBData::Append (rhs=%p) => "
487                      "(%s)", rhs.get(), value ? "true" : "false");
488     return value;
489 }
490