Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:29

0001 //===-- DataExtractor.h -----------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
0010 #define LLVM_SUPPORT_DATAEXTRACTOR_H
0011 
0012 #include "llvm/ADT/StringRef.h"
0013 #include "llvm/Support/DataTypes.h"
0014 #include "llvm/Support/Error.h"
0015 
0016 namespace llvm {
0017 
0018 /// An auxiliary type to facilitate extraction of 3-byte entities.
0019 struct Uint24 {
0020   uint8_t Bytes[3];
0021   Uint24(uint8_t U) {
0022     Bytes[0] = Bytes[1] = Bytes[2] = U;
0023   }
0024   Uint24(uint8_t U0, uint8_t U1, uint8_t U2) {
0025     Bytes[0] = U0; Bytes[1] = U1; Bytes[2] = U2;
0026   }
0027   uint32_t getAsUint32(bool IsLittleEndian) const {
0028     int LoIx = IsLittleEndian ? 0 : 2;
0029     return Bytes[LoIx] + (Bytes[1] << 8) + (Bytes[2-LoIx] << 16);
0030   }
0031 };
0032 
0033 using uint24_t = Uint24;
0034 static_assert(sizeof(uint24_t) == 3, "sizeof(uint24_t) != 3");
0035 
0036 /// Needed by swapByteOrder().
0037 inline uint24_t getSwappedBytes(uint24_t C) {
0038   return uint24_t(C.Bytes[2], C.Bytes[1], C.Bytes[0]);
0039 }
0040 
0041 class DataExtractor {
0042   StringRef Data;
0043   uint8_t IsLittleEndian;
0044   uint8_t AddressSize;
0045 public:
0046   /// A class representing a position in a DataExtractor, as well as any error
0047   /// encountered during extraction. It enables one to extract a sequence of
0048   /// values without error-checking and then checking for errors in bulk at the
0049   /// end. The class holds an Error object, so failing to check the result of
0050   /// the parse will result in a runtime error. The error flag is sticky and
0051   /// will cause all subsequent extraction functions to fail without even
0052   /// attempting to parse and without updating the Cursor offset. After clearing
0053   /// the error flag, one can again use the Cursor object for parsing.
0054   class Cursor {
0055     uint64_t Offset;
0056     Error Err;
0057 
0058     friend class DataExtractor;
0059 
0060   public:
0061     /// Construct a cursor for extraction from the given offset.
0062     explicit Cursor(uint64_t Offset) : Offset(Offset), Err(Error::success()) {}
0063 
0064     /// Checks whether the cursor is valid (i.e. no errors were encountered). In
0065     /// case of errors, this does not clear the error flag -- one must call
0066     /// takeError() instead.
0067     explicit operator bool() { return !Err; }
0068 
0069     /// Return the current position of this Cursor. In the error state this is
0070     /// the position of the Cursor before the first error was encountered.
0071     uint64_t tell() const { return Offset; }
0072 
0073     /// Set the cursor to the new offset. This does not impact the error state.
0074     void seek(uint64_t NewOffSet) { Offset = NewOffSet; }
0075 
0076     /// Return error contained inside this Cursor, if any. Clears the internal
0077     /// Cursor state.
0078     Error takeError() { return std::move(Err); }
0079   };
0080 
0081   /// Construct with a buffer that is owned by the caller.
0082   ///
0083   /// This constructor allows us to use data that is owned by the
0084   /// caller. The data must stay around as long as this object is
0085   /// valid.
0086   DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
0087     : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
0088   DataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian,
0089                 uint8_t AddressSize)
0090       : Data(StringRef(reinterpret_cast<const char *>(Data.data()),
0091                        Data.size())),
0092         IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
0093 
0094   /// Get the data pointed to by this extractor.
0095   StringRef getData() const { return Data; }
0096   /// Get the endianness for this extractor.
0097   bool isLittleEndian() const { return IsLittleEndian; }
0098   /// Get the address size for this extractor.
0099   uint8_t getAddressSize() const { return AddressSize; }
0100   /// Set the address size for this extractor.
0101   void setAddressSize(uint8_t Size) { AddressSize = Size; }
0102 
0103   /// Extract a C string from \a *offset_ptr.
0104   ///
0105   /// Returns a pointer to a C String from the data at the offset
0106   /// pointed to by \a offset_ptr. A variable length NULL terminated C
0107   /// string will be extracted and the \a offset_ptr will be
0108   /// updated with the offset of the byte that follows the NULL
0109   /// terminator byte.
0110   ///
0111   /// @param[in,out] OffsetPtr
0112   ///     A pointer to an offset within the data that will be advanced
0113   ///     by the appropriate number of bytes if the value is extracted
0114   ///     correctly. If the offset is out of bounds or there are not
0115   ///     enough bytes to extract this value, the offset will be left
0116   ///     unmodified.
0117   ///
0118   /// @param[in,out] Err
0119   ///     A pointer to an Error object. Upon return the Error object is set to
0120   ///     indicate the result (success/failure) of the function. If the Error
0121   ///     object is already set when calling this function, no extraction is
0122   ///     performed.
0123   ///
0124   /// @return
0125   ///     A pointer to the C string value in the data. If the offset
0126   ///     pointed to by \a offset_ptr is out of bounds, or if the
0127   ///     offset plus the length of the C string is out of bounds,
0128   ///     NULL will be returned.
0129   const char *getCStr(uint64_t *OffsetPtr, Error *Err = nullptr) const {
0130     return getCStrRef(OffsetPtr, Err).data();
0131   }
0132 
0133   /// Extract a C string from the location given by the cursor. In case of an
0134   /// extraction error, or if the cursor is already in an error state, a
0135   /// nullptr is returned.
0136   const char *getCStr(Cursor &C) const { return getCStrRef(C).data(); }
0137 
0138   /// Extract a C string from \a *offset_ptr.
0139   ///
0140   /// Returns a StringRef for the C String from the data at the offset
0141   /// pointed to by \a offset_ptr. A variable length NULL terminated C
0142   /// string will be extracted and the \a offset_ptr will be
0143   /// updated with the offset of the byte that follows the NULL
0144   /// terminator byte.
0145   ///
0146   /// \param[in,out] OffsetPtr
0147   ///     A pointer to an offset within the data that will be advanced
0148   ///     by the appropriate number of bytes if the value is extracted
0149   ///     correctly. If the offset is out of bounds or there are not
0150   ///     enough bytes to extract this value, the offset will be left
0151   ///     unmodified.
0152   ///
0153   /// @param[in,out] Err
0154   ///     A pointer to an Error object. Upon return the Error object is set to
0155   ///     indicate the result (success/failure) of the function. If the Error
0156   ///     object is already set when calling this function, no extraction is
0157   ///     performed.
0158   ///
0159   /// \return
0160   ///     A StringRef for the C string value in the data. If the offset
0161   ///     pointed to by \a offset_ptr is out of bounds, or if the
0162   ///     offset plus the length of the C string is out of bounds,
0163   ///     a default-initialized StringRef will be returned.
0164   StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err = nullptr) const;
0165 
0166   /// Extract a C string (as a StringRef) from the location given by the cursor.
0167   /// In case of an extraction error, or if the cursor is already in an error
0168   /// state, a default-initialized StringRef is returned.
0169   StringRef getCStrRef(Cursor &C) const {
0170     return getCStrRef(&C.Offset, &C.Err);
0171   }
0172 
0173   /// Extract a fixed length string from \a *OffsetPtr and consume \a Length
0174   /// bytes.
0175   ///
0176   /// Returns a StringRef for the string from the data at the offset
0177   /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
0178   /// and the \a OffsetPtr will be advanced by \a Length bytes.
0179   ///
0180   /// \param[in,out] OffsetPtr
0181   ///     A pointer to an offset within the data that will be advanced
0182   ///     by the appropriate number of bytes if the value is extracted
0183   ///     correctly. If the offset is out of bounds or there are not
0184   ///     enough bytes to extract this value, the offset will be left
0185   ///     unmodified.
0186   ///
0187   /// \param[in] Length
0188   ///     The length of the fixed length string to extract. If there are not
0189   ///     enough bytes in the data to extract the full string, the offset will
0190   ///     be left unmodified.
0191   ///
0192   /// \param[in] TrimChars
0193   ///     A set of characters to trim from the end of the string. Fixed length
0194   ///     strings are commonly either NULL terminated by one or more zero
0195   ///     bytes. Some clients have one or more spaces at the end of the string,
0196   ///     but a good default is to trim the NULL characters.
0197   ///
0198   /// \return
0199   ///     A StringRef for the C string value in the data. If the offset
0200   ///     pointed to by \a OffsetPtr is out of bounds, or if the
0201   ///     offset plus the length of the C string is out of bounds,
0202   ///     a default-initialized StringRef will be returned.
0203   StringRef getFixedLengthString(uint64_t *OffsetPtr,
0204       uint64_t Length, StringRef TrimChars = {"\0", 1}) const;
0205 
0206   /// Extract a fixed number of bytes from the specified offset.
0207   ///
0208   /// Returns a StringRef for the bytes from the data at the offset
0209   /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
0210   /// and the \a OffsetPtr will be advanced by \a Length bytes.
0211   ///
0212   /// \param[in,out] OffsetPtr
0213   ///     A pointer to an offset within the data that will be advanced
0214   ///     by the appropriate number of bytes if the value is extracted
0215   ///     correctly. If the offset is out of bounds or there are not
0216   ///     enough bytes to extract this value, the offset will be left
0217   ///     unmodified.
0218   ///
0219   /// \param[in] Length
0220   ///     The number of bytes to extract. If there are not enough bytes in the
0221   ///     data to extract all of the bytes, the offset will be left unmodified.
0222   ///
0223   /// @param[in,out] Err
0224   ///     A pointer to an Error object. Upon return the Error object is set to
0225   ///     indicate the result (success/failure) of the function. If the Error
0226   ///     object is already set when calling this function, no extraction is
0227   ///     performed.
0228   ///
0229   /// \return
0230   ///     A StringRef for the extracted bytes. If the offset pointed to by
0231   ///     \a OffsetPtr is out of bounds, or if the offset plus the length
0232   ///     is out of bounds, a default-initialized StringRef will be returned.
0233   StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length,
0234                      Error *Err = nullptr) const;
0235 
0236   /// Extract a fixed number of bytes from the location given by the cursor. In
0237   /// case of an extraction error, or if the cursor is already in an error
0238   /// state, a default-initialized StringRef is returned.
0239   StringRef getBytes(Cursor &C, uint64_t Length) {
0240     return getBytes(&C.Offset, Length, &C.Err);
0241   }
0242 
0243   /// Extract an unsigned integer of size \a byte_size from \a
0244   /// *offset_ptr.
0245   ///
0246   /// Extract a single unsigned integer value and update the offset
0247   /// pointed to by \a offset_ptr. The size of the extracted integer
0248   /// is specified by the \a byte_size argument. \a byte_size should
0249   /// have a value greater than or equal to one and less than or equal
0250   /// to eight since the return value is 64 bits wide. Any
0251   /// \a byte_size values less than 1 or greater than 8 will result in
0252   /// nothing being extracted, and zero being returned.
0253   ///
0254   /// @param[in,out] offset_ptr
0255   ///     A pointer to an offset within the data that will be advanced
0256   ///     by the appropriate number of bytes if the value is extracted
0257   ///     correctly. If the offset is out of bounds or there are not
0258   ///     enough bytes to extract this value, the offset will be left
0259   ///     unmodified.
0260   ///
0261   /// @param[in] byte_size
0262   ///     The size in byte of the integer to extract.
0263   ///
0264   /// @param[in,out] Err
0265   ///     A pointer to an Error object. Upon return the Error object is set to
0266   ///     indicate the result (success/failure) of the function. If the Error
0267   ///     object is already set when calling this function, no extraction is
0268   ///     performed.
0269   ///
0270   /// @return
0271   ///     The unsigned integer value that was extracted, or zero on
0272   ///     failure.
0273   uint64_t getUnsigned(uint64_t *offset_ptr, uint32_t byte_size,
0274                        Error *Err = nullptr) const;
0275 
0276   /// Extract an unsigned integer of the given size from the location given by
0277   /// the cursor. In case of an extraction error, or if the cursor is already in
0278   /// an error state, zero is returned.
0279   uint64_t getUnsigned(Cursor &C, uint32_t Size) const {
0280     return getUnsigned(&C.Offset, Size, &C.Err);
0281   }
0282 
0283   /// Extract an signed integer of size \a byte_size from \a *offset_ptr.
0284   ///
0285   /// Extract a single signed integer value (sign extending if required)
0286   /// and update the offset pointed to by \a offset_ptr. The size of
0287   /// the extracted integer is specified by the \a byte_size argument.
0288   /// \a byte_size should have a value greater than or equal to one
0289   /// and less than or equal to eight since the return value is 64
0290   /// bits wide. Any \a byte_size values less than 1 or greater than
0291   /// 8 will result in nothing being extracted, and zero being returned.
0292   ///
0293   /// @param[in,out] offset_ptr
0294   ///     A pointer to an offset within the data that will be advanced
0295   ///     by the appropriate number of bytes if the value is extracted
0296   ///     correctly. If the offset is out of bounds or there are not
0297   ///     enough bytes to extract this value, the offset will be left
0298   ///     unmodified.
0299   ///
0300   /// @param[in] size
0301   ///     The size in bytes of the integer to extract.
0302   ///
0303   /// @return
0304   ///     The sign extended signed integer value that was extracted,
0305   ///     or zero on failure.
0306   int64_t getSigned(uint64_t *offset_ptr, uint32_t size) const;
0307 
0308   //------------------------------------------------------------------
0309   /// Extract an pointer from \a *offset_ptr.
0310   ///
0311   /// Extract a single pointer from the data and update the offset
0312   /// pointed to by \a offset_ptr. The size of the extracted pointer
0313   /// is \a getAddressSize(), so the address size has to be
0314   /// set correctly prior to extracting any pointer values.
0315   ///
0316   /// @param[in,out] offset_ptr
0317   ///     A pointer to an offset within the data that will be advanced
0318   ///     by the appropriate number of bytes if the value is extracted
0319   ///     correctly. If the offset is out of bounds or there are not
0320   ///     enough bytes to extract this value, the offset will be left
0321   ///     unmodified.
0322   ///
0323   /// @return
0324   ///     The extracted pointer value as a 64 integer.
0325   uint64_t getAddress(uint64_t *offset_ptr) const {
0326     return getUnsigned(offset_ptr, AddressSize);
0327   }
0328 
0329   /// Extract a pointer-sized unsigned integer from the location given by the
0330   /// cursor. In case of an extraction error, or if the cursor is already in
0331   /// an error state, zero is returned.
0332   uint64_t getAddress(Cursor &C) const { return getUnsigned(C, AddressSize); }
0333 
0334   /// Extract a uint8_t value from \a *offset_ptr.
0335   ///
0336   /// Extract a single uint8_t from the binary data at the offset
0337   /// pointed to by \a offset_ptr, and advance the offset on success.
0338   ///
0339   /// @param[in,out] offset_ptr
0340   ///     A pointer to an offset within the data that will be advanced
0341   ///     by the appropriate number of bytes if the value is extracted
0342   ///     correctly. If the offset is out of bounds or there are not
0343   ///     enough bytes to extract this value, the offset will be left
0344   ///     unmodified.
0345   ///
0346   /// @param[in,out] Err
0347   ///     A pointer to an Error object. Upon return the Error object is set to
0348   ///     indicate the result (success/failure) of the function. If the Error
0349   ///     object is already set when calling this function, no extraction is
0350   ///     performed.
0351   ///
0352   /// @return
0353   ///     The extracted uint8_t value.
0354   uint8_t getU8(uint64_t *offset_ptr, Error *Err = nullptr) const;
0355 
0356   /// Extract a single uint8_t value from the location given by the cursor. In
0357   /// case of an extraction error, or if the cursor is already in an error
0358   /// state, zero is returned.
0359   uint8_t getU8(Cursor &C) const { return getU8(&C.Offset, &C.Err); }
0360 
0361   /// Extract \a count uint8_t values from \a *offset_ptr.
0362   ///
0363   /// Extract \a count uint8_t values from the binary data at the
0364   /// offset pointed to by \a offset_ptr, and advance the offset on
0365   /// success. The extracted values are copied into \a dst.
0366   ///
0367   /// @param[in,out] offset_ptr
0368   ///     A pointer to an offset within the data that will be advanced
0369   ///     by the appropriate number of bytes if the value is extracted
0370   ///     correctly. If the offset is out of bounds or there are not
0371   ///     enough bytes to extract this value, the offset will be left
0372   ///     unmodified.
0373   ///
0374   /// @param[out] dst
0375   ///     A buffer to copy \a count uint8_t values into. \a dst must
0376   ///     be large enough to hold all requested data.
0377   ///
0378   /// @param[in] count
0379   ///     The number of uint8_t values to extract.
0380   ///
0381   /// @return
0382   ///     \a dst if all values were properly extracted and copied,
0383   ///     NULL otherise.
0384   uint8_t *getU8(uint64_t *offset_ptr, uint8_t *dst, uint32_t count) const;
0385 
0386   /// Extract \a Count uint8_t values from the location given by the cursor and
0387   /// store them into the destination buffer. In case of an extraction error, or
0388   /// if the cursor is already in an error state, a nullptr is returned and the
0389   /// destination buffer is left unchanged.
0390   uint8_t *getU8(Cursor &C, uint8_t *Dst, uint32_t Count) const;
0391 
0392   /// Extract \a Count uint8_t values from the location given by the cursor and
0393   /// store them into the destination vector. The vector is resized to fit the
0394   /// extracted data. In case of an extraction error, or if the cursor is
0395   /// already in an error state, the destination vector is left unchanged and
0396   /// cursor is placed into an error state.
0397   void getU8(Cursor &C, SmallVectorImpl<uint8_t> &Dst, uint32_t Count) const {
0398     if (isValidOffsetForDataOfSize(C.Offset, Count))
0399       Dst.resize(Count);
0400 
0401     // This relies on the fact that getU8 will not attempt to write to the
0402     // buffer if isValidOffsetForDataOfSize(C.Offset, Count) is false.
0403     getU8(C, Dst.data(), Count);
0404   }
0405 
0406   //------------------------------------------------------------------
0407   /// Extract a uint16_t value from \a *offset_ptr.
0408   ///
0409   /// Extract a single uint16_t from the binary data at the offset
0410   /// pointed to by \a offset_ptr, and update the offset on success.
0411   ///
0412   /// @param[in,out] offset_ptr
0413   ///     A pointer to an offset within the data that will be advanced
0414   ///     by the appropriate number of bytes if the value is extracted
0415   ///     correctly. If the offset is out of bounds or there are not
0416   ///     enough bytes to extract this value, the offset will be left
0417   ///     unmodified.
0418   ///
0419   /// @param[in,out] Err
0420   ///     A pointer to an Error object. Upon return the Error object is set to
0421   ///     indicate the result (success/failure) of the function. If the Error
0422   ///     object is already set when calling this function, no extraction is
0423   ///     performed.
0424   ///
0425   /// @return
0426   ///     The extracted uint16_t value.
0427   //------------------------------------------------------------------
0428   uint16_t getU16(uint64_t *offset_ptr, Error *Err = nullptr) const;
0429 
0430   /// Extract a single uint16_t value from the location given by the cursor. In
0431   /// case of an extraction error, or if the cursor is already in an error
0432   /// state, zero is returned.
0433   uint16_t getU16(Cursor &C) const { return getU16(&C.Offset, &C.Err); }
0434 
0435   /// Extract \a count uint16_t values from \a *offset_ptr.
0436   ///
0437   /// Extract \a count uint16_t values from the binary data at the
0438   /// offset pointed to by \a offset_ptr, and advance the offset on
0439   /// success. The extracted values are copied into \a dst.
0440   ///
0441   /// @param[in,out] offset_ptr
0442   ///     A pointer to an offset within the data that will be advanced
0443   ///     by the appropriate number of bytes if the value is extracted
0444   ///     correctly. If the offset is out of bounds or there are not
0445   ///     enough bytes to extract this value, the offset will be left
0446   ///     unmodified.
0447   ///
0448   /// @param[out] dst
0449   ///     A buffer to copy \a count uint16_t values into. \a dst must
0450   ///     be large enough to hold all requested data.
0451   ///
0452   /// @param[in] count
0453   ///     The number of uint16_t values to extract.
0454   ///
0455   /// @return
0456   ///     \a dst if all values were properly extracted and copied,
0457   ///     NULL otherise.
0458   uint16_t *getU16(uint64_t *offset_ptr, uint16_t *dst, uint32_t count) const;
0459 
0460   /// Extract a 24-bit unsigned value from \a *offset_ptr and return it
0461   /// in a uint32_t.
0462   ///
0463   /// Extract 3 bytes from the binary data at the offset pointed to by
0464   /// \a offset_ptr, construct a uint32_t from them and update the offset
0465   /// on success.
0466   ///
0467   /// @param[in,out] OffsetPtr
0468   ///     A pointer to an offset within the data that will be advanced
0469   ///     by the 3 bytes if the value is extracted correctly. If the offset
0470   ///     is out of bounds or there are not enough bytes to extract this value,
0471   ///     the offset will be left unmodified.
0472   ///
0473   /// @param[in,out] Err
0474   ///     A pointer to an Error object. Upon return the Error object is set to
0475   ///     indicate the result (success/failure) of the function. If the Error
0476   ///     object is already set when calling this function, no extraction is
0477   ///     performed.
0478   ///
0479   /// @return
0480   ///     The extracted 24-bit value represented in a uint32_t.
0481   uint32_t getU24(uint64_t *OffsetPtr, Error *Err = nullptr) const;
0482 
0483   /// Extract a single 24-bit unsigned value from the location given by the
0484   /// cursor. In case of an extraction error, or if the cursor is already in an
0485   /// error state, zero is returned.
0486   uint32_t getU24(Cursor &C) const { return getU24(&C.Offset, &C.Err); }
0487 
0488   /// Extract a uint32_t value from \a *offset_ptr.
0489   ///
0490   /// Extract a single uint32_t from the binary data at the offset
0491   /// pointed to by \a offset_ptr, and update the offset on success.
0492   ///
0493   /// @param[in,out] offset_ptr
0494   ///     A pointer to an offset within the data that will be advanced
0495   ///     by the appropriate number of bytes if the value is extracted
0496   ///     correctly. If the offset is out of bounds or there are not
0497   ///     enough bytes to extract this value, the offset will be left
0498   ///     unmodified.
0499   ///
0500   /// @param[in,out] Err
0501   ///     A pointer to an Error object. Upon return the Error object is set to
0502   ///     indicate the result (success/failure) of the function. If the Error
0503   ///     object is already set when calling this function, no extraction is
0504   ///     performed.
0505   ///
0506   /// @return
0507   ///     The extracted uint32_t value.
0508   uint32_t getU32(uint64_t *offset_ptr, Error *Err = nullptr) const;
0509 
0510   /// Extract a single uint32_t value from the location given by the cursor. In
0511   /// case of an extraction error, or if the cursor is already in an error
0512   /// state, zero is returned.
0513   uint32_t getU32(Cursor &C) const { return getU32(&C.Offset, &C.Err); }
0514 
0515   /// Extract \a count uint32_t values from \a *offset_ptr.
0516   ///
0517   /// Extract \a count uint32_t values from the binary data at the
0518   /// offset pointed to by \a offset_ptr, and advance the offset on
0519   /// success. The extracted values are copied into \a dst.
0520   ///
0521   /// @param[in,out] offset_ptr
0522   ///     A pointer to an offset within the data that will be advanced
0523   ///     by the appropriate number of bytes if the value is extracted
0524   ///     correctly. If the offset is out of bounds or there are not
0525   ///     enough bytes to extract this value, the offset will be left
0526   ///     unmodified.
0527   ///
0528   /// @param[out] dst
0529   ///     A buffer to copy \a count uint32_t values into. \a dst must
0530   ///     be large enough to hold all requested data.
0531   ///
0532   /// @param[in] count
0533   ///     The number of uint32_t values to extract.
0534   ///
0535   /// @return
0536   ///     \a dst if all values were properly extracted and copied,
0537   ///     NULL otherise.
0538   uint32_t *getU32(uint64_t *offset_ptr, uint32_t *dst, uint32_t count) const;
0539 
0540   /// Extract a uint64_t value from \a *offset_ptr.
0541   ///
0542   /// Extract a single uint64_t from the binary data at the offset
0543   /// pointed to by \a offset_ptr, and update the offset on success.
0544   ///
0545   /// @param[in,out] offset_ptr
0546   ///     A pointer to an offset within the data that will be advanced
0547   ///     by the appropriate number of bytes if the value is extracted
0548   ///     correctly. If the offset is out of bounds or there are not
0549   ///     enough bytes to extract this value, the offset will be left
0550   ///     unmodified.
0551   ///
0552   /// @param[in,out] Err
0553   ///     A pointer to an Error object. Upon return the Error object is set to
0554   ///     indicate the result (success/failure) of the function. If the Error
0555   ///     object is already set when calling this function, no extraction is
0556   ///     performed.
0557   ///
0558   /// @return
0559   ///     The extracted uint64_t value.
0560   uint64_t getU64(uint64_t *offset_ptr, Error *Err = nullptr) const;
0561 
0562   /// Extract a single uint64_t value from the location given by the cursor. In
0563   /// case of an extraction error, or if the cursor is already in an error
0564   /// state, zero is returned.
0565   uint64_t getU64(Cursor &C) const { return getU64(&C.Offset, &C.Err); }
0566 
0567   /// Extract \a count uint64_t values from \a *offset_ptr.
0568   ///
0569   /// Extract \a count uint64_t values from the binary data at the
0570   /// offset pointed to by \a offset_ptr, and advance the offset on
0571   /// success. The extracted values are copied into \a dst.
0572   ///
0573   /// @param[in,out] offset_ptr
0574   ///     A pointer to an offset within the data that will be advanced
0575   ///     by the appropriate number of bytes if the value is extracted
0576   ///     correctly. If the offset is out of bounds or there are not
0577   ///     enough bytes to extract this value, the offset will be left
0578   ///     unmodified.
0579   ///
0580   /// @param[out] dst
0581   ///     A buffer to copy \a count uint64_t values into. \a dst must
0582   ///     be large enough to hold all requested data.
0583   ///
0584   /// @param[in] count
0585   ///     The number of uint64_t values to extract.
0586   ///
0587   /// @return
0588   ///     \a dst if all values were properly extracted and copied,
0589   ///     NULL otherise.
0590   uint64_t *getU64(uint64_t *offset_ptr, uint64_t *dst, uint32_t count) const;
0591 
0592   /// Extract a signed LEB128 value from \a *offset_ptr.
0593   ///
0594   /// Extracts an signed LEB128 number from this object's data
0595   /// starting at the offset pointed to by \a offset_ptr. The offset
0596   /// pointed to by \a offset_ptr will be updated with the offset of
0597   /// the byte following the last extracted byte.
0598   ///
0599   /// @param[in,out] OffsetPtr
0600   ///     A pointer to an offset within the data that will be advanced
0601   ///     by the appropriate number of bytes if the value is extracted
0602   ///     correctly. If the offset is out of bounds or there are not
0603   ///     enough bytes to extract this value, the offset will be left
0604   ///     unmodified.
0605   ///
0606   /// @param[in,out] Err
0607   ///     A pointer to an Error object. Upon return the Error object is set to
0608   ///     indicate the result (success/failure) of the function. If the Error
0609   ///     object is already set when calling this function, no extraction is
0610   ///     performed.
0611   ///
0612   /// @return
0613   ///     The extracted signed integer value.
0614   int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err = nullptr) const;
0615 
0616   /// Extract an signed LEB128 value from the location given by the cursor.
0617   /// In case of an extraction error, or if the cursor is already in an error
0618   /// state, zero is returned.
0619   int64_t getSLEB128(Cursor &C) const { return getSLEB128(&C.Offset, &C.Err); }
0620 
0621   /// Extract a unsigned LEB128 value from \a *offset_ptr.
0622   ///
0623   /// Extracts an unsigned LEB128 number from this object's data
0624   /// starting at the offset pointed to by \a offset_ptr. The offset
0625   /// pointed to by \a offset_ptr will be updated with the offset of
0626   /// the byte following the last extracted byte.
0627   ///
0628   /// @param[in,out] offset_ptr
0629   ///     A pointer to an offset within the data that will be advanced
0630   ///     by the appropriate number of bytes if the value is extracted
0631   ///     correctly. If the offset is out of bounds or there are not
0632   ///     enough bytes to extract this value, the offset will be left
0633   ///     unmodified.
0634   ///
0635   /// @param[in,out] Err
0636   ///     A pointer to an Error object. Upon return the Error object is set to
0637   ///     indicate the result (success/failure) of the function. If the Error
0638   ///     object is already set when calling this function, no extraction is
0639   ///     performed.
0640   ///
0641   /// @return
0642   ///     The extracted unsigned integer value.
0643   uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err = nullptr) const;
0644 
0645   /// Extract an unsigned LEB128 value from the location given by the cursor.
0646   /// In case of an extraction error, or if the cursor is already in an error
0647   /// state, zero is returned.
0648   uint64_t getULEB128(Cursor &C) const { return getULEB128(&C.Offset, &C.Err); }
0649 
0650   /// Advance the Cursor position by the given number of bytes. No-op if the
0651   /// cursor is in an error state.
0652   void skip(Cursor &C, uint64_t Length) const;
0653 
0654   /// Return true iff the cursor is at the end of the buffer, regardless of the
0655   /// error state of the cursor. The only way both eof and error states can be
0656   /// true is if one attempts a read while the cursor is at the very end of the
0657   /// data buffer.
0658   bool eof(const Cursor &C) const { return size() == C.Offset; }
0659 
0660   /// Test the validity of \a offset.
0661   ///
0662   /// @return
0663   ///     \b true if \a offset is a valid offset into the data in this
0664   ///     object, \b false otherwise.
0665   bool isValidOffset(uint64_t offset) const { return size() > offset; }
0666 
0667   /// Test the availability of \a length bytes of data from \a offset.
0668   ///
0669   /// @return
0670   ///     \b true if \a offset is a valid offset and there are \a
0671   ///     length bytes available at that offset, \b false otherwise.
0672   bool isValidOffsetForDataOfSize(uint64_t offset, uint64_t length) const {
0673     return offset + length >= offset && isValidOffset(offset + length - 1);
0674   }
0675 
0676   /// Test the availability of enough bytes of data for a pointer from
0677   /// \a offset. The size of a pointer is \a getAddressSize().
0678   ///
0679   /// @return
0680   ///     \b true if \a offset is a valid offset and there are enough
0681   ///     bytes for a pointer available at that offset, \b false
0682   ///     otherwise.
0683   bool isValidOffsetForAddress(uint64_t offset) const {
0684     return isValidOffsetForDataOfSize(offset, AddressSize);
0685   }
0686 
0687   /// Return the number of bytes in the underlying buffer.
0688   size_t size() const { return Data.size(); }
0689 
0690 protected:
0691   // Make it possible for subclasses to access these fields without making them
0692   // public.
0693   static uint64_t &getOffset(Cursor &C) { return C.Offset; }
0694   static Error &getError(Cursor &C) { return C.Err; }
0695 
0696 private:
0697   /// If it is possible to read \a Size bytes at offset \a Offset, returns \b
0698   /// true. Otherwise, returns \b false. If \a E is not nullptr, also sets the
0699   /// error object to indicate an error.
0700   bool prepareRead(uint64_t Offset, uint64_t Size, Error *E) const;
0701 
0702   template <typename T> T getU(uint64_t *OffsetPtr, Error *Err) const;
0703   template <typename T>
0704   T *getUs(uint64_t *OffsetPtr, T *Dst, uint32_t Count, Error *Err) const;
0705 };
0706 
0707 } // namespace llvm
0708 
0709 #endif