#ifndef SPINEL_DECODER_HPP_
#define SPINEL_DECODER_HPP_
#include "openthread-spinel-config.h"
#include <openthread/ip6.h>
#include <openthread/ncp.h>
#include "spinel.h"
namespace ot {
namespace Spinel {
class Decoder
{
public:
enum
{
kMaxNestedStructs = 4, };
Decoder(void);
void Init(const uint8_t *aFrame, uint16_t aLength);
const uint8_t *GetFrame(void) const { return mFrame; }
uint16_t GetLength(void) const { return mLength; }
uint16_t GetReadLength(void) const { return mIndex; }
uint16_t GetRemainingLength(void) const { return mLength - mIndex; }
bool IsAllRead(void) const { return (mIndex == mLength); }
void Reset(void);
otError ReadBool(bool &aBool);
otError ReadInt8(int8_t &aInt8);
otError ReadUint8(uint8_t &aUint8);
otError ReadInt16(int16_t &aInt16);
otError ReadUint16(uint16_t &aUint16);
otError ReadInt32(int32_t &aInt32);
otError ReadUint32(uint32_t &aUint32);
otError ReadInt64(int64_t &aInt64);
otError ReadUint64(uint64_t &aUint64);
otError ReadUintPacked(unsigned int &aUint);
otError ReadIp6Address(const spinel_ipv6addr_t *&aIp6AddrPtr)
{
return ReadItem(reinterpret_cast<const uint8_t **>(&aIp6AddrPtr), sizeof(spinel_ipv6addr_t));
}
otError ReadIp6Address(const otIp6Address *&aIp6AddrPtr)
{
return ReadItem(reinterpret_cast<const uint8_t **>(&aIp6AddrPtr), sizeof(spinel_ipv6addr_t));
}
otError ReadIp6Address(const uint8_t *&aIp6AddrBufPtr)
{
return ReadItem(&aIp6AddrBufPtr, sizeof(spinel_ipv6addr_t));
}
otError ReadIp6Address(spinel_ipv6addr_t &aIp6Addr);
otError ReadIp6Address(otIp6Address &aIp6Addr);
otError ReadEui64(const spinel_eui64_t *&aEui64Ptr)
{
return ReadItem(reinterpret_cast<const uint8_t **>(&aEui64Ptr), sizeof(spinel_eui64_t));
}
otError ReadEui64(const otExtAddress *&aEui64Ptr)
{
return ReadItem(reinterpret_cast<const uint8_t **>(&aEui64Ptr), sizeof(spinel_eui64_t));
}
otError ReadEui64(const uint8_t *&aEui64BufPtr) { return ReadItem(&aEui64BufPtr, sizeof(spinel_eui64_t)); }
otError ReadEui64(spinel_eui64_t &aEui64);
otError ReadEui64(otExtAddress &aEui64);
otError ReadEui48(const spinel_eui48_t *&aEui48Ptr)
{
return ReadItem(reinterpret_cast<const uint8_t **>(&aEui48Ptr), sizeof(spinel_eui48_t));
}
otError ReadEui48(const uint8_t *&aEui48BufPtr) { return ReadItem(&aEui48BufPtr, sizeof(spinel_eui48_t)); }
otError ReadEui48(spinel_eui48_t &aEui48);
otError ReadUtf8(const char *&aUtf8);
otError ReadData(const uint8_t *&aData, uint16_t &aDataLen);
otError ReadDataWithLen(const uint8_t *&aData, uint16_t &aDataLen);
otError OpenStruct(void);
otError CloseStruct(void);
uint16_t GetRemainingLengthInStruct(void) const { return mEnd - mIndex; }
bool IsAllReadInStruct(void) const { return (mIndex == mEnd); }
void SavePosition(void);
otError ResetToSaved(void);
private:
otError ReadItem(const uint8_t **aPtr, uint16_t aSize);
void ClearSavedPosition(void) { mSavedIndex = mLength; }
bool IsSavedPositionValid(void) const { return (mSavedIndex < mLength); }
const uint8_t *mFrame; uint16_t mLength; uint16_t mIndex; uint16_t mEnd; uint8_t mNumOpenStructs;
uint8_t mSavedNumOpenStructs; uint16_t mSavedIndex; uint16_t mSavedEnd;
uint16_t mPrevEnd[kMaxNestedStructs];
};
} }
#endif