blob: d7c90bfd1c73647a6e5398312dee4a895543a267 [file] [log] [blame]
// Copyright 2021 The Pigweed 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
//
// https://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.
#pragma once
#include "pw_bytes/endian.h"
#include "pw_bytes/span.h"
#include "pw_protobuf/decoder.h"
#include "pw_result/result.h"
#include "pw_status/status.h"
#include "pw_status/try.h"
namespace pw::protobuf {
// Decodes a proto message bytes field to a uint32_t value. The caller must
// advance the decoder and check the field number prior to calling this function
// otherwise there is undefined behavior. E.g.
//
// Decoder decoder(buffer);
// protobuf::Decoder decoder(request);
// if (!decoder.Next().ok()) {
// // HANDLE ERROR.
// }
// if (static_cast<MyProtoMessage::Fields>(decoder.FieldNumber()) !=
// MyProtoMessage::Fields::MY_FIELD) {
// // HANDLE ERROR.
// }
// Result<uint32_t> result = DecodeBytesToUint32(decoder);
// if (result.ok()) {
// // DO SOMETHING WITH result.value().
// }
//
// Returns:
// OK - Byte entry is successfully read.
// DATA_LOSS: Invalid protobuf data.
// INVALID_ARGUMENT - not able to read exactly 4 bytes.
// FAILED_PRECONDITION - no bytes were read.
inline Result<uint32_t> DecodeBytesToUint32(Decoder& decoder) {
ConstByteSpan bytes_read;
PW_TRY(decoder.ReadBytes(&bytes_read));
if (bytes_read.size() != sizeof(uint32_t)) {
return Status::InvalidArgument();
}
uint32_t value;
if (!bytes::ReadInOrder(std::endian::little, bytes_read, value)) {
return Status::Internal();
}
return value;
}
} // namespace pw::protobuf