DataEncoder.h revision 4bc40781466dd9d2de0d51fec5feb342ea45e87f
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
19namespace 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//----------------------------------------------------------------------
32class DataEncoder
33{
34public:
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
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
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 *
137    GetDataEnd ()
138    {
139        return m_end;
140    }
141
142    const uint8_t *
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
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 *
183    GetDataStart ()
184    {
185        return m_start;
186    }
187
188    const uint8_t *
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 &
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
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
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
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
427    ValidOffsetForDataOfSize (uint32_t offset, uint32_t length) const
428    {
429        return length <= BytesLeft (offset);
430    }
431
432    uint32_t
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
441protected:
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
451private:
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