blob: 844d5883e41367a1665fa40dc35ffe47659c40b6 [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* Contains the API definition for a message buffer reader for the data
* model. This reader does the necessary bounds-checks before reading
* and updates its own state as the buffer is read.
*/
#pragma once
#include <app/util/basic-types.h>
#include <lib/core/CHIPError.h>
#include <lib/support/BufferReader.h>
#include <lib/support/CodeUtils.h>
#include <stdint.h>
namespace chip {
class DataModelReader
{
public:
/**
* Create a data model reader from a given buffer and length.
*
* @param buffer The octet buffer to read from. The caller must ensure
* (most simply by allocating the reader on the stack) that
* the buffer outlives the reader. The buffer is allowed to
* be null if buf_len is 0.
* @param buf_len The number of octets in the buffer.
*/
DataModelReader(const uint8_t * buffer, uint16_t buf_len) : mReader(buffer, buf_len) {}
/**
* Number of octets we have read so far. This might be able to go away once
* we do less switching back and forth between DataModelReader and raw
* buffers.
*/
size_t OctetsRead() const { return mReader.OctetsRead(); }
/**
* The reader status.
*/
CHIP_ERROR StatusCode() const { return mReader.StatusCode(); }
/**
* Read a cluster id.
*
* @param [out] cluster_id Where the cluster id goes.
*
* @return Whether the read succeeded. The read can fail if there are not
* enough octets available.
*/
CHECK_RETURN_VALUE DataModelReader & ReadClusterId(ClusterId * cluster_id)
{
mReader.RawRead(cluster_id);
return *this;
}
/**
* Read an endpoint id.
*
* @param [out] endpoint_id Where the endpoint id goes.
*
* @return Whether the read succeeded. The read can fail if there are not
* enough octets available.
*/
CHECK_RETURN_VALUE DataModelReader & ReadEndpointId(EndpointId * endpoint_id)
{
mReader.RawRead(endpoint_id);
return *this;
}
/**
* Read a group id.
*
* @param [out] group_id Where the group id goes.
*
* @return Whether the read succeeded. The read can fail if there are not
* enough octets available.
*/
CHECK_RETURN_VALUE DataModelReader & ReadGroupId(GroupId * group_id)
{
mReader.RawRead(group_id);
return *this;
}
/**
* Read a single octet.
*
* @param [out] octet Where the octet goes.
*
* @return Whether the read succeeded. The read can fail if there are not
* enough octets available.
*
* @note Use of APIs that read some semantically-meaningful type is preferred.
*/
CHECK_RETURN_VALUE DataModelReader & ReadOctet(uint8_t * octet)
{
mReader.RawRead(octet);
return *this;
}
/**
* Read a single 16-bit unsigned integer.
*
* @param [out] dest Where the 16-bit integer goes.
*
* @return Whether the read succeeded. The read can fail if there are not
* enough octets available.
*
* @note Use of APIs that read some semantically-meaningful type is preferred.
*/
CHECK_RETURN_VALUE DataModelReader & Read16(uint16_t * dest)
{
mReader.RawRead(dest);
return *this;
}
private:
Encoding::LittleEndian::Reader mReader;
};
} // namespace chip