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