1 //===-- DataEncoder.h -------------------------------------------*- 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 #ifndef liblldb_DataEncoder_h_
11 #define liblldb_DataEncoder_h_
12 
13 #if defined (__cplusplus)
14 
15 #include "lldb/lldb-private.h"
16 #include <limits.h>
17 #include <stdint.h>
18 
19 namespace lldb_private {
20 
21 //----------------------------------------------------------------------
22 /// @class DataEncoder DataEncoder.h "lldb/Core/DataEncoder.h"
23 /// @brief An binary data encoding class.
24 ///
25 /// DataEncoder is a class that can encode binary data (swapping if needed)
26 /// to a data buffer. The data buffer can be caller owned, or can be
27 /// shared data that can be shared between multiple DataEncoder or
28 /// DataEncoder instances.
29 ///
30 /// @see DataBuffer
31 //----------------------------------------------------------------------
32 class DataEncoder
33 {
34 public:
35     //------------------------------------------------------------------
36     /// Default constructor.
37     ///
38     /// Initialize all members to a default empty state.
39     //------------------------------------------------------------------
40     DataEncoder ();
41 
42     //------------------------------------------------------------------
43     /// Construct with a buffer that is owned by the caller.
44     ///
45     /// This constructor allows us to use data that is owned by the
46     /// caller. The data must stay around as long as this object is
47     /// valid.
48     ///
49     /// @param[in] data
50     ///     A pointer to caller owned data.
51     ///
52     /// @param[in] data_length
53     ///     The length in bytes of \a data.
54     ///
55     /// @param[in] byte_order
56     ///     A byte order of the data that we are extracting from.
57     ///
58     /// @param[in] addr_size
59     ///     A new address byte size value.
60     //------------------------------------------------------------------
61     DataEncoder (void* data, uint32_t data_length, lldb::ByteOrder byte_order, uint8_t addr_size);
62 
63     //------------------------------------------------------------------
64     /// Construct with shared data.
65     ///
66     /// Copies the data shared pointer which adds a reference to the
67     /// contained in \a data_sp. The shared data reference is reference
68     /// counted to ensure the data lives as long as anyone still has a
69     /// valid shared pointer to the data in \a data_sp.
70     ///
71     /// @param[in] data_sp
72     ///     A shared pointer to data.
73     ///
74     /// @param[in] byte_order
75     ///     A byte order of the data that we are extracting from.
76     ///
77     /// @param[in] addr_size
78     ///     A new address byte size value.
79     //------------------------------------------------------------------
80     DataEncoder (const lldb::DataBufferSP& data_sp, lldb::ByteOrder byte_order, uint8_t addr_size);
81 
82     //------------------------------------------------------------------
83     /// Destructor
84     ///
85     /// If this object contains a valid shared data reference, the
86     /// reference count on the data will be decremented, and if zero,
87     /// the data will be freed.
88     //------------------------------------------------------------------
89     ~DataEncoder ();
90 
91     //------------------------------------------------------------------
92     /// Clears the object state.
93     ///
94     /// Clears the object contents back to a default invalid state, and
95     /// release any references to shared data that this object may
96     /// contain.
97     //------------------------------------------------------------------
98     void
99     Clear ();
100 
101     //------------------------------------------------------------------
102     /// Get the current address size.
103     ///
104     /// Return the size in bytes of any address values this object will
105     /// extract.
106     ///
107     /// @return
108     ///     The size in bytes of address values that will be extracted.
109     //------------------------------------------------------------------
110     uint8_t
GetAddressByteSize()111     GetAddressByteSize () const
112     {
113         return m_addr_size;
114     }
115 
116 
117     //------------------------------------------------------------------
118     /// Get the number of bytes contained in this object.
119     ///
120     /// @return
121     ///     The total number of bytes of data this object refers to.
122     //------------------------------------------------------------------
123     size_t
GetByteSize()124     GetByteSize () const
125     {
126         return m_end - m_start;
127     }
128 
129     //------------------------------------------------------------------
130     /// Get the data end pointer.
131     ///
132     /// @return
133     ///     Returns a pointer to the next byte contained in this
134     ///     object's data, or NULL of there is no data in this object.
135     //------------------------------------------------------------------
136     uint8_t *
GetDataEnd()137     GetDataEnd ()
138     {
139         return m_end;
140     }
141 
142     const uint8_t *
GetDataEnd()143     GetDataEnd () const
144     {
145         return m_end;
146     }
147 
148     //------------------------------------------------------------------
149     /// Get the shared data offset.
150     ///
151     /// Get the offset of the first byte of data in the shared data (if
152     /// any).
153     ///
154     /// @return
155     ///     If this object contains shared data, this function returns
156     ///     the offset in bytes into that shared data, zero otherwise.
157     //------------------------------------------------------------------
158     size_t
159     GetSharedDataOffset () const;
160 
161 
162     //------------------------------------------------------------------
163     /// Get the current byte order value.
164     ///
165     /// @return
166     ///     The current byte order value from this object's internal
167     ///     state.
168     //------------------------------------------------------------------
169     lldb::ByteOrder
GetByteOrder()170     GetByteOrder() const
171     {
172         return m_byte_order;
173     }
174 
175     //------------------------------------------------------------------
176     /// Get a the data start pointer.
177     ///
178     /// @return
179     ///     Returns a pointer to the first byte contained in this
180     ///     object's data, or NULL of there is no data in this object.
181     //------------------------------------------------------------------
182     uint8_t *
GetDataStart()183     GetDataStart ()
184     {
185         return m_start;
186     }
187 
188     const uint8_t *
GetDataStart()189     GetDataStart () const
190     {
191         return m_start;
192     }
193 
194     //------------------------------------------------------------------
195     /// Encode unsigned integer values into the data at \a offset.
196     ///
197     /// @param[in] offset
198     ///     The offset within the contained data at which to put the
199     ///     data.
200     ///
201     /// @param[in] value
202     ///     The value to encode into the data.
203     ///
204     /// @return
205     ///     The next offset in the bytes of this data if the data
206     ///     was successfully encoded, UINT32_MAX if the encoding failed.
207     //------------------------------------------------------------------
208     uint32_t
209     PutU8 (uint32_t offset, uint8_t value);
210 
211     uint32_t
212     PutU16 (uint32_t offset, uint16_t value);
213 
214     uint32_t
215     PutU32 (uint32_t offset, uint32_t value);
216 
217     uint32_t
218     PutU64 (uint32_t offset, uint64_t value);
219 
220     //------------------------------------------------------------------
221     /// Encode an unsigned integer of size \a byte_size to \a offset.
222     ///
223     /// Encode a single integer value at \a offset and return the offset
224     /// that follows the newly encoded integer when the data is successfully
225     /// encoded into the existing data. There must be enough room in the
226     /// data, else UINT32_MAX will be returned to indicate that encoding
227     /// failed.
228     ///
229     /// @param[in] offset
230     ///     The offset within the contained data at which to put the
231     ///     encoded integer.
232     ///
233     /// @param[in] byte_size
234     ///     The size in byte of the integer to encode.
235     ///
236     /// @param[in] value
237     ///     The integer value to write. The least significate bytes of
238     ///     the integer value will be written if the size is less than
239     ///     8 bytes.
240     ///
241     /// @return
242     ///     The next offset in the bytes of this data if the integer
243     ///     was successfully encoded, UINT32_MAX if the encoding failed.
244     //------------------------------------------------------------------
245     uint32_t
246     PutMaxU64 (uint32_t offset, uint32_t byte_size, uint64_t value);
247 
248     //------------------------------------------------------------------
249     /// Encode an arbitrary number of bytes.
250     ///
251     /// @param[in] offset
252     ///     The offset in bytes into the contained data at which to
253     ///     start encoding.
254     ///
255     /// @param[int] src
256     ///     The buffer that contains the the bytes to encode.
257     ///
258     /// @param[in] src_len
259     ///     The number of bytes to encode.
260     ///
261     /// @return
262     ///     The next valid offset within data if the put operation
263     ///     was successful, else UINT32_MAX to indicate the put failed.
264     //------------------------------------------------------------------
265     uint32_t
266     PutData (uint32_t offset,
267              const void *src,
268              uint32_t src_len);
269 
270     //------------------------------------------------------------------
271     /// Encode an address in the existing buffer at \a offset bytes into
272     /// the buffer.
273     ///
274     /// Encode a single address (honoring the m_addr_size member) to
275     /// the data and return the next offset where subsequent data would
276     /// go.
277     /// pointed to by \a offset_ptr. The size of the extracted address
278     /// comes from the \a m_addr_size member variable and should be
279     /// set correctly prior to extracting any address values.
280     ///
281     /// @param[in,out] offset_ptr
282     ///     A pointer to an offset within the data that will be advanced
283     ///     by the appropriate number of bytes if the value is extracted
284     ///     correctly. If the offset is out of bounds or there are not
285     ///     enough bytes to extract this value, the offset will be left
286     ///     unmodified.
287     ///
288     /// @return
289     ///     The next valid offset within data if the put operation
290     ///     was successful, else UINT32_MAX to indicate the put failed.
291     //------------------------------------------------------------------
292     uint32_t
293     PutAddress (uint32_t offset, lldb::addr_t addr);
294 
295     //------------------------------------------------------------------
296     /// Put a C string to \a offset.
297     ///
298     /// Encodes a C string into the existing data including the
299     /// terminating
300     ///
301     /// @param[in,out] offset_ptr
302     ///     A pointer to an offset within the data that will be advanced
303     ///     by the appropriate number of bytes if the value is extracted
304     ///     correctly. If the offset is out of bounds or there are not
305     ///     enough bytes to extract this value, the offset will be left
306     ///     unmodified.
307     ///
308     /// @return
309     ///     A pointer to the C string value in the data. If the offset
310     ///     pointed to by \a offset_ptr is out of bounds, or if the
311     ///     offset plus the length of the C string is out of bounds,
312     ///     NULL will be returned.
313     //------------------------------------------------------------------
314     uint32_t
315     PutCString (uint32_t offset_ptr, const char *cstr);
316 
317     lldb::DataBufferSP &
GetSharedDataBuffer()318     GetSharedDataBuffer ()
319     {
320         return m_data_sp;
321     }
322 
323     //------------------------------------------------------------------
324     /// Set the address byte size.
325     ///
326     /// Set the size in bytes that will be used when extracting any
327     /// address and pointer values from data contained in this object.
328     ///
329     /// @param[in] addr_size
330     ///     The size in bytes to use when extracting addresses.
331     //------------------------------------------------------------------
332     void
SetAddressByteSize(uint8_t addr_size)333     SetAddressByteSize (uint8_t addr_size)
334     {
335         m_addr_size = addr_size;
336     }
337 
338     //------------------------------------------------------------------
339     /// Set data with a buffer that is caller owned.
340     ///
341     /// Use data that is owned by the caller when extracting values.
342     /// The data must stay around as long as this object, or any object
343     /// that copies a subset of this object's data, is valid. If \a
344     /// bytes is NULL, or \a length is zero, this object will contain
345     /// no data.
346     ///
347     /// @param[in] bytes
348     ///     A pointer to caller owned data.
349     ///
350     /// @param[in] length
351     ///     The length in bytes of \a bytes.
352     ///
353     /// @param[in] byte_order
354     ///     A byte order of the data that we are extracting from.
355     ///
356     /// @return
357     ///     The number of bytes that this object now contains.
358     //------------------------------------------------------------------
359     uint32_t
360     SetData (const void *bytes, uint32_t length, lldb::ByteOrder byte_order);
361 
362     //------------------------------------------------------------------
363     /// Adopt a subset of shared data in \a data_sp.
364     ///
365     /// Copies the data shared pointer which adds a reference to the
366     /// contained in \a data_sp. The shared data reference is reference
367     /// counted to ensure the data lives as long as anyone still has a
368     /// valid shared pointer to the data in \a data_sp. The byte order
369     /// and address byte size settings remain the same. If
370     /// \a offset is not a valid offset in \a data_sp, then no reference
371     /// to the shared data will be added. If there are not \a length
372     /// bytes available in \a data starting at \a offset, the length
373     /// will be truncated to contains as many bytes as possible.
374     ///
375     /// @param[in] data_sp
376     ///     A shared pointer to data.
377     ///
378     /// @param[in] offset
379     ///     The offset into \a data_sp at which the subset starts.
380     ///
381     /// @param[in] length
382     ///     The length in bytes of the subset of \a data_sp.
383     ///
384     /// @return
385     ///     The number of bytes that this object now contains.
386     //------------------------------------------------------------------
387     uint32_t
388     SetData (const lldb::DataBufferSP& data_sp, uint32_t offset = 0, uint32_t length = UINT32_MAX);
389 
390     //------------------------------------------------------------------
391     /// Set the byte_order value.
392     ///
393     /// Sets the byte order of the data to extract. Extracted values
394     /// will be swapped if necessary when decoding.
395     ///
396     /// @param[in] byte_order
397     ///     The byte order value to use when extracting data.
398     //------------------------------------------------------------------
399     void
SetByteOrder(lldb::ByteOrder byte_order)400     SetByteOrder (lldb::ByteOrder byte_order)
401     {
402         m_byte_order = byte_order;
403     }
404 
405 
406     //------------------------------------------------------------------
407     /// Test the validity of \a offset.
408     ///
409     /// @return
410     ///     \b true if \a offset is a valid offset into the data in this
411     ///     object, \b false otherwise.
412     //------------------------------------------------------------------
413     bool
ValidOffset(uint32_t offset)414     ValidOffset (uint32_t offset) const
415     {
416         return offset < GetByteSize();
417     }
418 
419     //------------------------------------------------------------------
420     /// Test the availability of \a length bytes of data from \a offset.
421     ///
422     /// @return
423     ///     \b true if \a offset is a valid offset and there are \a
424     ///     length bytes available at that offset, \b false otherwise.
425     //------------------------------------------------------------------
426     bool
ValidOffsetForDataOfSize(uint32_t offset,uint32_t length)427     ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const
428     {
429         return length <= BytesLeft (offset);
430     }
431 
432     uint32_t
BytesLeft(uint32_t offset)433     BytesLeft (uint32_t offset) const
434     {
435         const uint32_t size = GetByteSize();
436         if (size > offset)
437             return size - offset;
438         return 0;
439     }
440 
441 protected:
442     //------------------------------------------------------------------
443     // Member variables
444     //------------------------------------------------------------------
445     uint8_t *m_start;   ///< A pointer to the first byte of data.
446     uint8_t *m_end;     ///< A pointer to the byte that is past the end of the data.
447     lldb::ByteOrder m_byte_order;   ///< The byte order of the data we are extracting from.
448     uint8_t m_addr_size;            ///< The address size to use when extracting pointers or addresses
449     mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can be shared among multilple instances
450 
451 private:
452     DISALLOW_COPY_AND_ASSIGN (DataEncoder);
453 
454 };
455 
456 } // namespace lldb_private
457 
458 #endif  // #if defined (__cplusplus)
459 #endif  // #ifndef liblldb_DataEncoder_h_
460