Skip to content

Commit 4a2fa5e

Browse files
authored
Make WAV decoder input pointers const-correct (#32)
Update WAV decoder API to use const uint8_t* for input buffers, making it explicit that input data is not modified. Changes: - decode_header() and next() now take const uint8_t* buffers - Replaced all type-punned pointer casts with std::memcpy for reading uint16_t and uint32_t values from buffers - Added #include <cstring> for memcpy The memcpy approach eliminates strict aliasing violations and improves portability while maintaining const-correctness. This improves API safety and follows C++ best practices while maintaining full backward compatibility.
1 parent 4d1dfba commit 4a2fa5e

File tree

2 files changed

+11
-10
lines changed

2 files changed

+11
-10
lines changed

include/wav_decoder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ class WAVDecoder {
6565
uint16_t num_channels() { return this->num_channels_; }
6666
uint16_t bits_per_sample() { return this->bits_per_sample_; }
6767

68-
WAVDecoderResult decode_header(uint8_t *buffer, size_t bytes_available);
68+
WAVDecoderResult decode_header(const uint8_t *buffer, size_t bytes_available);
6969

7070
// Advance decoding:
7171
// 1. Check bytes_to_skip() first, and skip that many bytes.
7272
// 2. Read exactly bytes_needed() into the start of the buffer.
7373
// 3. Run next() and loop to 1 until the result is
7474
// WAV_DECODER_SUCCESS_IN_DATA.
7575
// 4. Use chunk_bytes_left() to read the data samples.
76-
WAVDecoderResult next(uint8_t *buffer);
76+
WAVDecoderResult next(const uint8_t *buffer);
7777

7878
void reset();
7979

src/decode/wav_decoder.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#include "wav_decoder.h"
22
#include <cstdint>
3+
#include <cstring>
34

45
namespace esp_audio_libs {
56
namespace wav_decoder {
67

7-
WAVDecoderResult WAVDecoder::decode_header(uint8_t *buffer, size_t bytes_available) {
8+
WAVDecoderResult WAVDecoder::decode_header(const uint8_t *buffer, size_t bytes_available) {
89
size_t bytes_to_skip = this->bytes_to_skip();
910
size_t bytes_to_read = this->bytes_needed();
1011
this->bytes_processed_ = 0;
@@ -44,7 +45,7 @@ WAVDecoderResult WAVDecoder::decode_header(uint8_t *buffer, size_t bytes_availab
4445
return WAV_DECODER_ERROR_FAILED;
4546
}
4647

47-
WAVDecoderResult WAVDecoder::next(uint8_t *buffer) {
48+
WAVDecoderResult WAVDecoder::next(const uint8_t *buffer) {
4849
this->bytes_to_skip_ = 0;
4950

5051
switch (this->state_) {
@@ -54,7 +55,7 @@ WAVDecoderResult WAVDecoder::next(uint8_t *buffer) {
5455
return WAV_DECODER_ERROR_NO_RIFF;
5556
}
5657

57-
this->chunk_bytes_left_ = *((uint32_t *) (buffer + 4));
58+
std::memcpy(&this->chunk_bytes_left_, buffer + 4, sizeof(uint32_t));
5859
if ((this->chunk_bytes_left_ % 2) != 0) {
5960
// Pad byte
6061
this->chunk_bytes_left_++;
@@ -80,7 +81,7 @@ WAVDecoderResult WAVDecoder::next(uint8_t *buffer) {
8081

8182
case WAV_DECODER_BEFORE_FMT: {
8283
this->chunk_name_ = std::string((const char *) buffer, 4);
83-
this->chunk_bytes_left_ = *((uint32_t *) (buffer + 4));
84+
std::memcpy(&this->chunk_bytes_left_, buffer + 4, sizeof(uint32_t));
8485
if ((this->chunk_bytes_left_ % 2) != 0) {
8586
// Pad byte
8687
this->chunk_bytes_left_++;
@@ -108,9 +109,9 @@ WAVDecoderResult WAVDecoder::next(uint8_t *buffer) {
108109
* bits per sample (uint16_t)
109110
* [rest of format chunk]
110111
*/
111-
this->num_channels_ = *((uint16_t *) (buffer + 2));
112-
this->sample_rate_ = *((uint32_t *) (buffer + 4));
113-
this->bits_per_sample_ = *((uint16_t *) (buffer + 14));
112+
std::memcpy(&this->num_channels_, buffer + 2, sizeof(uint16_t));
113+
std::memcpy(&this->sample_rate_, buffer + 4, sizeof(uint32_t));
114+
std::memcpy(&this->bits_per_sample_, buffer + 14, sizeof(uint16_t));
114115

115116
// Next chunk
116117
this->state_ = WAV_DECODER_BEFORE_DATA;
@@ -120,7 +121,7 @@ WAVDecoderResult WAVDecoder::next(uint8_t *buffer) {
120121

121122
case WAV_DECODER_BEFORE_DATA: {
122123
this->chunk_name_ = std::string((const char *) buffer, 4);
123-
this->chunk_bytes_left_ = *((uint32_t *) (buffer + 4));
124+
std::memcpy(&this->chunk_bytes_left_, buffer + 4, sizeof(uint32_t));
124125
if ((this->chunk_bytes_left_ % 2) != 0) {
125126
// Pad byte
126127
this->chunk_bytes_left_++;

0 commit comments

Comments
 (0)