Use optionals where methods may not return a valid value

This commit is contained in:
Chris Robinson 2019-06-30 16:57:10 -07:00
parent 49ceae681b
commit f458642237
2 changed files with 26 additions and 38 deletions

View File

@ -1337,7 +1337,8 @@ ALsizei ChannelsFromDevFmt(DevFmtChannels chans, ALsizei ambiorder) noexcept
return 0;
}
static ALboolean DecomposeDevFormat(ALenum format, DevFmtChannels *chans, DevFmtType *type)
struct DevFmtPair { DevFmtChannels chans; DevFmtType type; };
static al::optional<DevFmtPair> DecomposeDevFormat(ALenum format)
{
static const struct {
ALenum format;
@ -1372,14 +1373,10 @@ static ALboolean DecomposeDevFormat(ALenum format, DevFmtChannels *chans, DevFmt
for(const auto &item : list)
{
if(item.format == format)
{
*chans = item.channels;
*type = item.type;
return AL_TRUE;
}
return al::optional<DevFmtPair>{al::in_place, DevFmtPair{item.channels, item.type}};
}
return AL_FALSE;
return al::nullopt;
}
static ALCboolean IsValidALCType(ALCenum type)
@ -3975,12 +3972,16 @@ START_API_FUNC
DeviceRef device{new ALCdevice{Capture}};
device->Frequency = frequency;
if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
auto decompfmt = DecomposeDevFormat(format);
if(!decompfmt)
{
alcSetError(nullptr, ALC_INVALID_ENUM);
return nullptr;
}
device->Frequency = frequency;
device->FmtChans = decompfmt->chans;
device->FmtType = decompfmt->type;
device->Flags.set<FrequencyRequest, ChannelsRequest, SampleTypeRequest>();
device->UpdateSize = samples;

View File

@ -40,6 +40,7 @@
#include "alBuffer.h"
#include "sample_cvt.h"
#include "alexcpt.h"
#include "aloptional.h"
namespace {
@ -332,8 +333,8 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALuint freq, ALsizei size, U
ALBuf->LoopEnd = ALBuf->SampleLen;
}
using DecompResult = std::tuple<bool, UserFmtChannels, UserFmtType>;
DecompResult DecomposeUserFormat(ALenum format)
struct DecompResult { UserFmtChannels channels; UserFmtType type; };
al::optional<DecompResult> DecomposeUserFormat(ALenum format)
{
struct FormatMap {
ALenum format;
@ -398,18 +399,12 @@ DecompResult DecomposeUserFormat(ALenum format)
{ AL_FORMAT_BFORMAT3D_MULAW, UserFmtBFormat3D, UserFmtMulaw },
}};
DecompResult ret{};
for(const auto &fmt : UserFmtList)
{
if(fmt.format == format)
{
std::get<0>(ret) = true;
std::get<1>(ret) = fmt.channels;
std::get<2>(ret) = fmt.type;
break;
}
return al::optional<DecompResult>{al::in_place, DecompResult{fmt.channels, fmt.type}};
}
return ret;
return al::nullopt;
}
} // namespace
@ -551,15 +546,11 @@ START_API_FUNC
"Declaring persistently mapped storage without read or write access");
else
{
UserFmtType srctype{UserFmtUByte};
UserFmtChannels srcchannels{UserFmtMono};
bool success;
std::tie(success, srcchannels, srctype) = DecomposeUserFormat(format);
if(UNLIKELY(!success))
auto usrfmt = DecomposeUserFormat(format);
if(UNLIKELY(!usrfmt))
alSetError(context.get(), AL_INVALID_ENUM, "Invalid format 0x%04x", format);
else
LoadData(context.get(), albuf, freq, size, srcchannels, srctype,
LoadData(context.get(), albuf, freq, size, usrfmt->channels, usrfmt->type,
static_cast<const al::byte*>(data), flags);
}
}
@ -688,23 +679,19 @@ START_API_FUNC
return;
}
UserFmtType srctype{UserFmtUByte};
UserFmtChannels srcchannels{UserFmtMono};
bool success;
std::tie(success, srcchannels, srctype) = DecomposeUserFormat(format);
if(UNLIKELY(!success))
auto usrfmt = DecomposeUserFormat(format);
if(UNLIKELY(!usrfmt))
{
alSetError(context.get(), AL_INVALID_ENUM, "Invalid format 0x%04x", format);
return;
}
ALsizei unpack_align{albuf->UnpackAlign.load()};
ALsizei align{SanitizeAlignment(srctype, unpack_align)};
ALsizei align{SanitizeAlignment(usrfmt->type, unpack_align)};
if(UNLIKELY(align < 1))
alSetError(context.get(), AL_INVALID_VALUE, "Invalid unpack alignment %d", unpack_align);
else if (UNLIKELY(static_cast<long>(srcchannels) !=
static_cast<long>(albuf->mFmtChannels) ||
srctype != albuf->OriginalType))
else if(UNLIKELY(long{usrfmt->channels} != long{albuf->mFmtChannels} ||
usrfmt->type != albuf->OriginalType))
alSetError(context.get(), AL_INVALID_ENUM,
"Unpacking data with mismatched format");
else if(UNLIKELY(align != albuf->OriginalAlign))
@ -743,15 +730,15 @@ START_API_FUNC
length = length/byte_align * align;
void *dst = albuf->mData.data() + offset;
if(srctype == UserFmtIMA4 && albuf->mFmtType == FmtShort)
if(usrfmt->type == UserFmtIMA4 && albuf->mFmtType == FmtShort)
Convert_ALshort_ALima4(static_cast<ALshort*>(dst),
static_cast<const al::byte*>(data), num_chans, length, align);
else if(srctype == UserFmtMSADPCM && albuf->mFmtType == FmtShort)
else if(usrfmt->type == UserFmtMSADPCM && albuf->mFmtType == FmtShort)
Convert_ALshort_ALmsadpcm(static_cast<ALshort*>(dst),
static_cast<const al::byte*>(data), num_chans, length, align);
else
{
assert(static_cast<long>(srctype) == static_cast<long>(albuf->mFmtType));
assert(long{usrfmt->type} == static_cast<long>(albuf->mFmtType));
memcpy(dst, data, length * frame_size);
}
}