LLVM 23.0.0git
DataExtractor.h
Go to the documentation of this file.
1//===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
10#define LLVM_SUPPORT_DATAEXTRACTOR_H
11
12#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/Error.h"
16
17namespace llvm {
18
19/// An auxiliary type to facilitate extraction of 3-byte entities.
20struct Uint24 {
22 Uint24(uint8_t U) : Bytes{U, U, U} {}
23 Uint24(uint8_t U0, uint8_t U1, uint8_t U2) : Bytes{U0, U1, U2} {}
24 uint32_t getAsUint32(bool IsLittleEndian) const {
25 int LoIx = IsLittleEndian ? 0 : 2;
26 return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16);
27 }
28};
29
31static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3");
32
33/// Needed by swapByteOrder().
35 return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]);
36}
37
39 StringRef Data;
40 uint8_t IsLittleEndian;
41
42public:
43 /// A class representing a position in a DataExtractor, as well as any error
44 /// encountered during extraction. It enables one to extract a sequence of
45 /// values without error-checking and then checking for errors in bulk at the
46 /// end. The class holds an Error object, so failing to check the result of
47 /// the parse will result in a runtime error. The error flag is sticky and
48 /// will cause all subsequent extraction functions to fail without even
49 /// attempting to parse and without updating the Cursor offset. After clearing
50 /// the error flag, one can again use the Cursor object for parsing.
51 class Cursor {
52 uint64_t Offset;
53 Error Err;
54
55 friend class DataExtractor;
56
57 public:
58 /// Construct a cursor for extraction from the given offset.
59 explicit Cursor(uint64_t Offset) : Offset(Offset), Err(Error::success()) {}
60
61 /// Checks whether the cursor is valid (i.e. no errors were encountered). In
62 /// case of errors, this does not clear the error flag -- one must call
63 /// takeError() instead.
64 explicit operator bool() { return !Err; }
65
66 /// Return the current position of this Cursor. In the error state this is
67 /// the position of the Cursor before the first error was encountered.
68 uint64_t tell() const { return Offset; }
69
70 /// Set the cursor to the new offset. This does not impact the error state.
71 void seek(uint64_t NewOffSet) { Offset = NewOffSet; }
72
73 /// Return error contained inside this Cursor, if any. Clears the internal
74 /// Cursor state.
75 Error takeError() { return std::move(Err); }
76 };
77
78 /// Construct with a buffer that is owned by the caller.
79 ///
80 /// This constructor allows us to use data that is owned by the
81 /// caller. The data must stay around as long as this object is
82 /// valid.
83 DataExtractor(StringRef Data, bool IsLittleEndian)
84 : Data(Data), IsLittleEndian(IsLittleEndian) {}
85
86 DataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian)
87 : Data(StringRef(reinterpret_cast<const char *>(Data.data()),
88 Data.size())),
89 IsLittleEndian(IsLittleEndian) {}
90
91 /// Get the data pointed to by this extractor.
92 StringRef getData() const { return Data; }
93 /// Get the endianness for this extractor.
94 bool isLittleEndian() const { return IsLittleEndian; }
95
96 /// Extract a C string from \a *offset_ptr.
97 ///
98 /// Returns a pointer to a C String from the data at the offset
99 /// pointed to by \a offset_ptr. A variable length NULL terminated C
100 /// string will be extracted and the \a offset_ptr will be
101 /// updated with the offset of the byte that follows the NULL
102 /// terminator byte.
103 ///
104 /// @param[in,out] OffsetPtr
105 /// A pointer to an offset within the data that will be advanced
106 /// by the appropriate number of bytes if the value is extracted
107 /// correctly. If the offset is out of bounds or there are not
108 /// enough bytes to extract this value, the offset will be left
109 /// unmodified.
110 ///
111 /// @param[in,out] Err
112 /// A pointer to an Error object. Upon return the Error object is set to
113 /// indicate the result (success/failure) of the function. If the Error
114 /// object is already set when calling this function, no extraction is
115 /// performed.
116 ///
117 /// @return
118 /// A pointer to the C string value in the data. If the offset
119 /// pointed to by \a offset_ptr is out of bounds, or if the
120 /// offset plus the length of the C string is out of bounds,
121 /// NULL will be returned.
122 const char *getCStr(uint64_t *OffsetPtr, Error *Err = nullptr) const {
123 return getCStrRef(OffsetPtr, Err).data();
124 }
125
126 /// Extract a C string from the location given by the cursor. In case of an
127 /// extraction error, or if the cursor is already in an error state, a
128 /// nullptr is returned.
129 const char *getCStr(Cursor &C) const { return getCStrRef(C).data(); }
130
131 /// Extract a C string from \a *offset_ptr.
132 ///
133 /// Returns a StringRef for the C String from the data at the offset
134 /// pointed to by \a offset_ptr. A variable length NULL terminated C
135 /// string will be extracted and the \a offset_ptr will be
136 /// updated with the offset of the byte that follows the NULL
137 /// terminator byte.
138 ///
139 /// \param[in,out] OffsetPtr
140 /// A pointer to an offset within the data that will be advanced
141 /// by the appropriate number of bytes if the value is extracted
142 /// correctly. If the offset is out of bounds or there are not
143 /// enough bytes to extract this value, the offset will be left
144 /// unmodified.
145 ///
146 /// @param[in,out] Err
147 /// A pointer to an Error object. Upon return the Error object is set to
148 /// indicate the result (success/failure) of the function. If the Error
149 /// object is already set when calling this function, no extraction is
150 /// performed.
151 ///
152 /// \return
153 /// A StringRef for the C string value in the data. If the offset
154 /// pointed to by \a offset_ptr is out of bounds, or if the
155 /// offset plus the length of the C string is out of bounds,
156 /// a default-initialized StringRef will be returned.
158 Error *Err = nullptr) const;
159
160 /// Extract a C string (as a StringRef) from the location given by the cursor.
161 /// In case of an extraction error, or if the cursor is already in an error
162 /// state, a default-initialized StringRef is returned.
164 return getCStrRef(&C.Offset, &C.Err);
165 }
166
167 /// Extract a fixed length string from \a *OffsetPtr and consume \a Length
168 /// bytes.
169 ///
170 /// Returns a StringRef for the string from the data at the offset
171 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
172 /// and the \a OffsetPtr will be advanced by \a Length bytes.
173 ///
174 /// \param[in,out] OffsetPtr
175 /// A pointer to an offset within the data that will be advanced
176 /// by the appropriate number of bytes if the value is extracted
177 /// correctly. If the offset is out of bounds or there are not
178 /// enough bytes to extract this value, the offset will be left
179 /// unmodified.
180 ///
181 /// \param[in] Length
182 /// The length of the fixed length string to extract. If there are not
183 /// enough bytes in the data to extract the full string, the offset will
184 /// be left unmodified.
185 ///
186 /// \param[in] TrimChars
187 /// A set of characters to trim from the end of the string. Fixed length
188 /// strings are commonly either NULL terminated by one or more zero
189 /// bytes. Some clients have one or more spaces at the end of the string,
190 /// but a good default is to trim the NULL characters.
191 ///
192 /// \return
193 /// A StringRef for the C string value in the data. If the offset
194 /// pointed to by \a OffsetPtr is out of bounds, or if the
195 /// offset plus the length of the C string is out of bounds,
196 /// a default-initialized StringRef will be returned.
198 StringRef TrimChars = {"\0",
199 1}) const;
200
201 /// Extract a fixed number of bytes from the specified offset.
202 ///
203 /// Returns a StringRef for the bytes from the data at the offset
204 /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
205 /// and the \a OffsetPtr will be advanced by \a Length bytes.
206 ///
207 /// \param[in,out] OffsetPtr
208 /// A pointer to an offset within the data that will be advanced
209 /// by the appropriate number of bytes if the value is extracted
210 /// correctly. If the offset is out of bounds or there are not
211 /// enough bytes to extract this value, the offset will be left
212 /// unmodified.
213 ///
214 /// \param[in] Length
215 /// The number of bytes to extract. If there are not enough bytes in the
216 /// data to extract all of the bytes, the offset will be left unmodified.
217 ///
218 /// @param[in,out] Err
219 /// A pointer to an Error object. Upon return the Error object is set to
220 /// indicate the result (success/failure) of the function. If the Error
221 /// object is already set when calling this function, no extraction is
222 /// performed.
223 ///
224 /// \return
225 /// A StringRef for the extracted bytes. If the offset pointed to by
226 /// \a OffsetPtr is out of bounds, or if the offset plus the length
227 /// is out of bounds, a default-initialized StringRef will be returned.
228 LLVM_ABI StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length,
229 Error *Err = nullptr) const;
230
231 /// Extract a fixed number of bytes from the location given by the cursor. In
232 /// case of an extraction error, or if the cursor is already in an error
233 /// state, a default-initialized StringRef is returned.
235 return getBytes(&C.Offset, Length, &C.Err);
236 }
237
238 /// Extract an unsigned integer of size \a byte_size from \a
239 /// *offset_ptr.
240 ///
241 /// Extract a single unsigned integer value and update the offset
242 /// pointed to by \a offset_ptr. The size of the extracted integer
243 /// is specified by the \a byte_size argument. \a byte_size should
244 /// have a value greater than or equal to one and less than or equal
245 /// to eight since the return value is 64 bits wide. Any
246 /// \a byte_size values less than 1 or greater than 8 will result in
247 /// nothing being extracted, and zero being returned.
248 ///
249 /// @param[in,out] offset_ptr
250 /// A pointer to an offset within the data that will be advanced
251 /// by the appropriate number of bytes if the value is extracted
252 /// correctly. If the offset is out of bounds or there are not
253 /// enough bytes to extract this value, the offset will be left
254 /// unmodified.
255 ///
256 /// @param[in] byte_size
257 /// The size in byte of the integer to extract.
258 ///
259 /// @param[in,out] Err
260 /// A pointer to an Error object. Upon return the Error object is set to
261 /// indicate the result (success/failure) of the function. If the Error
262 /// object is already set when calling this function, no extraction is
263 /// performed.
264 ///
265 /// @return
266 /// The unsigned integer value that was extracted, or zero on
267 /// failure.
268 LLVM_ABI uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size,
269 Error *Err = nullptr) const;
270
271 /// Extract an unsigned integer of the given size from the location given by
272 /// the cursor. In case of an extraction error, or if the cursor is already in
273 /// an error state, zero is returned.
275 return getUnsigned(&C.Offset, Size, &C.Err);
276 }
277
278 /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
279 ///
280 /// Extract a single signed integer value (sign extending if required)
281 /// and update the offset pointed to by \a offset_ptr. The size of
282 /// the extracted integer is specified by the \a byte_size argument.
283 /// \a byte_size should have a value greater than or equal to one
284 /// and less than or equal to eight since the return value is 64
285 /// bits wide. Any \a byte_size values less than 1 or greater than
286 /// 8 will result in nothing being extracted, and zero being returned.
287 ///
288 /// @param[in,out] offset_ptr
289 /// A pointer to an offset within the data that will be advanced
290 /// by the appropriate number of bytes if the value is extracted
291 /// correctly. If the offset is out of bounds or there are not
292 /// enough bytes to extract this value, the offset will be left
293 /// unmodified.
294 ///
295 /// @param[in] size
296 /// The size in bytes of the integer to extract.
297 ///
298 /// @return
299 /// The sign extended signed integer value that was extracted,
300 /// or zero on failure.
301 LLVM_ABI int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const;
302
303 /// Extract a uint8_t value from \a *offset_ptr.
304 ///
305 /// Extract a single uint8_t from the binary data at the offset
306 /// pointed to by \a offset_ptr, and advance the offset on success.
307 ///
308 /// @param[in,out] offset_ptr
309 /// A pointer to an offset within the data that will be advanced
310 /// by the appropriate number of bytes if the value is extracted
311 /// correctly. If the offset is out of bounds or there are not
312 /// enough bytes to extract this value, the offset will be left
313 /// unmodified.
314 ///
315 /// @param[in,out] Err
316 /// A pointer to an Error object. Upon return the Error object is set to
317 /// indicate the result (success/failure) of the function. If the Error
318 /// object is already set when calling this function, no extraction is
319 /// performed.
320 ///
321 /// @return
322 /// The extracted uint8_t value.
323 LLVM_ABI uint8_t getU8(uint64_t *offset_ptr, Error *Err = nullptr) const;
324
325 /// Extract a single uint8_t value from the location given by the cursor. In
326 /// case of an extraction error, or if the cursor is already in an error
327 /// state, zero is returned.
328 uint8_t getU8(Cursor &C) const { return getU8(&C.Offset, &C.Err); }
329
330 /// Extract \a count uint8_t values from \a *offset_ptr.
331 ///
332 /// Extract \a count uint8_t values from the binary data at the
333 /// offset pointed to by \a offset_ptr, and advance the offset on
334 /// success. The extracted values are copied into \a dst.
335 ///
336 /// @param[in,out] offset_ptr
337 /// A pointer to an offset within the data that will be advanced
338 /// by the appropriate number of bytes if the value is extracted
339 /// correctly. If the offset is out of bounds or there are not
340 /// enough bytes to extract this value, the offset will be left
341 /// unmodified.
342 ///
343 /// @param[out] dst
344 /// A buffer to copy \a count uint8_t values into. \a dst must
345 /// be large enough to hold all requested data.
346 ///
347 /// @param[in] count
348 /// The number of uint8_t values to extract.
349 ///
350 /// @return
351 /// \a dst if all values were properly extracted and copied,
352 /// NULL otherise.
353 LLVM_ABI uint8_t *getU8(uint64_t *offset_ptr, uint8_t *dst,
354 uint32_t count) const;
355
356 /// Extract \a Count uint8_t values from the location given by the cursor and
357 /// store them into the destination buffer. In case of an extraction error, or
358 /// if the cursor is already in an error state, a nullptr is returned and the
359 /// destination buffer is left unchanged.
360 LLVM_ABI uint8_t *getU8(Cursor &C, uint8_t *Dst, uint32_t Count) const;
361
362 /// Extract \a Count uint8_t values from the location given by the cursor and
363 /// store them into the destination vector. The vector is resized to fit the
364 /// extracted data. In case of an extraction error, or if the cursor is
365 /// already in an error state, the destination vector is left unchanged and
366 /// cursor is placed into an error state.
369 Dst.resize(Count);
370
371 // This relies on the fact that getU8 will not attempt to write to the
372 // buffer if isValidOffsetForDataOfSize(C.Offset, Count) is false.
373 getU8(C, Dst.data(), Count);
374 }
375
376 /// Extract a int8_t value from \a *OffsetPtr. In case of an extraction error,
377 /// or if error is already set, zero is returned and the offset is left
378 /// unmodified.
379 int8_t getS8(uint64_t *OffsetPtr, Error *Err = nullptr) const {
380 return static_cast<int8_t>(getU8(OffsetPtr, Err));
381 }
382
383 /// Extract a int8_t value from \a *OffsetPtr. In case of an extraction error,
384 /// or if the cursor is already in an error state, zero is returned and the
385 /// offset is left unmodified.
386 int8_t getS8(Cursor &C) const { return static_cast<int8_t>(getU8(C)); }
387
388 //------------------------------------------------------------------
389 /// Extract a uint16_t value from \a *offset_ptr.
390 ///
391 /// Extract a single uint16_t from the binary data at the offset
392 /// pointed to by \a offset_ptr, and update the offset on success.
393 ///
394 /// @param[in,out] offset_ptr
395 /// A pointer to an offset within the data that will be advanced
396 /// by the appropriate number of bytes if the value is extracted
397 /// correctly. If the offset is out of bounds or there are not
398 /// enough bytes to extract this value, the offset will be left
399 /// unmodified.
400 ///
401 /// @param[in,out] Err
402 /// A pointer to an Error object. Upon return the Error object is set to
403 /// indicate the result (success/failure) of the function. If the Error
404 /// object is already set when calling this function, no extraction is
405 /// performed.
406 ///
407 /// @return
408 /// The extracted uint16_t value.
409 //------------------------------------------------------------------
410 LLVM_ABI uint16_t getU16(uint64_t *offset_ptr, Error *Err = nullptr) const;
411
412 /// Extract a single uint16_t value from the location given by the cursor. In
413 /// case of an extraction error, or if the cursor is already in an error
414 /// state, zero is returned.
415 uint16_t getU16(Cursor &C) const { return getU16(&C.Offset, &C.Err); }
416
417 /// Extract \a count uint16_t values from \a *offset_ptr.
418 ///
419 /// Extract \a count uint16_t values from the binary data at the
420 /// offset pointed to by \a offset_ptr, and advance the offset on
421 /// success. The extracted values are copied into \a dst.
422 ///
423 /// @param[in,out] offset_ptr
424 /// A pointer to an offset within the data that will be advanced
425 /// by the appropriate number of bytes if the value is extracted
426 /// correctly. If the offset is out of bounds or there are not
427 /// enough bytes to extract this value, the offset will be left
428 /// unmodified.
429 ///
430 /// @param[out] dst
431 /// A buffer to copy \a count uint16_t values into. \a dst must
432 /// be large enough to hold all requested data.
433 ///
434 /// @param[in] count
435 /// The number of uint16_t values to extract.
436 ///
437 /// @return
438 /// \a dst if all values were properly extracted and copied,
439 /// NULL otherise.
440 LLVM_ABI uint16_t *getU16(uint64_t *offset_ptr, uint16_t *dst,
441 uint32_t count) const;
442
443 /// Extract a int16_t value from \a *OffsetPtr. In case of an extraction
444 /// error, or if error is already set, zero is returned and the offset is left
445 /// unmodified.
446 int16_t getS16(uint64_t *OffsetPtr, Error *Err = nullptr) const {
447 return static_cast<int16_t>(getU16(OffsetPtr, Err));
448 }
449
450 /// Extract a int16_t value from \a *OffsetPtr. In case of an extraction
451 /// error, or if the cursor is already in an error state, zero is returned and
452 /// the offset is left unmodified.
453 int16_t getS16(Cursor &C) const { return static_cast<int16_t>(getU16(C)); }
454
455 /// Extract a 24-bit unsigned value from \a *offset_ptr and return it
456 /// in a uint32_t.
457 ///
458 /// Extract 3 bytes from the binary data at the offset pointed to by
459 /// \a offset_ptr, construct a uint32_t from them and update the offset
460 /// on success.
461 ///
462 /// @param[in,out] OffsetPtr
463 /// A pointer to an offset within the data that will be advanced
464 /// by the 3 bytes if the value is extracted correctly. If the offset
465 /// is out of bounds or there are not enough bytes to extract this value,
466 /// the offset will be left unmodified.
467 ///
468 /// @param[in,out] Err
469 /// A pointer to an Error object. Upon return the Error object is set to
470 /// indicate the result (success/failure) of the function. If the Error
471 /// object is already set when calling this function, no extraction is
472 /// performed.
473 ///
474 /// @return
475 /// The extracted 24-bit value represented in a uint32_t.
476 LLVM_ABI uint32_t getU24(uint64_t *OffsetPtr, Error *Err = nullptr) const;
477
478 /// Extract a single 24-bit unsigned value from the location given by the
479 /// cursor. In case of an extraction error, or if the cursor is already in an
480 /// error state, zero is returned.
481 uint32_t getU24(Cursor &C) const { return getU24(&C.Offset, &C.Err); }
482
483 /// Extract a uint32_t value from \a *offset_ptr.
484 ///
485 /// Extract a single uint32_t from the binary data at the offset
486 /// pointed to by \a offset_ptr, and update the offset on success.
487 ///
488 /// @param[in,out] offset_ptr
489 /// A pointer to an offset within the data that will be advanced
490 /// by the appropriate number of bytes if the value is extracted
491 /// correctly. If the offset is out of bounds or there are not
492 /// enough bytes to extract this value, the offset will be left
493 /// unmodified.
494 ///
495 /// @param[in,out] Err
496 /// A pointer to an Error object. Upon return the Error object is set to
497 /// indicate the result (success/failure) of the function. If the Error
498 /// object is already set when calling this function, no extraction is
499 /// performed.
500 ///
501 /// @return
502 /// The extracted uint32_t value.
503 LLVM_ABI uint32_t getU32(uint64_t *offset_ptr, Error *Err = nullptr) const;
504
505 /// Extract a single uint32_t value from the location given by the cursor. In
506 /// case of an extraction error, or if the cursor is already in an error
507 /// state, zero is returned.
508 uint32_t getU32(Cursor &C) const { return getU32(&C.Offset, &C.Err); }
509
510 /// Extract \a count uint32_t values from \a *offset_ptr.
511 ///
512 /// Extract \a count uint32_t values from the binary data at the
513 /// offset pointed to by \a offset_ptr, and advance the offset on
514 /// success. The extracted values are copied into \a dst.
515 ///
516 /// @param[in,out] offset_ptr
517 /// A pointer to an offset within the data that will be advanced
518 /// by the appropriate number of bytes if the value is extracted
519 /// correctly. If the offset is out of bounds or there are not
520 /// enough bytes to extract this value, the offset will be left
521 /// unmodified.
522 ///
523 /// @param[out] dst
524 /// A buffer to copy \a count uint32_t values into. \a dst must
525 /// be large enough to hold all requested data.
526 ///
527 /// @param[in] count
528 /// The number of uint32_t values to extract.
529 ///
530 /// @return
531 /// \a dst if all values were properly extracted and copied,
532 /// NULL otherise.
533 LLVM_ABI uint32_t *getU32(uint64_t *offset_ptr, uint32_t *dst,
534 uint32_t count) const;
535
536 /// Extract a int32_t value from \a *OffsetPtr. In case of an extraction
537 /// error, or if error is already set, zero is returned and the offset is left
538 /// unmodified.
539 int32_t getS32(uint64_t *OffsetPtr, Error *Err = nullptr) const {
540 return static_cast<int32_t>(getU32(OffsetPtr, Err));
541 }
542
543 /// Extract a int32_t value from \a *OffsetPtr. In case of an extraction
544 /// error, or if the cursor is already in an error state, zero is returned and
545 /// the offset is left unmodified.
546 int32_t getS32(Cursor &C) const { return static_cast<int32_t>(getU32(C)); }
547
548 /// Extract a uint64_t value from \a *offset_ptr.
549 ///
550 /// Extract a single uint64_t from the binary data at the offset
551 /// pointed to by \a offset_ptr, and update the offset on success.
552 ///
553 /// @param[in,out] offset_ptr
554 /// A pointer to an offset within the data that will be advanced
555 /// by the appropriate number of bytes if the value is extracted
556 /// correctly. If the offset is out of bounds or there are not
557 /// enough bytes to extract this value, the offset will be left
558 /// unmodified.
559 ///
560 /// @param[in,out] Err
561 /// A pointer to an Error object. Upon return the Error object is set to
562 /// indicate the result (success/failure) of the function. If the Error
563 /// object is already set when calling this function, no extraction is
564 /// performed.
565 ///
566 /// @return
567 /// The extracted uint64_t value.
568 LLVM_ABI uint64_t getU64(uint64_t *offset_ptr, Error *Err = nullptr) const;
569
570 /// Extract a single uint64_t value from the location given by the cursor. In
571 /// case of an extraction error, or if the cursor is already in an error
572 /// state, zero is returned.
573 uint64_t getU64(Cursor &C) const { return getU64(&C.Offset, &C.Err); }
574
575 /// Extract \a count uint64_t values from \a *offset_ptr.
576 ///
577 /// Extract \a count uint64_t values from the binary data at the
578 /// offset pointed to by \a offset_ptr, and advance the offset on
579 /// success. The extracted values are copied into \a dst.
580 ///
581 /// @param[in,out] offset_ptr
582 /// A pointer to an offset within the data that will be advanced
583 /// by the appropriate number of bytes if the value is extracted
584 /// correctly. If the offset is out of bounds or there are not
585 /// enough bytes to extract this value, the offset will be left
586 /// unmodified.
587 ///
588 /// @param[out] dst
589 /// A buffer to copy \a count uint64_t values into. \a dst must
590 /// be large enough to hold all requested data.
591 ///
592 /// @param[in] count
593 /// The number of uint64_t values to extract.
594 ///
595 /// @return
596 /// \a dst if all values were properly extracted and copied,
597 /// NULL otherise.
598 LLVM_ABI uint64_t *getU64(uint64_t *offset_ptr, uint64_t *dst,
599 uint32_t count) const;
600
601 /// Extract a int64_t value from \a *OffsetPtr. In case of an extraction
602 /// error, or if error is already set, zero is returned and the offset is left
603 /// unmodified.
604 int64_t getS64(uint64_t *OffsetPtr, Error *Err = nullptr) const {
605 return static_cast<int64_t>(getU64(OffsetPtr, Err));
606 }
607
608 /// Extract a int64_t value from \a *OffsetPtr. In case of an extraction
609 /// error, or if the cursor is already in an error state, zero is returned and
610 /// the offset is left unmodified.
611 int64_t getS64(Cursor &C) const { return static_cast<int64_t>(getU64(C)); }
612
613 /// Extract a signed LEB128 value from \a *offset_ptr.
614 ///
615 /// Extracts an signed LEB128 number from this object's data
616 /// starting at the offset pointed to by \a offset_ptr. The offset
617 /// pointed to by \a offset_ptr will be updated with the offset of
618 /// the byte following the last extracted byte.
619 ///
620 /// @param[in,out] OffsetPtr
621 /// A pointer to an offset within the data that will be advanced
622 /// by the appropriate number of bytes if the value is extracted
623 /// correctly. If the offset is out of bounds or there are not
624 /// enough bytes to extract this value, the offset will be left
625 /// unmodified.
626 ///
627 /// @param[in,out] Err
628 /// A pointer to an Error object. Upon return the Error object is set to
629 /// indicate the result (success/failure) of the function. If the Error
630 /// object is already set when calling this function, no extraction is
631 /// performed.
632 ///
633 /// @return
634 /// The extracted signed integer value.
635 LLVM_ABI int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err = nullptr) const;
636
637 /// Extract an signed LEB128 value from the location given by the cursor.
638 /// In case of an extraction error, or if the cursor is already in an error
639 /// state, zero is returned.
640 int64_t getSLEB128(Cursor &C) const { return getSLEB128(&C.Offset, &C.Err); }
641
642 /// Extract a unsigned LEB128 value from \a *offset_ptr.
643 ///
644 /// Extracts an unsigned LEB128 number from this object's data
645 /// starting at the offset pointed to by \a offset_ptr. The offset
646 /// pointed to by \a offset_ptr will be updated with the offset of
647 /// the byte following the last extracted byte.
648 ///
649 /// @param[in,out] offset_ptr
650 /// A pointer to an offset within the data that will be advanced
651 /// by the appropriate number of bytes if the value is extracted
652 /// correctly. If the offset is out of bounds or there are not
653 /// enough bytes to extract this value, the offset will be left
654 /// unmodified.
655 ///
656 /// @param[in,out] Err
657 /// A pointer to an Error object. Upon return the Error object is set to
658 /// indicate the result (success/failure) of the function. If the Error
659 /// object is already set when calling this function, no extraction is
660 /// performed.
661 ///
662 /// @return
663 /// The extracted unsigned integer value.
665 llvm::Error *Err = nullptr) const;
666
667 /// Extract an unsigned LEB128 value from the location given by the cursor.
668 /// In case of an extraction error, or if the cursor is already in an error
669 /// state, zero is returned.
670 uint64_t getULEB128(Cursor &C) const { return getULEB128(&C.Offset, &C.Err); }
671
672 /// Advance the Cursor position by the given number of bytes. No-op if the
673 /// cursor is in an error state.
674 LLVM_ABI void skip(Cursor &C, uint64_t Length) const;
675
676 /// Return true iff the cursor is at the end of the buffer, regardless of the
677 /// error state of the cursor. The only way both eof and error states can be
678 /// true is if one attempts a read while the cursor is at the very end of the
679 /// data buffer.
680 bool eof(const Cursor &C) const { return size() == C.Offset; }
681
682 /// Test the validity of \a offset.
683 ///
684 /// @return
685 /// \b true if \a offset is a valid offset into the data in this
686 /// object, \b false otherwise.
687 bool isValidOffset(uint64_t offset) const { return size() > offset; }
688
689 /// Test the availability of \a length bytes of data from \a offset.
690 ///
691 /// @return
692 /// \b true if \a offset is a valid offset and there are \a
693 /// length bytes available at that offset, \b false otherwise.
694 bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const {
695 return offset + length >= offset && isValidOffset(offset + length - 1);
696 }
697
698 /// Return the number of bytes in the underlying buffer.
699 size_t size() const { return Data.size(); }
700
701protected:
702 // Make it possible for subclasses to access these fields without making them
703 // public.
704 static uint64_t &getOffset(Cursor &C) { return C.Offset; }
705 static Error &getError(Cursor &C) { return C.Err; }
706
707private:
708 /// If it is possible to read \a Size bytes at offset \a Offset, returns \b
709 /// true. Otherwise, returns \b false. If \a E is not nullptr, also sets the
710 /// error object to indicate an error.
711 bool prepareRead(uint64_t Offset, uint64_t Size, Error *E) const;
712
713 template <typename T> T getU(uint64_t *OffsetPtr, Error *Err) const;
714 template <typename T>
715 T *getUs(uint64_t *OffsetPtr, T *Dst, uint32_t Count, Error *Err) const;
716};
717
718} // namespace llvm
719
720#endif
aarch64 promote const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
#define T
static Split data
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Cursor(uint64_t Offset)
Construct a cursor for extraction from the given offset.
uint64_t tell() const
Return the current position of this Cursor.
Error takeError()
Return error contained inside this Cursor, if any.
void seek(uint64_t NewOffSet)
Set the cursor to the new offset. This does not impact the error state.
LLVM_ABI StringRef getFixedLengthString(uint64_t *OffsetPtr, uint64_t Length, StringRef TrimChars={"\0", 1}) const
Extract a fixed length string from *OffsetPtr and consume Length bytes.
uint32_t getU32(Cursor &C) const
Extract a single uint32_t value from the location given by the cursor.
LLVM_ABI uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size, Error *Err=nullptr) const
Extract an unsigned integer of size byte_size from *offset_ptr.
LLVM_ABI uint32_t getU32(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint32_t value from *offset_ptr.
size_t size() const
Return the number of bytes in the underlying buffer.
const char * getCStr(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
void getU8(Cursor &C, SmallVectorImpl< uint8_t > &Dst, uint32_t Count) const
Extract Count uint8_t values from the location given by the cursor and store them into the destinatio...
int16_t getS16(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int16_t value from *OffsetPtr.
int8_t getS8(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int8_t value from *OffsetPtr.
int64_t getSLEB128(Cursor &C) const
Extract an signed LEB128 value from the location given by the cursor.
static uint64_t & getOffset(Cursor &C)
int32_t getS32(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int32_t value from *OffsetPtr.
bool eof(const Cursor &C) const
Return true iff the cursor is at the end of the buffer, regardless of the error state of the cursor.
LLVM_ABI StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a C string from *offset_ptr.
LLVM_ABI uint8_t getU8(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint8_t value from *offset_ptr.
DataExtractor(StringRef Data, bool IsLittleEndian)
Construct with a buffer that is owned by the caller.
LLVM_ABI int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const
Extract an signed integer of size byte_size from *offset_ptr.
int64_t getS64(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a int64_t value from *OffsetPtr.
LLVM_ABI uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err=nullptr) const
Extract a unsigned LEB128 value from *offset_ptr.
uint64_t getUnsigned(Cursor &C, uint32_t Size) const
Extract an unsigned integer of the given size from the location given by the cursor.
uint64_t getULEB128(Cursor &C) const
Extract an unsigned LEB128 value from the location given by the cursor.
uint32_t getU24(Cursor &C) const
Extract a single 24-bit unsigned value from the location given by the cursor.
StringRef getData() const
Get the data pointed to by this extractor.
LLVM_ABI int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a signed LEB128 value from *offset_ptr.
StringRef getCStrRef(Cursor &C) const
Extract a C string (as a StringRef) from the location given by the cursor.
StringRef getBytes(Cursor &C, uint64_t Length)
Extract a fixed number of bytes from the location given by the cursor.
int32_t getS32(Cursor &C) const
Extract a int32_t value from *OffsetPtr.
DataExtractor(ArrayRef< uint8_t > Data, bool IsLittleEndian)
const char * getCStr(Cursor &C) const
Extract a C string from the location given by the cursor.
LLVM_ABI uint16_t getU16(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint16_t value from *offset_ptr.
uint16_t getU16(Cursor &C) const
Extract a single uint16_t value from the location given by the cursor.
LLVM_ABI void skip(Cursor &C, uint64_t Length) const
Advance the Cursor position by the given number of bytes.
uint64_t getU64(Cursor &C) const
Extract a single uint64_t value from the location given by the cursor.
LLVM_ABI uint64_t getU64(uint64_t *offset_ptr, Error *Err=nullptr) const
Extract a uint64_t value from *offset_ptr.
uint8_t getU8(Cursor &C) const
Extract a single uint8_t value from the location given by the cursor.
static Error & getError(Cursor &C)
int16_t getS16(Cursor &C) const
Extract a int16_t value from *OffsetPtr.
bool isValidOffset(uint64_t offset) const
Test the validity of offset.
bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const
Test the availability of length bytes of data from offset.
bool isLittleEndian() const
Get the endianness for this extractor.
LLVM_ABI StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length, Error *Err=nullptr) const
Extract a fixed number of bytes from the specified offset.
int8_t getS8(Cursor &C) const
Extract a int8_t value from *OffsetPtr.
LLVM_ABI uint32_t getU24(uint64_t *OffsetPtr, Error *Err=nullptr) const
Extract a 24-bit unsigned value from *offset_ptr and return it in a uint32_t.
int64_t getS64(Cursor &C) const
Extract a int64_t value from *OffsetPtr.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
@ Length
Definition DWP.cpp:558
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1668
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
uint24_t getSwappedBytes(uint24_t C)
Needed by swapByteOrder().
Uint24 uint24_t
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition STLExtras.h:2011
LogicalResult success(bool IsSuccess=true)
Utility function to generate a LogicalResult.
An auxiliary type to facilitate extraction of 3-byte entities.
Uint24(uint8_t U)
uint8_t Bytes[3]
uint32_t getAsUint32(bool IsLittleEndian) const
Uint24(uint8_t U0, uint8_t U1, uint8_t U2)