mirror of https://github.com/axmolengine/axmol.git
Update thirdparty libs
This commit is contained in:
parent
09b32e26d5
commit
c44c84a1ca
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
## astc
|
## astc
|
||||||
- [![Upstream](https://img.shields.io/github/v/release/ARM-software/astc-encoder?label=Upstream)](https://github.com/ARM-software/astc-encoder)
|
- [![Upstream](https://img.shields.io/github/v/release/ARM-software/astc-encoder?label=Upstream)](https://github.com/ARM-software/astc-encoder)
|
||||||
- Version: 4.3.0
|
- Version: 4.3.1
|
||||||
- License: Apache-2.0
|
- License: Apache-2.0
|
||||||
|
|
||||||
## Box2D
|
## Box2D
|
||||||
|
@ -21,13 +21,13 @@
|
||||||
|
|
||||||
## Bullet
|
## Bullet
|
||||||
- [![Upstream](https://img.shields.io/github/v/release/bulletphysics/bullet3?label=Upstream)](https://github.com/bulletphysics/bullet3)
|
- [![Upstream](https://img.shields.io/github/v/release/bulletphysics/bullet3?label=Upstream)](https://github.com/bulletphysics/bullet3)
|
||||||
- Version: 3.24
|
- Version: 3.25
|
||||||
- License: zlib
|
- License: zlib
|
||||||
- Update method: Compare `axmol/thirdparty/bullet` with `bullet3/src`
|
- Update method: Compare `axmol/thirdparty/bullet` with `bullet3/src`
|
||||||
|
|
||||||
## c-ares
|
## c-ares
|
||||||
- [![Upstream](https://img.shields.io/github/v/release/c-ares/c-ares?label=Upstream)](https://github.com/c-ares/c-ares)
|
- [![Upstream](https://img.shields.io/github/v/release/c-ares/c-ares?label=Upstream)](https://github.com/c-ares/c-ares)
|
||||||
- Version: git 1.18.1-c25d4eb (2138)
|
- Version: git 1.19.0-bb8f5bb (2184)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
## Chipmunk2D
|
## Chipmunk2D
|
||||||
|
@ -161,7 +161,7 @@
|
||||||
|
|
||||||
## OpenAL Soft
|
## OpenAL Soft
|
||||||
- [![Upstream](https://img.shields.io/github/v/tag/kcat/openal-soft?label=Upstream)](https://github.com/kcat/openal-soft)
|
- [![Upstream](https://img.shields.io/github/v/tag/kcat/openal-soft?label=Upstream)](https://github.com/kcat/openal-soft)
|
||||||
- Version: 1.22.2
|
- Version: 1.23.0
|
||||||
- License: LGPL-2.1
|
- License: LGPL-2.1
|
||||||
|
|
||||||
## OpenSSL
|
## OpenSSL
|
||||||
|
@ -180,8 +180,10 @@
|
||||||
- License: BSD-3-Clause
|
- License: BSD-3-Clause
|
||||||
|
|
||||||
## pugixml
|
## pugixml
|
||||||
- [![Upstream](https://img.shields.io/github/v/tag/zeux/pugixml?label=Upstream)](https://github.com/zeux/pugixml)
|
- [![Upstream](https://img.shields.io/github/v/tag/halx99/pugixml?label=Upstream)](https://github.com/halx99/pugixml) by halx99 for string_view support
|
||||||
- Version: 1.12.1
|
- original repo: https://github.com/zeux/pugixml
|
||||||
|
- all tests passed: https://github.com/halx99/pugixml/actions/runs/4090401630
|
||||||
|
- Version: 1.13
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
## rapidjson
|
## rapidjson
|
||||||
|
@ -203,7 +205,7 @@
|
||||||
|
|
||||||
## stb (stb_image)
|
## stb (stb_image)
|
||||||
- Upstream: https://github.com/nothings/stb
|
- Upstream: https://github.com/nothings/stb
|
||||||
- Version: 2.27
|
- Version: 2.28
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
## unzip (minizip-1.2)
|
## unzip (minizip-1.2)
|
||||||
|
@ -218,7 +220,7 @@
|
||||||
|
|
||||||
## webp
|
## webp
|
||||||
- [![Upstream](https://img.shields.io/github/v/tag/webmproject/libwebp?label=Upstream)](https://github.com/webmproject/libwebp)
|
- [![Upstream](https://img.shields.io/github/v/tag/webmproject/libwebp?label=Upstream)](https://github.com/webmproject/libwebp)
|
||||||
- Version: 1.2.4
|
- Version: 1.3.0
|
||||||
- License: Google Inc
|
- License: Google Inc
|
||||||
|
|
||||||
## xsbase
|
## xsbase
|
||||||
|
@ -248,7 +250,7 @@
|
||||||
|
|
||||||
## ntcvt
|
## ntcvt
|
||||||
- [![Upstream](https://img.shields.io/github/v/tag/simdsoft/ntcvt?label=Upstream)](https://github.com/simdsoft/ntcvt)
|
- [![Upstream](https://img.shields.io/github/v/tag/simdsoft/ntcvt?label=Upstream)](https://github.com/simdsoft/ntcvt)
|
||||||
- Version: git-8422188 (7)
|
- Version: 0.0.2
|
||||||
- License: Apache-2.0
|
- License: Apache-2.0
|
||||||
|
|
||||||
## Some third party libs supporting axmol too:
|
## Some third party libs supporting axmol too:
|
||||||
|
|
|
@ -48,8 +48,6 @@
|
||||||
#define ASTCENC_SSE 42
|
#define ASTCENC_SSE 42
|
||||||
#elif defined(__SSE4_1__)
|
#elif defined(__SSE4_1__)
|
||||||
#define ASTCENC_SSE 41
|
#define ASTCENC_SSE 41
|
||||||
#elif defined(__SSE3__)
|
|
||||||
#define ASTCENC_SSE 30
|
|
||||||
#elif defined(__SSE2__)
|
#elif defined(__SSE2__)
|
||||||
#define ASTCENC_SSE 20
|
#define ASTCENC_SSE 20
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1046,7 +1046,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4& t0p)
|
||||||
*/
|
*/
|
||||||
ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p)
|
ASTCENC_SIMD_INLINE void vtable_prepare(vint4 t0, vint4 t1, vint4& t0p, vint4& t1p)
|
||||||
{
|
{
|
||||||
#if ASTCENC_SSE >= 30
|
#if ASTCENC_SSE >= 41
|
||||||
t0p = t0;
|
t0p = t0;
|
||||||
t1p = t0 ^ t1;
|
t1p = t0 ^ t1;
|
||||||
#else
|
#else
|
||||||
|
@ -1062,7 +1062,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(
|
||||||
vint4 t0, vint4 t1, vint4 t2, vint4 t3,
|
vint4 t0, vint4 t1, vint4 t2, vint4 t3,
|
||||||
vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p)
|
vint4& t0p, vint4& t1p, vint4& t2p, vint4& t3p)
|
||||||
{
|
{
|
||||||
#if ASTCENC_SSE >= 30
|
#if ASTCENC_SSE >= 41
|
||||||
t0p = t0;
|
t0p = t0;
|
||||||
t1p = t0 ^ t1;
|
t1p = t0 ^ t1;
|
||||||
t2p = t1 ^ t2;
|
t2p = t1 ^ t2;
|
||||||
|
@ -1080,7 +1080,7 @@ ASTCENC_SIMD_INLINE void vtable_prepare(
|
||||||
*/
|
*/
|
||||||
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
|
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
|
||||||
{
|
{
|
||||||
#if ASTCENC_SSE >= 30
|
#if ASTCENC_SSE >= 41
|
||||||
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
|
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
|
||||||
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
|
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
|
||||||
|
|
||||||
|
@ -1102,7 +1102,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 idx)
|
||||||
*/
|
*/
|
||||||
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
|
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
|
||||||
{
|
{
|
||||||
#if ASTCENC_SSE >= 30
|
#if ASTCENC_SSE >= 41
|
||||||
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
|
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
|
||||||
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
|
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
|
||||||
|
|
||||||
|
@ -1130,7 +1130,7 @@ ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 idx)
|
||||||
*/
|
*/
|
||||||
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx)
|
ASTCENC_SIMD_INLINE vint4 vtable_8bt_32bi(vint4 t0, vint4 t1, vint4 t2, vint4 t3, vint4 idx)
|
||||||
{
|
{
|
||||||
#if ASTCENC_SSE >= 30
|
#if ASTCENC_SSE >= 41
|
||||||
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
|
// Set index byte MSB to 1 for unused bytes so shuffle returns zero
|
||||||
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
|
__m128i idxx = _mm_or_si128(idx.m, _mm_set1_epi32(static_cast<int>(0xFFFFFF00)));
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,8 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle, int partId,
|
||||||
|
|
||||||
if (m_convexBodyWrap->getCollisionShape()->isConvex())
|
if (m_convexBodyWrap->getCollisionShape()->isConvex())
|
||||||
{
|
{
|
||||||
#ifndef BT_DISABLE_CONVEX_CONCAVE_EARLY_OUT
|
#ifdef BT_ENABLE_CONVEX_CONCAVE_EARLY_OUT
|
||||||
|
//todo: check this issue https://github.com/bulletphysics/bullet3/issues/4263
|
||||||
//an early out optimisation if the object is separated from the triangle
|
//an early out optimisation if the object is separated from the triangle
|
||||||
//projected on the triangle normal)
|
//projected on the triangle normal)
|
||||||
{
|
{
|
||||||
|
@ -139,7 +140,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle, int partId,
|
||||||
if (dist > contact_threshold)
|
if (dist > contact_threshold)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif //BT_DISABLE_CONVEX_CONCAVE_EARLY_OUT
|
#endif //BT_ENABLE_CONVEX_CONCAVE_EARLY_OUT
|
||||||
|
|
||||||
btTriangleShape tm(triangle[0], triangle[1], triangle[2]);
|
btTriangleShape tm(triangle[0], triangle[1], triangle[2]);
|
||||||
tm.setMargin(m_collisionMarginTriangle);
|
tm.setMargin(m_collisionMarginTriangle);
|
||||||
|
|
|
@ -229,10 +229,12 @@ public:
|
||||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||||
|
m_min[3] = 0.f;
|
||||||
|
|
||||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||||
|
m_max[3] = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
btAABB(const btVector3 &V1,
|
btAABB(const btVector3 &V1,
|
||||||
|
@ -243,10 +245,12 @@ public:
|
||||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||||
|
m_min[3] = 0.f;
|
||||||
|
|
||||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||||
|
m_max[3] = 0.f;
|
||||||
|
|
||||||
m_min[0] -= margin;
|
m_min[0] -= margin;
|
||||||
m_min[1] -= margin;
|
m_min[1] -= margin;
|
||||||
|
@ -275,9 +279,11 @@ public:
|
||||||
m_min[0] = SIMD_INFINITY;
|
m_min[0] = SIMD_INFINITY;
|
||||||
m_min[1] = SIMD_INFINITY;
|
m_min[1] = SIMD_INFINITY;
|
||||||
m_min[2] = SIMD_INFINITY;
|
m_min[2] = SIMD_INFINITY;
|
||||||
|
m_min[3] = 0.f;
|
||||||
m_max[0] = -SIMD_INFINITY;
|
m_max[0] = -SIMD_INFINITY;
|
||||||
m_max[1] = -SIMD_INFINITY;
|
m_max[1] = -SIMD_INFINITY;
|
||||||
m_max[2] = -SIMD_INFINITY;
|
m_max[2] = -SIMD_INFINITY;
|
||||||
|
m_max[3] = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIMD_FORCE_INLINE void increment_margin(btScalar margin)
|
SIMD_FORCE_INLINE void increment_margin(btScalar margin)
|
||||||
|
@ -295,10 +301,12 @@ public:
|
||||||
m_min[0] = other.m_min[0] - margin;
|
m_min[0] = other.m_min[0] - margin;
|
||||||
m_min[1] = other.m_min[1] - margin;
|
m_min[1] = other.m_min[1] - margin;
|
||||||
m_min[2] = other.m_min[2] - margin;
|
m_min[2] = other.m_min[2] - margin;
|
||||||
|
m_min[3] = 0.f;
|
||||||
|
|
||||||
m_max[0] = other.m_max[0] + margin;
|
m_max[0] = other.m_max[0] + margin;
|
||||||
m_max[1] = other.m_max[1] + margin;
|
m_max[1] = other.m_max[1] + margin;
|
||||||
m_max[2] = other.m_max[2] + margin;
|
m_max[2] = other.m_max[2] + margin;
|
||||||
|
m_max[3] = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CLASS_POINT>
|
template <typename CLASS_POINT>
|
||||||
|
@ -310,10 +318,12 @@ public:
|
||||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||||
|
m_min[3] = 0.f;
|
||||||
|
|
||||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||||
|
m_max[3] = 0.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename CLASS_POINT>
|
template <typename CLASS_POINT>
|
||||||
|
@ -325,10 +335,12 @@ public:
|
||||||
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]);
|
||||||
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]);
|
||||||
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]);
|
||||||
|
m_min[3] = 0.f;
|
||||||
|
|
||||||
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]);
|
||||||
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]);
|
||||||
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]);
|
||||||
|
m_max[3] = 0.f;
|
||||||
|
|
||||||
m_min[0] -= margin;
|
m_min[0] -= margin;
|
||||||
m_min[1] -= margin;
|
m_min[1] -= margin;
|
||||||
|
|
|
@ -4,8 +4,8 @@ Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied warranty.
|
This software is provided 'as-is', without any express or implied warranty.
|
||||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
including commercial applications, and to alter it and redistribute it freely,
|
including commercial applications, and to alter it and redistribute it freely,
|
||||||
subject to the following restrictions:
|
subject to the following restrictions:
|
||||||
|
|
||||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||||
|
@ -19,8 +19,10 @@ subject to the following restrictions:
|
||||||
#include "btPointCollector.h"
|
#include "btPointCollector.h"
|
||||||
#include "LinearMath/btTransformUtil.h"
|
#include "LinearMath/btTransformUtil.h"
|
||||||
|
|
||||||
#ifdef MAX_ITERATIONS
|
#ifdef BT_USE_DOUBLE_PRECISION
|
||||||
#define MAX_ITERATIONS 64
|
#define MAX_ITERATIONS 64
|
||||||
|
#else
|
||||||
|
#define MAX_ITERATIONS 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA, const btConvexShape* convexB, btSimplexSolverInterface* simplexSolver)
|
btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA, const btConvexShape* convexB, btSimplexSolverInterface* simplexSolver)
|
||||||
|
|
|
@ -71,8 +71,8 @@ public:
|
||||||
const btVector3& normal,
|
const btVector3& normal,
|
||||||
btScalar distance) : m_localPointA(pointA),
|
btScalar distance) : m_localPointA(pointA),
|
||||||
m_localPointB(pointB),
|
m_localPointB(pointB),
|
||||||
m_positionWorldOnB(0,0,0),
|
m_positionWorldOnB(0,0,0),
|
||||||
m_positionWorldOnA(0,0,0),
|
m_positionWorldOnA(0,0,0),
|
||||||
m_normalWorldOnB(normal),
|
m_normalWorldOnB(normal),
|
||||||
m_distance1(distance),
|
m_distance1(distance),
|
||||||
m_combinedFriction(btScalar(0.)),
|
m_combinedFriction(btScalar(0.)),
|
||||||
|
@ -95,8 +95,8 @@ public:
|
||||||
m_contactERP(0.f),
|
m_contactERP(0.f),
|
||||||
m_frictionCFM(0.f),
|
m_frictionCFM(0.f),
|
||||||
m_lifeTime(0),
|
m_lifeTime(0),
|
||||||
m_lateralFrictionDir1(0,0,0),
|
m_lateralFrictionDir1(0,0,0),
|
||||||
m_lateralFrictionDir2(0,0,0)
|
m_lateralFrictionDir2(0,0,0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,9 +169,12 @@ btVectorXu btLemkeAlgorithm::solve(unsigned int maxloops /* = 0*/)
|
||||||
|
|
||||||
/*the column becomes part of the basis*/
|
/*the column becomes part of the basis*/
|
||||||
basis[pivotRowIndex] = pivotColIndexOld;
|
basis[pivotRowIndex] = pivotColIndexOld;
|
||||||
|
bool isRayTermination = false;
|
||||||
pivotRowIndex = findLexicographicMinimum(A, pivotColIndex);
|
pivotRowIndex = findLexicographicMinimum(A, pivotColIndex, z0Row, isRayTermination);
|
||||||
|
if (isRayTermination)
|
||||||
|
{
|
||||||
|
break; // ray termination
|
||||||
|
}
|
||||||
if (z0Row == pivotRowIndex)
|
if (z0Row == pivotRowIndex)
|
||||||
{ //if z0 leaves the basis the solution is found --> one last elimination step is necessary
|
{ //if z0 leaves the basis the solution is found --> one last elimination step is necessary
|
||||||
GaussJordanEliminationStep(A, pivotRowIndex, pivotColIndex, basis);
|
GaussJordanEliminationStep(A, pivotRowIndex, pivotColIndex, basis);
|
||||||
|
@ -217,79 +220,100 @@ btVectorXu btLemkeAlgorithm::solve(unsigned int maxloops /* = 0*/)
|
||||||
return solutionVector;
|
return solutionVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
int btLemkeAlgorithm::findLexicographicMinimum(const btMatrixXu& A, const int& pivotColIndex)
|
int btLemkeAlgorithm::findLexicographicMinimum(const btMatrixXu& A, const int& pivotColIndex, const int& z0Row, bool& isRayTermination)
|
||||||
{
|
{
|
||||||
int RowIndex = 0;
|
isRayTermination = false;
|
||||||
|
btAlignedObjectArray<int> activeRows;
|
||||||
|
|
||||||
|
bool firstRow = true;
|
||||||
|
btScalar currentMin = 0.0;
|
||||||
|
|
||||||
int dim = A.rows();
|
int dim = A.rows();
|
||||||
btAlignedObjectArray<btVectorXu> Rows;
|
|
||||||
for (int row = 0; row < dim; row++)
|
for (int row = 0; row < dim; row++)
|
||||||
{
|
{
|
||||||
btVectorXu vec(dim + 1);
|
const btScalar denom = A(row, pivotColIndex);
|
||||||
vec.setZero(); //, INIT, 0.)
|
|
||||||
Rows.push_back(vec);
|
|
||||||
btScalar a = A(row, pivotColIndex);
|
|
||||||
if (a > 0)
|
|
||||||
{
|
|
||||||
Rows[row][0] = A(row, 2 * dim + 1) / a;
|
|
||||||
Rows[row][1] = A(row, 2 * dim) / a;
|
|
||||||
for (int j = 2; j < dim + 1; j++)
|
|
||||||
Rows[row][j] = A(row, j - 1) / a;
|
|
||||||
|
|
||||||
#ifdef BT_DEBUG_OSTREAM
|
if (denom > btMachEps())
|
||||||
// if (DEBUGLEVEL) {
|
{
|
||||||
// cout << "Rows(" << row << ") = " << Rows[row] << endl;
|
const btScalar q = A(row, dim + dim + 1) / denom;
|
||||||
// }
|
if (firstRow)
|
||||||
#endif
|
{
|
||||||
|
currentMin = q;
|
||||||
|
activeRows.push_back(row);
|
||||||
|
firstRow = false;
|
||||||
|
}
|
||||||
|
else if (fabs(currentMin - q) < btMachEps())
|
||||||
|
{
|
||||||
|
activeRows.push_back(row);
|
||||||
|
}
|
||||||
|
else if (currentMin > q)
|
||||||
|
{
|
||||||
|
currentMin = q;
|
||||||
|
activeRows.clear();
|
||||||
|
activeRows.push_back(row);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < Rows.size(); i++)
|
if (activeRows.size() == 0)
|
||||||
{
|
{
|
||||||
if (Rows[i].nrm2() > 0.)
|
isRayTermination = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (activeRows.size() == 1)
|
||||||
|
{
|
||||||
|
return activeRows[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there are multiple rows, check if they contain the row for z_0.
|
||||||
|
for (int i = 0; i < activeRows.size(); i++)
|
||||||
|
{
|
||||||
|
if (activeRows[i] == z0Row)
|
||||||
{
|
{
|
||||||
int j = 0;
|
return z0Row;
|
||||||
for (; j < Rows.size(); j++)
|
|
||||||
{
|
|
||||||
if (i != j)
|
|
||||||
{
|
|
||||||
if (Rows[j].nrm2() > 0.)
|
|
||||||
{
|
|
||||||
btVectorXu test(dim + 1);
|
|
||||||
for (int ii = 0; ii < dim + 1; ii++)
|
|
||||||
{
|
|
||||||
test[ii] = Rows[j][ii] - Rows[i][ii];
|
|
||||||
}
|
|
||||||
|
|
||||||
//=Rows[j] - Rows[i]
|
|
||||||
if (!LexicographicPositive(test))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == Rows.size())
|
|
||||||
{
|
|
||||||
RowIndex += i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RowIndex;
|
// look through the columns of the inverse of the basic matrix from left to right until the tie is broken.
|
||||||
}
|
for (int col = 0; col < dim ; col++)
|
||||||
|
{
|
||||||
|
btAlignedObjectArray<int> activeRowsCopy(activeRows);
|
||||||
|
activeRows.clear();
|
||||||
|
firstRow = true;
|
||||||
|
for (int i = 0; i<activeRowsCopy.size();i++)
|
||||||
|
{
|
||||||
|
const int row = activeRowsCopy[i];
|
||||||
|
|
||||||
bool btLemkeAlgorithm::LexicographicPositive(const btVectorXu& v)
|
// denom is positive here as an invariant.
|
||||||
{
|
const btScalar denom = A(row, pivotColIndex);
|
||||||
int i = 0;
|
const btScalar ratio = A(row, col) / denom;
|
||||||
// if (DEBUGLEVEL)
|
if (firstRow)
|
||||||
// cout << "v " << v << endl;
|
{
|
||||||
|
currentMin = ratio;
|
||||||
|
activeRows.push_back(row);
|
||||||
|
firstRow = false;
|
||||||
|
}
|
||||||
|
else if (fabs(currentMin - ratio) < btMachEps())
|
||||||
|
{
|
||||||
|
activeRows.push_back(row);
|
||||||
|
}
|
||||||
|
else if (currentMin > ratio)
|
||||||
|
{
|
||||||
|
currentMin = ratio;
|
||||||
|
activeRows.clear();
|
||||||
|
activeRows.push_back(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (i < v.size() - 1 && fabs(v[i]) < btMachEps())
|
if (activeRows.size() == 1)
|
||||||
i++;
|
{
|
||||||
if (v[i] > 0)
|
return activeRows[0];
|
||||||
return true;
|
}
|
||||||
|
}
|
||||||
return false;
|
// must not reach here.
|
||||||
|
isRayTermination = true;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void btLemkeAlgorithm::GaussJordanEliminationStep(btMatrixXu& A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray<int>& basis)
|
void btLemkeAlgorithm::GaussJordanEliminationStep(btMatrixXu& A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray<int>& basis)
|
||||||
|
|
|
@ -71,8 +71,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int findLexicographicMinimum(const btMatrixXu& A, const int& pivotColIndex);
|
int findLexicographicMinimum(const btMatrixXu& A, const int& pivotColIndex, const int& z0Row, bool& isRayTermination);
|
||||||
bool LexicographicPositive(const btVectorXu& v);
|
|
||||||
void GaussJordanEliminationStep(btMatrixXu& A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray<int>& basis);
|
void GaussJordanEliminationStep(btMatrixXu& A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray<int>& basis);
|
||||||
bool greaterZero(const btVectorXu& vector);
|
bool greaterZero(const btVectorXu& vector);
|
||||||
bool validBasis(const btAlignedObjectArray<int>& basis);
|
bool validBasis(const btAlignedObjectArray<int>& basis);
|
||||||
|
|
|
@ -678,7 +678,9 @@ HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // describes the
|
||||||
if (vcount < 8) vcount = 8;
|
if (vcount < 8) vcount = 8;
|
||||||
|
|
||||||
btAlignedObjectArray<btVector3> vertexSource;
|
btAlignedObjectArray<btVector3> vertexSource;
|
||||||
vertexSource.resize(static_cast<int>(vcount));
|
btVector3 zero;
|
||||||
|
zero.setZero();
|
||||||
|
vertexSource.resize(static_cast<int>(vcount), zero);
|
||||||
|
|
||||||
btVector3 scale;
|
btVector3 scale;
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ subject to the following restrictions:
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
|
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
|
||||||
#define BT_BULLET_VERSION 324
|
#define BT_BULLET_VERSION 325
|
||||||
|
|
||||||
inline int btGetVersion()
|
inline int btGetVersion()
|
||||||
{
|
{
|
||||||
|
|
|
@ -481,7 +481,7 @@ public:
|
||||||
|
|
||||||
buffer[9] = '3';
|
buffer[9] = '3';
|
||||||
buffer[10] = '2';
|
buffer[10] = '2';
|
||||||
buffer[11] = '4';
|
buffer[11] = '5';
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void startSerialization()
|
virtual void startSerialization()
|
||||||
|
@ -512,7 +512,7 @@ public:
|
||||||
currentPtr += BT_HEADER_LENGTH;
|
currentPtr += BT_HEADER_LENGTH;
|
||||||
for (int i = 0; i < m_chunkPtrs.size(); i++)
|
for (int i = 0; i < m_chunkPtrs.size(); i++)
|
||||||
{
|
{
|
||||||
int curLength = sizeof(btChunk) + m_chunkPtrs[i]->m_length;
|
int curLength = (int)sizeof(btChunk) + m_chunkPtrs[i]->m_length;
|
||||||
memcpy(currentPtr, m_chunkPtrs[i], curLength);
|
memcpy(currentPtr, m_chunkPtrs[i], curLength);
|
||||||
btAlignedFree(m_chunkPtrs[i]);
|
btAlignedFree(m_chunkPtrs[i]);
|
||||||
currentPtr += curLength;
|
currentPtr += curLength;
|
||||||
|
|
|
@ -8,7 +8,7 @@ INCLUDE (CheckCSourceCompiles)
|
||||||
INCLUDE (CheckStructHasMember)
|
INCLUDE (CheckStructHasMember)
|
||||||
INCLUDE (CheckLibraryExists)
|
INCLUDE (CheckLibraryExists)
|
||||||
|
|
||||||
PROJECT (c-ares LANGUAGES C VERSION "1.18.0" )
|
PROJECT (c-ares LANGUAGES C VERSION "1.19.0" )
|
||||||
|
|
||||||
# Set this version before release
|
# Set this version before release
|
||||||
SET (CARES_VERSION "${PROJECT_VERSION}")
|
SET (CARES_VERSION "${PROJECT_VERSION}")
|
||||||
|
@ -26,7 +26,7 @@ INCLUDE (GNUInstallDirs) # include this *AFTER* PROJECT(), otherwise paths are w
|
||||||
# For example, a version of 4:0:2 would generate output such as:
|
# For example, a version of 4:0:2 would generate output such as:
|
||||||
# libname.so -> libname.so.2
|
# libname.so -> libname.so.2
|
||||||
# libname.so.2 -> libname.so.2.2.0
|
# libname.so.2 -> libname.so.2.2.0
|
||||||
SET (CARES_LIB_VERSIONINFO "7:1:5")
|
SET (CARES_LIB_VERSIONINFO "8:0:6")
|
||||||
|
|
||||||
|
|
||||||
OPTION (CARES_STATIC "Build as a static library" OFF)
|
OPTION (CARES_STATIC "Build as a static library" OFF)
|
||||||
|
@ -82,9 +82,14 @@ SET (TARGETS_INST_DEST
|
||||||
|
|
||||||
# Function in Library
|
# Function in Library
|
||||||
# CHECK_LIBRARY_EXISTS can't be used as it will return true if the function
|
# CHECK_LIBRARY_EXISTS can't be used as it will return true if the function
|
||||||
# is found in a different dependent library.
|
# is found in a different required/dependent library.
|
||||||
MACRO (CARES_FUNCTION_IN_LIBRARY func lib var)
|
MACRO (CARES_FUNCTION_IN_LIBRARY func lib var)
|
||||||
|
|
||||||
|
SET (_ORIG_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
|
||||||
|
SET (CMAKE_REQUIRED_LIBRARIES )
|
||||||
CHECK_FUNCTION_EXISTS ("${func}" "_CARES_FUNC_IN_LIB_GLOBAL_${func}")
|
CHECK_FUNCTION_EXISTS ("${func}" "_CARES_FUNC_IN_LIB_GLOBAL_${func}")
|
||||||
|
SET (CMAKE_REQUIRED_LIBRARIES "${_ORIG_CMAKE_REQUIRED_LIBRARIES}")
|
||||||
|
|
||||||
IF ("${_CARES_FUNC_IN_LIB_GLOBAL_${func}}")
|
IF ("${_CARES_FUNC_IN_LIB_GLOBAL_${func}}")
|
||||||
SET (${var} FALSE)
|
SET (${var} FALSE)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
|
@ -689,6 +694,12 @@ IF (CARES_INSTALL)
|
||||||
if( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
|
if( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" )
|
||||||
|
|
||||||
if ( "${CPACK_PACKAGE_ARCHITECTURE}" STREQUAL "" )
|
if ( "${CPACK_PACKAGE_ARCHITECTURE}" STREQUAL "" )
|
||||||
|
set( CPACK_PACKAGE_ARCHITECTURE "${CMAKE_SYSTEM_PROCESSOR}" )
|
||||||
|
endif()
|
||||||
|
if ( "${CPACK_PACKAGE_ARCHITECTURE}" STREQUAL "" )
|
||||||
|
if ( "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows" )
|
||||||
|
message( FATAL_ERROR "Failed to determine CPACK_PACKAGE_ARCHITECTURE. Is CMAKE_SYSTEM_PROCESSOR set?" )
|
||||||
|
endif()
|
||||||
# Note: the architecture should default to the local architecture, but it
|
# Note: the architecture should default to the local architecture, but it
|
||||||
# in fact comes up empty. We call `uname -m` to ask the kernel instead.
|
# in fact comes up empty. We call `uname -m` to ask the kernel instead.
|
||||||
EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE )
|
EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE )
|
||||||
|
|
|
@ -3,7 +3,7 @@ c-ares
|
||||||
|
|
||||||
[![Build Status](https://api.cirrus-ci.com/github/c-ares/c-ares.svg)](https://cirrus-ci.com/github/c-ares/c-ares)
|
[![Build Status](https://api.cirrus-ci.com/github/c-ares/c-ares.svg)](https://cirrus-ci.com/github/c-ares/c-ares)
|
||||||
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/aevgc5914tm72pvs/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares/branch/master)
|
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/aevgc5914tm72pvs/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares/branch/master)
|
||||||
[![Coverage Status](https://coveralls.io/repos/c-ares/c-ares/badge.svg?branch=master&service=github)](https://coveralls.io/github/c-ares/c-ares?branch=master)
|
[![Coverage Status](https://coveralls.io/repos/github/c-ares/c-ares/badge.svg)](https://coveralls.io/github/c-ares/c-ares)
|
||||||
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/291/badge)](https://bestpractices.coreinfrastructure.org/projects/291)
|
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/291/badge)](https://bestpractices.coreinfrastructure.org/projects/291)
|
||||||
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/c-ares.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:c-ares)
|
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/c-ares.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:c-ares)
|
||||||
[![Releases](https://coderelease.io/badge/c-ares/c-ares)](https://coderelease.io/github/repository/c-ares/c-ares)
|
[![Releases](https://coderelease.io/badge/c-ares/c-ares)](https://coderelease.io/github/repository/c-ares/c-ares)
|
||||||
|
|
|
@ -17,7 +17,7 @@ This utility comes with the \fBc\-ares\fR asynchronous resolver library.
|
||||||
\fB\-d\fR
|
\fB\-d\fR
|
||||||
Print some extra debugging output.
|
Print some extra debugging output.
|
||||||
.TP
|
.TP
|
||||||
\fB\-h\fR, \fB\-\-help\fR
|
\fB\-h\fR, \fB\-?\fR
|
||||||
Display this help and exit.
|
Display this help and exit.
|
||||||
.TP
|
.TP
|
||||||
\fB\-v\fR
|
\fB\-v\fR
|
||||||
|
|
|
@ -18,34 +18,40 @@ This utility comes with the \fBc\-ares\fR asynchronous resolver library.
|
||||||
\fB\-c\fR class
|
\fB\-c\fR class
|
||||||
Set the query class.
|
Set the query class.
|
||||||
Possible values for class are
|
Possible values for class are
|
||||||
NY, CHAOS, HS, IN (default).
|
ANY, CHAOS, HS and IN (default).
|
||||||
.TP
|
.TP
|
||||||
\fB\-d\fR
|
\fB\-d\fR
|
||||||
Print some extra debugging output.
|
Print some extra debugging output.
|
||||||
.TP
|
.TP
|
||||||
\fB\-f\fR flag
|
\fB\-f\fR flag
|
||||||
Add a flag.
|
Add a behavior control flag.
|
||||||
Possible values for flag are
|
Possible values for flag are
|
||||||
igntc, noaliases, norecurse, primary, stayopen, usevc.
|
igntc - ignore to query in TCP to get truncated UDP answer,
|
||||||
|
noaliases - don't honor the HOSTALIASES environment variable,
|
||||||
|
norecurse - don't query upstream servers recursively,
|
||||||
|
primary - use the first server,
|
||||||
|
stayopen - don't close the communication sockets, and
|
||||||
|
usevc - always use TCP.
|
||||||
.TP
|
.TP
|
||||||
\fB\-h\fR, \fB\-\-help\fR
|
\fB\-h\fR, \fB\-?\fR
|
||||||
Display this help and exit.
|
Display this help and exit.
|
||||||
.TP
|
.TP
|
||||||
\fB\-T\fR port
|
|
||||||
Use specified TCP port to connect to DNS server.
|
|
||||||
.TP
|
|
||||||
\fB\-s\fR server
|
\fB\-s\fR server
|
||||||
Connect to specified DNS server, instead of the system's default one(s).
|
Connect to specified DNS server, instead of the system's default one(s).
|
||||||
|
Servers are tried in round-robin, if the previous one failed.
|
||||||
.TP
|
.TP
|
||||||
\fB\-t\fR type
|
\fB\-t\fR type
|
||||||
Query records of specified type.
|
Query records of specified type.
|
||||||
Possible values for type are
|
Possible values for type are
|
||||||
A (default), AAAA, AFSDB, ANY, AXFR, CNAME, GPOS, HINFO, ISDN, KEY, LOC, MAILA,
|
A (default), AAAA, AFSDB, ANY, AXFR, CNAME, GPOS, HINFO, ISDN, KEY, LOC, MAILA,
|
||||||
MAILB, MB, MD, MF, MG, MINFO, MR, MX, NAPTR, NS, NSAP, NSAP_PTR, NULL,
|
MAILB, MB, MD, MF, MG, MINFO, MR, MX, NAPTR, NS, NSAP, NSAP_PTR, NULL,
|
||||||
PTR, PX, RP, RT, SIG, SOA, SRV, TXT, URI, WKS, X25,
|
PTR, PX, RP, RT, SIG, SOA, SRV, TXT, URI, WKS and X25.
|
||||||
|
.TP
|
||||||
|
\fB\-T\fR port
|
||||||
|
Connect to the specified TCP port of DNS server.
|
||||||
.TP
|
.TP
|
||||||
\fB\-U\fR port
|
\fB\-U\fR port
|
||||||
Use specified UDP port to connect to DNS server.
|
Connect to the specified UDP port of DNS server.
|
||||||
.TP
|
.TP
|
||||||
\fB\-x\fR
|
\fB\-x\fR
|
||||||
For an IPv4 \fB-t PTR a.b.c.d\fR lookup, query for
|
For an IPv4 \fB-t PTR a.b.c.d\fR lookup, query for
|
||||||
|
|
|
@ -17,7 +17,7 @@ This utility comes with the \fBc\-ares\fR asynchronous resolver library.
|
||||||
\fB\-d\fR
|
\fB\-d\fR
|
||||||
Print some extra debugging output.
|
Print some extra debugging output.
|
||||||
.TP
|
.TP
|
||||||
\fB\-h\fR, \fB\-\-help\fR
|
\fB\-h\fR, \fB\-?\fR
|
||||||
Display this help and exit.
|
Display this help and exit.
|
||||||
.TP
|
.TP
|
||||||
\fB\-t\fR type
|
\fB\-t\fR type
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_destroy_options \- Destroy options initialized with ares_save_options
|
ares_destroy_options \- Destroy options initialized with ares_save_options
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B void ares_destroy_options(struct ares_options *\fIoptions\fP)
|
void ares_destroy_options(struct ares_options *\fIoptions\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_destroy_options(3)\fP function destroys the options struct
|
The \fBares_destroy_options(3)\fP function destroys the options struct
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_dup \- Duplicate a resolver channel
|
ares_dup \- Duplicate a resolver channel
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_dup(ares_channel *\fIdest\fP, ares_channel \fIsource\fP)
|
int ares_dup(ares_channel *\fIdest\fP, ares_channel \fIsource\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_dup(3)\fP function duplicates an existing communications channel
|
The \fBares_dup(3)\fP function duplicates an existing communications channel
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
ares_expand_name \- Expand a DNS-encoded domain name
|
ares_expand_name \- Expand a DNS-encoded domain name
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_expand_name(const unsigned char *\fIencoded\fP,
|
int ares_expand_name(const unsigned char *\fIencoded\fP,
|
||||||
.B const unsigned char *\fIabuf\fP, int \fIalen\fP, char **\fIs\fP,
|
const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B long *\fIenclen\fP)
|
char **\fIs\fP, long *\fIenclen\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
ares_expand_string \- Expand a length encoded string
|
ares_expand_string \- Expand a length encoded string
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_expand_string(const unsigned char *\fIencoded\fP,
|
int ares_expand_string(const unsigned char *\fIencoded\fP,
|
||||||
.B const unsigned char *\fIabuf\fP, int \fIalen\fP, unsigned char **\fIs\fP,
|
const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B long *\fIenclen\fP)
|
unsigned char **\fIs\fP, long *\fIenclen\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -19,11 +19,9 @@
|
||||||
ares_free_data \- Free data allocated by several c-ares functions
|
ares_free_data \- Free data allocated by several c-ares functions
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B void ares_free_data(void *\fIdataptr\fP)
|
void ares_free_data(void *\fIdataptr\fP)
|
||||||
.PP
|
|
||||||
.B cc file.c -lcares
|
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_free_hostent \- Free host structure allocated by ares functions
|
ares_free_hostent \- Free host structure allocated by ares functions
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B void ares_free_hostent(struct hostent *\fIhost\fP)
|
void ares_free_hostent(struct hostent *\fIhost\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_free_string \- Free strings allocated by ares functions
|
ares_free_string \- Free strings allocated by ares functions
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B void ares_free_string(void *\fIstr\fP)
|
void ares_free_string(void *\fIstr\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fIares_free_string(3)\fP function frees a string allocated by an ares
|
The \fIares_free_string(3)\fP function frees a string allocated by an ares
|
||||||
|
|
|
@ -19,10 +19,13 @@
|
||||||
ares_get_servers, ares_get_servers_ports \- Retrieve name servers from an initialized ares_channel
|
ares_get_servers, ares_get_servers_ports \- Retrieve name servers from an initialized ares_channel
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_get_servers(ares_channel \fIchannel\fP, struct ares_addr_node **\fIservers\fP)
|
int ares_get_servers(ares_channel \fIchannel\fP,
|
||||||
.B int ares_get_servers_ports(ares_channel \fIchannel\fP, struct ares_addr_port_node **\fIservers\fP)
|
struct ares_addr_node **\fIservers\fP)
|
||||||
|
|
||||||
|
int ares_get_servers_ports(ares_channel \fIchannel\fP,
|
||||||
|
struct ares_addr_port_node **\fIservers\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_get_servers(3)\fP function retrieves name servers configuration
|
The \fBares_get_servers(3)\fP function retrieves name servers configuration
|
||||||
|
|
|
@ -18,14 +18,16 @@
|
||||||
ares_getaddrinfo \- Initiate a host query by name and service
|
ares_getaddrinfo \- Initiate a host query by name and service
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef void (*ares_addrinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
typedef void (*ares_addrinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B int \fItimeouts\fP, struct ares_addrinfo *\fIresult\fP)
|
int \fItimeouts\fP,
|
||||||
.PP
|
struct ares_addrinfo *\fIresult\fP)
|
||||||
.B void ares_getaddrinfo(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
|
||||||
.B const char* \fIservice\fP, const struct ares_addrinfo_hints *\fIhints\fP,
|
void ares_getaddrinfo(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
.B ares_addrinfo_callback \fIcallback\fP, void *\fIarg\fP)
|
const char* \fIservice\fP,
|
||||||
|
const struct ares_addrinfo_hints *\fIhints\fP,
|
||||||
|
ares_addrinfo_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,14 +18,15 @@
|
||||||
ares_gethostbyaddr \- Initiate a host query by address
|
ares_gethostbyaddr \- Initiate a host query by address
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B int \fItimeouts\fP, struct hostent *\fIhostent\fP)
|
int \fItimeouts\fP,
|
||||||
.PP
|
struct hostent *\fIhostent\fP)
|
||||||
.B void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP,
|
|
||||||
.B int \fIaddrlen\fP, int \fIfamily\fP, ares_host_callback \fIcallback\fP,
|
void ares_gethostbyaddr(ares_channel \fIchannel\fP, const void *\fIaddr\fP,
|
||||||
.B void *\fIarg\fP)
|
int \fIaddrlen\fP, int \fIfamily\fP,
|
||||||
|
ares_host_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,13 +18,15 @@
|
||||||
ares_gethostbyname \- Initiate a host query by name
|
ares_gethostbyname \- Initiate a host query by name
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
typedef void (*ares_host_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B int \fItimeouts\fP, struct hostent *\fIhostent\fP)
|
int \fItimeouts\fP,
|
||||||
.PP
|
struct hostent *\fIhostent\fP)
|
||||||
.B void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
|
||||||
.B int \fIfamily\fP, ares_host_callback \fIcallback\fP, void *\fIarg\fP)
|
void ares_gethostbyname(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
|
int \fIfamily\fP, ares_host_callback \fIcallback\fP,
|
||||||
|
void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_gethostbyname_file \- Lookup a name in the system's hosts file
|
ares_gethostbyname_file \- Lookup a name in the system's hosts file
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_gethostbyname_file(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
int ares_gethostbyname_file(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
.B int \fIfamily\fP, struct hostent **host)
|
int \fIfamily\fP, struct hostent **host)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,14 +18,15 @@
|
||||||
ares_getnameinfo \- Address-to-nodename translation in protocol-independent manner
|
ares_getnameinfo \- Address-to-nodename translation in protocol-independent manner
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B int \fItimeouts\fP, char *\fInode\fP, char *\fIservice\fP)
|
int \fItimeouts\fP, char *\fInode\fP,
|
||||||
.PP
|
char *\fIservice\fP)
|
||||||
.B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP,
|
|
||||||
.B ares_socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP,
|
void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP,
|
||||||
.B void *\fIarg\fP)
|
ares_socklen_t \fIsalen\fP, int \fIflags\fP,
|
||||||
|
ares_nameinfo_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_getsock \- get socket descriptors to wait on
|
ares_getsock \- get socket descriptors to wait on
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_getsock(ares_channel \fIchannel\fP, ares_socket_t *\fIsocks\fP,
|
int ares_getsock(ares_channel \fIchannel\fP, ares_socket_t *\fIsocks\fP,
|
||||||
.B int \fInumsocks\fP);
|
int \fInumsocks\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_inet_ntop \- convert a network format address to presentation format
|
ares_inet_ntop \- convert a network format address to presentation format
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B const char *
|
const char *ares_inet_ntop(int \fIaf\fP, const void *\fIsrc\fP, char *\fIdst\fP,
|
||||||
.B ares_inet_ntop(int af, const void *src, char *dst, ares_socklen_t size);
|
ares_socklen_t \fIsize\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This is a portable version with the identical functionality of the commonly
|
This is a portable version with the identical functionality of the commonly
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_inet_pton \- convert an IPv4 or IPv6 address from text to binary form
|
ares_inet_pton \- convert an IPv4 or IPv6 address from text to binary form
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B const char *ares_inet_pton(int af, const char *src, void *dst);
|
const char *ares_inet_pton(int \fIaf\fP, const char *\fIsrc\fP, void *\fIdst\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This is a portable version with the identical functionality of the commonly
|
This is a portable version with the identical functionality of the commonly
|
||||||
|
|
|
@ -41,6 +41,7 @@ struct ares_options {
|
||||||
int nsort;
|
int nsort;
|
||||||
int ednspsz;
|
int ednspsz;
|
||||||
char *resolvconf_path;
|
char *resolvconf_path;
|
||||||
|
char *hosts_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
int ares_init_options(ares_channel *\fIchannelptr\fP,
|
int ares_init_options(ares_channel *\fIchannelptr\fP,
|
||||||
|
@ -101,16 +102,14 @@ resolv.conf or the RES_OPTIONS environment variable.
|
||||||
.B ARES_OPT_UDP_PORT
|
.B ARES_OPT_UDP_PORT
|
||||||
.B unsigned short \fIudp_port\fP;
|
.B unsigned short \fIudp_port\fP;
|
||||||
.br
|
.br
|
||||||
The port to use for queries over UDP, in network byte order.
|
The port to use for queries over UDP, in host byte order.
|
||||||
The default value is 53 (in network byte order), the standard name
|
The default value is 53, the standard name service port.
|
||||||
service port.
|
|
||||||
.TP 18
|
.TP 18
|
||||||
.B ARES_OPT_TCP_PORT
|
.B ARES_OPT_TCP_PORT
|
||||||
.B unsigned short \fItcp_port\fP;
|
.B unsigned short \fItcp_port\fP;
|
||||||
.br
|
.br
|
||||||
The port to use for queries over TCP, in network byte order.
|
The port to use for queries over TCP, in host byte order.
|
||||||
The default value is 53 (in network byte order), the standard name
|
The default value is 53, the standard name service port.
|
||||||
service port.
|
|
||||||
.TP 18
|
.TP 18
|
||||||
.B ARES_OPT_SERVERS
|
.B ARES_OPT_SERVERS
|
||||||
.B struct in_addr *\fIservers\fP;
|
.B struct in_addr *\fIservers\fP;
|
||||||
|
@ -195,6 +194,16 @@ should be set to a path string, and will be honoured on *nix like systems. The
|
||||||
default is
|
default is
|
||||||
.B /etc/resolv.conf
|
.B /etc/resolv.conf
|
||||||
.br
|
.br
|
||||||
|
.TP 18
|
||||||
|
.B ARES_OPT_HOSTS_FILE
|
||||||
|
.B char *\fIhosts_path\fP;
|
||||||
|
.br
|
||||||
|
The path to use for reading the hosts file. The
|
||||||
|
.I hosts_path
|
||||||
|
should be set to a path string, and will be honoured on *nix like systems. The
|
||||||
|
default is
|
||||||
|
.B /etc/hosts
|
||||||
|
.br
|
||||||
.PP
|
.PP
|
||||||
The \fIoptmask\fP parameter also includes options without a corresponding
|
The \fIoptmask\fP parameter also includes options without a corresponding
|
||||||
field in the
|
field in the
|
||||||
|
|
|
@ -79,7 +79,8 @@ DllMain function. Doing so will produce deadlocks and other problems.
|
||||||
Initialize everything possible. This sets all known bits.
|
Initialize everything possible. This sets all known bits.
|
||||||
.TP
|
.TP
|
||||||
.B ARES_LIB_INIT_WIN32
|
.B ARES_LIB_INIT_WIN32
|
||||||
Initialize Win32/64 specific libraries.
|
Initialize Win32/64 specific libraries. As of c-ares 1.19.0, this is ignored
|
||||||
|
as there are no currently dynamically loaded libraries.
|
||||||
.TP
|
.TP
|
||||||
.B ARES_LIB_INIT_NONE
|
.B ARES_LIB_INIT_NONE
|
||||||
Initialize nothing extra. This sets no bit.
|
Initialize nothing extra. This sets no bit.
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
ares_mkquery \- Compose a single-question DNS query buffer
|
ares_mkquery \- Compose a single-question DNS query buffer
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP,
|
int ares_mkquery(const char *\fIname\fP, int \fIdnsclass\fP, int \fItype\fP,
|
||||||
.B unsigned short \fIid\fP, int \fIrd\fP, unsigned char **\fIbuf\fP,
|
unsigned short \fIid\fP, int \fIrd\fP, unsigned char **\fIbuf\fP,
|
||||||
.B int *\fIbuflen\fP)
|
int *\fIbuflen\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Deprecated function. See \fIares_create_query(3)\fP instead!
|
Deprecated function. See \fIares_create_query(3)\fP instead!
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
ares_parse_a_reply \- Parse a reply to a DNS query of type A
|
ares_parse_a_reply \- Parse a reply to a DNS query of type A
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct hostent **\fIhost\fP,
|
struct hostent **\fIhost\fP,
|
||||||
.B struct ares_addrttl *\fIaddrttls\fP, int *\fInaddrttls\fP);
|
struct ares_addrttl *\fIaddrttls\fP, int *\fInaddrttls\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
ares_parse_aaaa_reply \- Parse a reply to a DNS query of type AAAA
|
ares_parse_aaaa_reply \- Parse a reply to a DNS query of type AAAA
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct hostent **\fIhost\fP,
|
struct hostent **\fIhost\fP,
|
||||||
.B struct ares_addr6ttl *\fIaddrttls\fP, int *\fInaddrttls\fP);
|
struct ares_addr6ttl *\fIaddrttls\fP, int *\fInaddrttls\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -17,11 +17,10 @@
|
||||||
.SH NAME
|
.SH NAME
|
||||||
ares_parse_mx_reply \- Parse a reply to a DNS query of type MX
|
ares_parse_mx_reply \- Parse a reply to a DNS query of type MX
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
#include <ares.h>
|
||||||
.B #include <ares.h>
|
|
||||||
.PP
|
int ares_parse_mx_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||||
.B int ares_parse_mx_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
struct ares_mx_reply** \fImx_out\fP);
|
||||||
.B struct ares_mx_reply** \fImx_out\fP);
|
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_parse_naptr_reply \- Parse a reply to a DNS query of type NAPTR
|
ares_parse_naptr_reply \- Parse a reply to a DNS query of type NAPTR
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_naptr_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
int ares_parse_naptr_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct ares_naptr_reply** \fInaptr_out\fP);
|
struct ares_naptr_reply** \fInaptr_out\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_parse_ns_reply \- Parse a reply to a DNS query of type NS into a hostent
|
ares_parse_ns_reply \- Parse a reply to a DNS query of type NS into a hostent
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_ns_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
int ares_parse_ns_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct hostent **\fIhost\fP);
|
struct hostent **\fIhost\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
ares_parse_ptr_reply \- Parse a reply to a DNS query of type PTR into a hostent
|
ares_parse_ptr_reply \- Parse a reply to a DNS query of type PTR into a hostent
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_ptr_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
int ares_parse_ptr_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP,
|
||||||
.B const void *\fIaddr\fP, int \fIaddrlen\fP, int \fIfamily\fP,
|
const void *\fIaddr\fP, int \fIaddrlen\fP,
|
||||||
.B struct hostent **\fIhost\fP);
|
int \fIfamily\fP, struct hostent **\fIhost\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_parse_soa_reply \- Parse a reply to a DNS query of type SOA
|
ares_parse_soa_reply \- Parse a reply to a DNS query of type SOA
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_soa_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
int ares_parse_soa_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct ares_soa_reply** \fIsoa_out\fP);
|
struct ares_soa_reply** \fIsoa_out\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_parse_srv_reply \- Parse a reply to a DNS query of type SRV
|
ares_parse_srv_reply \- Parse a reply to a DNS query of type SRV
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_srv_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
int ares_parse_srv_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct ares_srv_reply** \fIsrv_out\fP);
|
struct ares_srv_reply** \fIsrv_out\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,13 +18,13 @@
|
||||||
ares_parse_txt_reply \- Parse a reply to a DNS query of type TXT
|
ares_parse_txt_reply \- Parse a reply to a DNS query of type TXT
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_txt_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
int ares_parse_txt_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct ares_txt_reply **\fItxt_out\fP);
|
struct ares_txt_reply **\fItxt_out\fP);
|
||||||
.PP
|
|
||||||
.B int ares_parse_txt_reply_ext(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
int ares_parse_txt_reply_ext(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct ares_txt_ext **\fItxt_out\fP);
|
struct ares_txt_ext **\fItxt_out\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
ares_parse_uri_reply \- Parse a reply to a DNS query of type URI
|
ares_parse_uri_reply \- Parse a reply to a DNS query of type URI
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_parse_uri_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
int ares_parse_uri_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP,
|
||||||
.B struct ares_uri_reply** \fIuri_out\fP);
|
struct ares_uri_reply** \fIuri_out\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -44,7 +44,7 @@ if they complete successfully or fail.
|
||||||
\fBares_process_fd(3)\fP works the same way but acts and operates only on the
|
\fBares_process_fd(3)\fP works the same way but acts and operates only on the
|
||||||
specific file descriptors (sockets) you pass in to the function. Use
|
specific file descriptors (sockets) you pass in to the function. Use
|
||||||
ARES_SOCKET_BAD for "no action". This function is provided to allow users of
|
ARES_SOCKET_BAD for "no action". This function is provided to allow users of
|
||||||
c-ares to void \fIselect(3)\fP in their applications and within c-ares.
|
c-ares to avoid \fIselect(3)\fP in their applications and within c-ares.
|
||||||
|
|
||||||
To only process possible timeout conditions without a socket event occurring,
|
To only process possible timeout conditions without a socket event occurring,
|
||||||
one may pass NULL as the values for both \fIread_fds\fP and \fIwrite_fds\fP for
|
one may pass NULL as the values for both \fIread_fds\fP and \fIwrite_fds\fP for
|
||||||
|
|
|
@ -18,14 +18,15 @@
|
||||||
ares_query \- Initiate a single-question DNS query
|
ares_query \- Initiate a single-question DNS query
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP)
|
int \fItimeouts\fP, unsigned char *\fIabuf\fP,
|
||||||
.PP
|
int \fIalen\fP)
|
||||||
.B void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
|
||||||
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP,
|
void ares_query(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
.B void *\fIarg\fP)
|
int \fIdnsclass\fP, int \fItype\fP,
|
||||||
|
ares_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,9 +18,10 @@
|
||||||
ares_save_options \- Save configuration values obtained from initialized ares_channel
|
ares_save_options \- Save configuration values obtained from initialized ares_channel
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_save_options(ares_channel \fIchannel\fP, struct ares_options *\fIoptions\fP, int *\fIoptmask\fP)
|
int ares_save_options(ares_channel \fIchannel\fP,
|
||||||
|
struct ares_options *\fIoptions\fP, int *\fIoptmask\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_save_options(3)\fP function saves the channel data identified by
|
The \fBares_save_options(3)\fP function saves the channel data identified by
|
||||||
|
|
|
@ -18,14 +18,15 @@
|
||||||
ares_search \- Initiate a DNS query with domain search
|
ares_search \- Initiate a DNS query with domain search
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP)
|
int \fItimeouts\fP, unsigned char *\fIabuf\fP,
|
||||||
.PP
|
int \fIalen\fP)
|
||||||
.B void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
|
||||||
.B int \fIdnsclass\fP, int \fItype\fP, ares_callback \fIcallback\fP,
|
void ares_search(ares_channel \fIchannel\fP, const char *\fIname\fP,
|
||||||
.B void *\fIarg\fP)
|
int \fIdnsclass\fP, int \fItype\fP,
|
||||||
|
ares_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
ares_send \- Initiate a DNS query
|
ares_send \- Initiate a DNS query
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
typedef void (*ares_callback)(void *\fIarg\fP, int \fIstatus\fP,
|
||||||
.B int \fItimeouts\fP, unsigned char *\fIabuf\fP, int \fIalen\fP)
|
int \fItimeouts\fP, unsigned char *\fIabuf\fP,
|
||||||
.PP
|
int \fIalen\fP)
|
||||||
.B void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
|
||||||
.B int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
|
void ares_send(ares_channel \fIchannel\fP, const unsigned char *\fIqbuf\fP,
|
||||||
|
int \fIqlen\fP, ares_callback \fIcallback\fP, void *\fIarg\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_set_local_dev \- Bind to a specific network device when creating sockets.
|
ares_set_local_dev \- Bind to a specific network device when creating sockets.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B void ares_set_local_dev(ares_channel \fIchannel\fP, const char* \fIlocal_dev_name\fP)
|
void ares_set_local_dev(ares_channel \fIchannel\fP, const char* \fIlocal_dev_name\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_set_local_dev\fP function causes all future sockets
|
The \fBares_set_local_dev\fP function causes all future sockets
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_set_local_ip4 \- Set local IPv4 address outgoing requests.
|
ares_set_local_ip4 \- Set local IPv4 address outgoing requests.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B void ares_set_local_ip4(ares_channel \fIchannel\fP, unsigned int \fIlocal_ip\fP)
|
void ares_set_local_ip4(ares_channel \fIchannel\fP, unsigned int \fIlocal_ip\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_set_local_ip4\fP function sets the IP address for outbound
|
The \fBares_set_local_ip4\fP function sets the IP address for outbound
|
||||||
|
|
|
@ -18,15 +18,15 @@
|
||||||
ares_set_local_ip6 \- Set local IPv6 address outgoing requests.
|
ares_set_local_ip6 \- Set local IPv6 address outgoing requests.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B void ares_set_local_ip6(ares_channel \fIchannel\fP, const unsigned char* \fIlocal_ip6\fP)
|
void ares_set_local_ip6(ares_channel \fIchannel\fP, const unsigned char* \fIlocal_ip6\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_set_local_ip6\fP function sets the IPv6 address for outbound
|
The \fBares_set_local_ip6\fP function sets the IPv6 address for outbound IPv6
|
||||||
IPv6 requests. The parameter \fIlocal_ip6\fP is specified in network byte
|
requests. The parameter \fIlocal_ip6\fP is specified in network byte order.
|
||||||
order. This allows users to specify outbound interfaces when used on
|
This allows users to specify outbound interfaces when used on multi-homed
|
||||||
multi-homed systems. The local_ip6 argument must be 16 bytes in length.
|
systems. The \fIlocal_ip6\fP argument must be 16 bytes in length.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ares_set_local_ip4 (3)
|
.BR ares_set_local_ip4 (3)
|
||||||
.SH NOTES
|
.SH NOTES
|
||||||
|
|
|
@ -18,10 +18,13 @@
|
||||||
ares_set_servers, ares_set_servers_ports \- Initialize an ares_channel name servers configuration
|
ares_set_servers, ares_set_servers_ports \- Initialize an ares_channel name servers configuration
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_set_servers(ares_channel \fIchannel\fP, struct ares_addr_node *\fIservers\fP)
|
int ares_set_servers(ares_channel \fIchannel\fP,
|
||||||
.B int ares_set_servers_ports(ares_channel \fIchannel\fP, struct ares_addr_port_node *\fIservers\fP)
|
struct ares_addr_node *\fIservers\fP)
|
||||||
|
|
||||||
|
int ares_set_servers_ports(ares_channel \fIchannel\fP,
|
||||||
|
struct ares_addr_port_node *\fIservers\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_set_servers(3)\fP function initializes name servers configuration
|
The \fBares_set_servers(3)\fP function initializes name servers configuration
|
||||||
|
|
|
@ -18,10 +18,11 @@
|
||||||
ares_set_servers_csv, ares_set_servers_ports_csv \- Set list of DNS servers to be used.
|
ares_set_servers_csv, ares_set_servers_ports_csv \- Set list of DNS servers to be used.
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_set_servers_csv(ares_channel \fIchannel\fP, const char* \fIservers\fP)
|
int ares_set_servers_csv(ares_channel \fIchannel\fP, const char* \fIservers\fP)
|
||||||
.B int ares_set_servers_ports_csv(ares_channel \fIchannel\fP, const char* \fIservers\fP)
|
|
||||||
|
int ares_set_servers_ports_csv(ares_channel \fIchannel\fP, const char* \fIservers\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_set_servers_csv\fP and \fBares_set_servers_ports_csv\fPfunctions set
|
The \fBares_set_servers_csv\fP and \fBares_set_servers_ports_csv\fPfunctions set
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
ares_set_socket_callback \- Set a socket creation callback
|
ares_set_socket_callback \- Set a socket creation callback
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef int (*ares_sock_create_callback)(ares_socket_t \fIsocket_fd\fP,
|
typedef int (*ares_sock_create_callback)(ares_socket_t \fIsocket_fd\fP,
|
||||||
int \fItype\fP,
|
int \fItype\fP,
|
||||||
void *\fIuserdata\fP)
|
void *\fIuserdata\fP)
|
||||||
.PP
|
|
||||||
.B void ares_set_socket_callback(ares_channel \fIchannel\fP,
|
void ares_set_socket_callback(ares_channel \fIchannel\fP,
|
||||||
ares_sock_create_callback \fIcallback\fP,
|
ares_sock_create_callback \fIcallback\fP,
|
||||||
void *\fIuserdata\fP)
|
void *\fIuserdata\fP)
|
||||||
.PP
|
.PP
|
||||||
.B cc file.c -lcares
|
.B cc file.c -lcares
|
||||||
.fi
|
.fi
|
||||||
|
|
|
@ -4,17 +4,15 @@
|
||||||
ares_set_socket_configure_callback \- Set a socket configuration callback
|
ares_set_socket_configure_callback \- Set a socket configuration callback
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B typedef int (*ares_sock_config_callback)(ares_socket_t \fIsocket_fd\fP,
|
typedef int (*ares_sock_config_callback)(ares_socket_t \fIsocket_fd\fP,
|
||||||
int \fItype\fP,
|
int \fItype\fP,
|
||||||
void *\fIuserdata\fP)
|
void *\fIuserdata\fP)
|
||||||
.PP
|
|
||||||
.B void ares_set_socket_configure_callback(ares_channel \fIchannel\fP,
|
void ares_set_socket_configure_callback(ares_channel \fIchannel\fP,
|
||||||
ares_sock_config_callback \fIcallback\fP,
|
ares_sock_config_callback \fIcallback\fP,
|
||||||
void *\fIuserdata\fP)
|
void *\fIuserdata\fP)
|
||||||
.PP
|
|
||||||
.B cc file.c -lcares
|
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
|
|
|
@ -4,21 +4,20 @@
|
||||||
ares_set_socket_functions \- Set socket io callbacks
|
ares_set_socket_functions \- Set socket io callbacks
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B struct ares_socket_functions {
|
|
||||||
ares_socket_t(*\fIasocket\fP)(int, int, int, void *);
|
|
||||||
int(*\fIaclose\fP)(ares_socket_t, void *);
|
|
||||||
int(*\fIaconnect\fP)(ares_socket_t, const struct sockaddr *, ares_socklen_t, void *);
|
|
||||||
ares_ssize_t(*\fIarecvfrom\fP)(ares_socket_t, void *, size_t, int, struct sockaddr *, ares_socklen_t *, void *);
|
|
||||||
ares_ssize_t(*\fIasendv\fP)(ares_socket_t, const struct iovec *, int, void *);
|
|
||||||
};
|
|
||||||
|
|
||||||
.PP
|
struct ares_socket_functions {
|
||||||
.B void ares_set_socket_functions(ares_channel \fIchannel\fP,
|
ares_socket_t (*\fIasocket\fP)(int, int, int, void *);
|
||||||
const struct ares_socket_functions * \fIfunctions\fP,
|
int (*\fIaclose\fP)(ares_socket_t, void *);
|
||||||
void *\fIuser_data\fP);
|
int (*\fIaconnect\fP)(ares_socket_t, const struct sockaddr *, ares_socklen_t, void *);
|
||||||
|
ares_ssize_t (*\fIarecvfrom\fP)(ares_socket_t, void *, size_t, int,
|
||||||
|
struct sockaddr *, ares_socklen_t *, void *);
|
||||||
|
ares_ssize_t (*\fIasendv\fP)(ares_socket_t, const struct iovec *, int, void *);
|
||||||
|
};
|
||||||
|
|
||||||
|
void ares_set_socket_functions(ares_channel \fIchannel\fP,
|
||||||
|
const struct ares_socket_functions * \fIfunctions\fP,
|
||||||
|
void *\fIuser_data\fP);
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
ares_set_sortlist \- Initialize an ares_channel sortlist configuration
|
ares_set_sortlist \- Initialize an ares_channel sortlist configuration
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B int ares_set_sortlist(ares_channel \fIchannel\fP, const char *\fIsortstr\fP)
|
int ares_set_sortlist(ares_channel \fIchannel\fP, const char *\fIsortstr\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The \fBares_set_sortlist(3)\fP function initializes an address sortlist configuration
|
The \fBares_set_sortlist(3)\fP function initializes an address sortlist configuration
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
ares_strerror \- Get the description of an ares library error code
|
ares_strerror \- Get the description of an ares library error code
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.nf
|
.nf
|
||||||
.B #include <ares.h>
|
#include <ares.h>
|
||||||
.PP
|
|
||||||
.B const char *ares_strerror(int \fIcode\fP)
|
const char *ares_strerror(int \fIcode\fP)
|
||||||
.fi
|
.fi
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
|
|
|
@ -63,6 +63,13 @@
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# include <winsock2.h>
|
# include <winsock2.h>
|
||||||
# include <ws2tcpip.h>
|
# include <ws2tcpip.h>
|
||||||
|
/* To aid with linking against a static c-ares build, lets tell the microsoft
|
||||||
|
* compiler to pull in needed dependencies */
|
||||||
|
# ifdef _MSC_VER
|
||||||
|
# pragma comment(lib, "ws2_32")
|
||||||
|
# pragma comment(lib, "advapi32")
|
||||||
|
# pragma comment(lib, "iphlpapi")
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
# include <netinet/in.h>
|
# include <netinet/in.h>
|
||||||
|
@ -168,6 +175,7 @@ extern "C" {
|
||||||
#define ARES_OPT_EDNSPSZ (1 << 15)
|
#define ARES_OPT_EDNSPSZ (1 << 15)
|
||||||
#define ARES_OPT_NOROTATE (1 << 16)
|
#define ARES_OPT_NOROTATE (1 << 16)
|
||||||
#define ARES_OPT_RESOLVCONF (1 << 17)
|
#define ARES_OPT_RESOLVCONF (1 << 17)
|
||||||
|
#define ARES_OPT_HOSTS_FILE (1 << 18)
|
||||||
|
|
||||||
/* Nameinfo flag values */
|
/* Nameinfo flag values */
|
||||||
#define ARES_NI_NOFQDN (1 << 0)
|
#define ARES_NI_NOFQDN (1 << 0)
|
||||||
|
@ -277,6 +285,7 @@ struct ares_options {
|
||||||
int nsort;
|
int nsort;
|
||||||
int ednspsz;
|
int ednspsz;
|
||||||
char *resolvconf_path;
|
char *resolvconf_path;
|
||||||
|
char *hosts_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hostent;
|
struct hostent;
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
#define ARES_COPYRIGHT "2004 - 2021 Daniel Stenberg, <daniel@haxx.se>."
|
#define ARES_COPYRIGHT "2004 - 2021 Daniel Stenberg, <daniel@haxx.se>."
|
||||||
|
|
||||||
#define ARES_VERSION_MAJOR 1
|
#define ARES_VERSION_MAJOR 1
|
||||||
#define ARES_VERSION_MINOR 18
|
#define ARES_VERSION_MINOR 19
|
||||||
#define ARES_VERSION_PATCH 1
|
#define ARES_VERSION_PATCH 0
|
||||||
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
|
||||||
(ARES_VERSION_MINOR<<8)|\
|
(ARES_VERSION_MINOR<<8)|\
|
||||||
(ARES_VERSION_PATCH))
|
(ARES_VERSION_PATCH))
|
||||||
#define ARES_VERSION_STR "1.18.1"
|
#define ARES_VERSION_STR "1.19.0"
|
||||||
|
|
||||||
#if (ARES_VERSION >= 0x010700)
|
#if (ARES_VERSION >= 0x010700)
|
||||||
# define CARES_HAVE_ARES_LIBRARY_INIT 1
|
# define CARES_HAVE_ARES_LIBRARY_INIT 1
|
||||||
|
|
|
@ -10,6 +10,11 @@ CONFIGURE_FILE (ares_config.h.cmake ${PROJECT_BINARY_DIR}/ares_config.h)
|
||||||
IF (CARES_SHARED)
|
IF (CARES_SHARED)
|
||||||
ADD_LIBRARY (${PROJECT_NAME} SHARED ${CSOURCES})
|
ADD_LIBRARY (${PROJECT_NAME} SHARED ${CSOURCES})
|
||||||
|
|
||||||
|
# Include resource file in windows builds for versioned DLLs
|
||||||
|
IF (WIN32)
|
||||||
|
TARGET_SOURCES (${PROJECT_NAME} PRIVATE cares.rc)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
# Convert CARES_LIB_VERSIONINFO libtool version format into VERSION and SOVERSION
|
# Convert CARES_LIB_VERSIONINFO libtool version format into VERSION and SOVERSION
|
||||||
# Convert from ":" separated into CMake list format using ";"
|
# Convert from ":" separated into CMake list format using ";"
|
||||||
STRING (REPLACE ":" ";" CARES_LIB_VERSIONINFO ${CARES_LIB_VERSIONINFO})
|
STRING (REPLACE ":" ";" CARES_LIB_VERSIONINFO ${CARES_LIB_VERSIONINFO})
|
||||||
|
|
|
@ -65,7 +65,6 @@ HHEADERS = ares_android.h \
|
||||||
ares_inet_net_pton.h \
|
ares_inet_net_pton.h \
|
||||||
ares_iphlpapi.h \
|
ares_iphlpapi.h \
|
||||||
ares_ipv6.h \
|
ares_ipv6.h \
|
||||||
ares_library_init.h \
|
|
||||||
ares_llist.h \
|
ares_llist.h \
|
||||||
ares_nowarn.h \
|
ares_nowarn.h \
|
||||||
ares_platform.h \
|
ares_platform.h \
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef __ARES_DATA_H
|
||||||
|
#define __ARES_DATA_H
|
||||||
|
|
||||||
|
|
||||||
/* Copyright (C) 2009-2013 by Daniel Stenberg
|
/* Copyright (C) 2009-2013 by Daniel Stenberg
|
||||||
*
|
*
|
||||||
|
@ -74,3 +77,5 @@ struct ares_data {
|
||||||
|
|
||||||
void *ares_malloc_data(ares_datatype type);
|
void *ares_malloc_data(ares_datatype type);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __ARES_DATA_H
|
||||||
|
|
|
@ -38,6 +38,8 @@ void ares_destroy_options(struct ares_options *options)
|
||||||
ares_free(options->lookups);
|
ares_free(options->lookups);
|
||||||
if(options->resolvconf_path)
|
if(options->resolvconf_path)
|
||||||
ares_free(options->resolvconf_path);
|
ares_free(options->resolvconf_path);
|
||||||
|
if(options->hosts_path)
|
||||||
|
ares_free(options->hosts_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ares_destroy(ares_channel channel)
|
void ares_destroy(ares_channel channel)
|
||||||
|
@ -90,6 +92,9 @@ void ares_destroy(ares_channel channel)
|
||||||
if (channel->resolvconf_path)
|
if (channel->resolvconf_path)
|
||||||
ares_free(channel->resolvconf_path);
|
ares_free(channel->resolvconf_path);
|
||||||
|
|
||||||
|
if (channel->hosts_path)
|
||||||
|
ares_free(channel->hosts_path);
|
||||||
|
|
||||||
ares_free(channel);
|
ares_free(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ static int ares__isprint(int ch)
|
||||||
* - underscores which are used in SRV records.
|
* - underscores which are used in SRV records.
|
||||||
* - Forward slashes such as are used for classless in-addr.arpa
|
* - Forward slashes such as are used for classless in-addr.arpa
|
||||||
* delegation (CNAMEs)
|
* delegation (CNAMEs)
|
||||||
|
* - Asterisks may be used for wildcard domains in CNAMEs as seen in the
|
||||||
|
* real world.
|
||||||
* While RFC 2181 section 11 does state not to do validation,
|
* While RFC 2181 section 11 does state not to do validation,
|
||||||
* that applies to servers, not clients. Vulnerabilities have been
|
* that applies to servers, not clients. Vulnerabilities have been
|
||||||
* reported when this validation is not performed. Security is more
|
* reported when this validation is not performed. Security is more
|
||||||
|
@ -71,7 +73,7 @@ static int ares__isprint(int ch)
|
||||||
* anyhow). */
|
* anyhow). */
|
||||||
static int is_hostnamech(int ch)
|
static int is_hostnamech(int ch)
|
||||||
{
|
{
|
||||||
/* [A-Za-z0-9-._/]
|
/* [A-Za-z0-9-*._/]
|
||||||
* Don't use isalnum() as it is locale-specific
|
* Don't use isalnum() as it is locale-specific
|
||||||
*/
|
*/
|
||||||
if (ch >= 'A' && ch <= 'Z')
|
if (ch >= 'A' && ch <= 'Z')
|
||||||
|
@ -80,7 +82,7 @@ static int is_hostnamech(int ch)
|
||||||
return 1;
|
return 1;
|
||||||
if (ch >= '0' && ch <= '9')
|
if (ch >= '0' && ch <= '9')
|
||||||
return 1;
|
return 1;
|
||||||
if (ch == '-' || ch == '.' || ch == '_' || ch == '/')
|
if (ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '*')
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -326,7 +326,7 @@ static int fake_addrinfo(const char *name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (family == AF_INET6 || family == AF_UNSPEC)
|
if (!result && (family == AF_INET6 || family == AF_UNSPEC))
|
||||||
{
|
{
|
||||||
struct ares_in6_addr addr6;
|
struct ares_in6_addr addr6;
|
||||||
result = ares_inet_pton(AF_INET6, name, &addr6) < 1 ? 0 : 1;
|
result = ares_inet_pton(AF_INET6, name, &addr6) < 1 ? 0 : 1;
|
||||||
|
@ -404,16 +404,46 @@ static void end_hquery(struct host_query *hquery, int status)
|
||||||
ares_free(hquery);
|
ares_free(hquery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_localhost(const char *name)
|
||||||
|
{
|
||||||
|
/* RFC6761 6.3 says : The domain "localhost." and any names falling within ".localhost." */
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (strcmp(name, "localhost") == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
len = strlen(name);
|
||||||
|
if (len < 10 /* strlen(".localhost") */)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (strcmp(name + (len - 10 /* strlen(".localhost") */), ".localhost") == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int file_lookup(struct host_query *hquery)
|
static int file_lookup(struct host_query *hquery)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int error;
|
int error;
|
||||||
int status;
|
int status;
|
||||||
const char *path_hosts = NULL;
|
char *path_hosts = NULL;
|
||||||
|
|
||||||
if (hquery->hints.ai_flags & ARES_AI_ENVHOSTS)
|
if (hquery->hints.ai_flags & ARES_AI_ENVHOSTS)
|
||||||
{
|
{
|
||||||
path_hosts = getenv("CARES_HOSTS");
|
path_hosts = ares_strdup(getenv("CARES_HOSTS"));
|
||||||
|
if (!path_hosts)
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hquery->channel->hosts_path)
|
||||||
|
{
|
||||||
|
path_hosts = ares_strdup(hquery->channel->hosts_path);
|
||||||
|
if (!path_hosts)
|
||||||
|
return ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path_hosts)
|
if (!path_hosts)
|
||||||
|
@ -447,15 +477,15 @@ static int file_lookup(struct host_query *hquery)
|
||||||
return ARES_ENOTFOUND;
|
return ARES_ENOTFOUND;
|
||||||
|
|
||||||
strcat(PATH_HOSTS, WIN_PATH_HOSTS);
|
strcat(PATH_HOSTS, WIN_PATH_HOSTS);
|
||||||
path_hosts = PATH_HOSTS;
|
|
||||||
|
|
||||||
#elif defined(WATT32)
|
#elif defined(WATT32)
|
||||||
const char *PATH_HOSTS = _w32_GetHostsFile();
|
const char *PATH_HOSTS = _w32_GetHostsFile();
|
||||||
|
|
||||||
if (!PATH_HOSTS)
|
if (!PATH_HOSTS)
|
||||||
return ARES_ENOTFOUND;
|
return ARES_ENOTFOUND;
|
||||||
#endif
|
#endif
|
||||||
path_hosts = PATH_HOSTS;
|
path_hosts = ares_strdup(PATH_HOSTS);
|
||||||
|
if (!path_hosts)
|
||||||
|
return ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp = fopen(path_hosts, "r");
|
fp = fopen(path_hosts, "r");
|
||||||
|
@ -466,21 +496,29 @@ static int file_lookup(struct host_query *hquery)
|
||||||
{
|
{
|
||||||
case ENOENT:
|
case ENOENT:
|
||||||
case ESRCH:
|
case ESRCH:
|
||||||
return ARES_ENOTFOUND;
|
status = ARES_ENOTFOUND;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error,
|
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error,
|
||||||
strerror(error)));
|
strerror(error)));
|
||||||
DEBUGF(fprintf(stderr, "Error opening file: %s\n", path_hosts));
|
DEBUGF(fprintf(stderr, "Error opening file: %s\n", path_hosts));
|
||||||
return ARES_EFILE;
|
status = ARES_EFILE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status = ares__readaddrinfo(fp, hquery->name, hquery->port, &hquery->hints, hquery->ai);
|
else
|
||||||
fclose(fp);
|
{
|
||||||
|
status = ares__readaddrinfo(fp, hquery->name, hquery->port, &hquery->hints, hquery->ai);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
ares_free(path_hosts);
|
||||||
|
|
||||||
/* RFC6761 section 6.3 #3 states that "Name resolution APIs and libraries
|
/* RFC6761 section 6.3 #3 states that "Name resolution APIs and libraries
|
||||||
* SHOULD recognize localhost names as special and SHOULD always return the
|
* SHOULD recognize localhost names as special and SHOULD always return the
|
||||||
* IP loopback address for address queries" */
|
* IP loopback address for address queries".
|
||||||
if (status == ARES_ENOTFOUND && strcmp(hquery->name, "localhost") == 0)
|
* We will also ignore ALL errors when trying to resolve localhost, such
|
||||||
|
* as permissions errors reading /etc/hosts or a malformed /etc/hosts */
|
||||||
|
if (status != ARES_SUCCESS && is_localhost(hquery->name))
|
||||||
{
|
{
|
||||||
return ares__addrinfo_localhost(hquery->name, hquery->port,
|
return ares__addrinfo_localhost(hquery->name, hquery->port,
|
||||||
&hquery->hints, hquery->ai);
|
&hquery->hints, hquery->ai);
|
||||||
|
@ -497,7 +535,7 @@ static void next_lookup(struct host_query *hquery, int status)
|
||||||
/* RFC6761 section 6.3 #3 says "Name resolution APIs SHOULD NOT send
|
/* RFC6761 section 6.3 #3 says "Name resolution APIs SHOULD NOT send
|
||||||
* queries for localhost names to their configured caching DNS
|
* queries for localhost names to their configured caching DNS
|
||||||
* server(s)." */
|
* server(s)." */
|
||||||
if (strcmp(hquery->name, "localhost") != 0)
|
if (!is_localhost(hquery->name))
|
||||||
{
|
{
|
||||||
/* DNS lookup */
|
/* DNS lookup */
|
||||||
if (next_dns_lookup(hquery))
|
if (next_dns_lookup(hquery))
|
||||||
|
@ -543,7 +581,16 @@ static void host_callback(void *arg, int status, int timeouts,
|
||||||
if (addinfostatus != ARES_SUCCESS && addinfostatus != ARES_ENODATA)
|
if (addinfostatus != ARES_SUCCESS && addinfostatus != ARES_ENODATA)
|
||||||
{
|
{
|
||||||
/* error in parsing result e.g. no memory */
|
/* error in parsing result e.g. no memory */
|
||||||
end_hquery(hquery, addinfostatus);
|
if (addinfostatus == ARES_EBADRESP && hquery->ai->nodes)
|
||||||
|
{
|
||||||
|
/* We got a bad response from server, but at least one query
|
||||||
|
* ended with ARES_SUCCESS */
|
||||||
|
end_hquery(hquery, ARES_SUCCESS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end_hquery(hquery, addinfostatus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (hquery->ai->nodes)
|
else if (hquery->ai->nodes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,9 +47,12 @@
|
||||||
#include <resolv.h>
|
#include <resolv.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_WINSOCK)
|
||||||
|
# include <iphlpapi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_inet_net_pton.h"
|
#include "ares_inet_net_pton.h"
|
||||||
#include "ares_library_init.h"
|
|
||||||
#include "ares_nowarn.h"
|
#include "ares_nowarn.h"
|
||||||
#include "ares_platform.h"
|
#include "ares_platform.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
@ -58,6 +61,18 @@
|
||||||
#undef WIN32 /* Redefined in MingW/MSVC headers */
|
#undef WIN32 /* Redefined in MingW/MSVC headers */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Define RtlGenRandom = SystemFunction036. This is in advapi32.dll. There is
|
||||||
|
* no need to dynamically load this, other software used widely does not.
|
||||||
|
* http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
|
||||||
|
* https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-rtlgenrandom
|
||||||
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG RandomBufferLength);
|
||||||
|
# ifndef RtlGenRandom
|
||||||
|
# define RtlGenRandom(a,b) SystemFunction036(a,b)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static int init_by_options(ares_channel channel,
|
static int init_by_options(ares_channel channel,
|
||||||
const struct ares_options *options,
|
const struct ares_options *options,
|
||||||
int optmask);
|
int optmask);
|
||||||
|
@ -149,6 +164,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
|
||||||
channel->sock_funcs = NULL;
|
channel->sock_funcs = NULL;
|
||||||
channel->sock_func_cb_data = NULL;
|
channel->sock_func_cb_data = NULL;
|
||||||
channel->resolvconf_path = NULL;
|
channel->resolvconf_path = NULL;
|
||||||
|
channel->hosts_path = NULL;
|
||||||
|
|
||||||
channel->last_server = 0;
|
channel->last_server = 0;
|
||||||
channel->last_timeout_processed = (time_t)now.tv_sec;
|
channel->last_timeout_processed = (time_t)now.tv_sec;
|
||||||
|
@ -217,13 +233,15 @@ done:
|
||||||
if (channel->servers)
|
if (channel->servers)
|
||||||
ares_free(channel->servers);
|
ares_free(channel->servers);
|
||||||
if (channel->ndomains != -1)
|
if (channel->ndomains != -1)
|
||||||
ares_strsplit_free(channel->domains, channel->ndomains);
|
ares__strsplit_free(channel->domains, channel->ndomains);
|
||||||
if (channel->sortlist)
|
if (channel->sortlist)
|
||||||
ares_free(channel->sortlist);
|
ares_free(channel->sortlist);
|
||||||
if(channel->lookups)
|
if(channel->lookups)
|
||||||
ares_free(channel->lookups);
|
ares_free(channel->lookups);
|
||||||
if(channel->resolvconf_path)
|
if(channel->resolvconf_path)
|
||||||
ares_free(channel->resolvconf_path);
|
ares_free(channel->resolvconf_path);
|
||||||
|
if(channel->hosts_path)
|
||||||
|
ares_free(channel->hosts_path);
|
||||||
ares_free(channel);
|
ares_free(channel);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -335,6 +353,9 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
||||||
if (channel->resolvconf_path)
|
if (channel->resolvconf_path)
|
||||||
(*optmask) |= ARES_OPT_RESOLVCONF;
|
(*optmask) |= ARES_OPT_RESOLVCONF;
|
||||||
|
|
||||||
|
if (channel->hosts_path)
|
||||||
|
(*optmask) |= ARES_OPT_HOSTS_FILE;
|
||||||
|
|
||||||
/* Copy easy stuff */
|
/* Copy easy stuff */
|
||||||
options->flags = channel->flags;
|
options->flags = channel->flags;
|
||||||
|
|
||||||
|
@ -414,6 +435,13 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* copy path for hosts file */
|
||||||
|
if (channel->hosts_path) {
|
||||||
|
options->hosts_path = ares_strdup(channel->hosts_path);
|
||||||
|
if (!options->hosts_path)
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
return ARES_SUCCESS;
|
return ARES_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,6 +558,14 @@ static int init_by_options(ares_channel channel,
|
||||||
return ARES_ENOMEM;
|
return ARES_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set path for hosts file, if given. */
|
||||||
|
if ((optmask & ARES_OPT_HOSTS_FILE) && !channel->hosts_path)
|
||||||
|
{
|
||||||
|
channel->hosts_path = ares_strdup(options->hosts_path);
|
||||||
|
if (!channel->hosts_path && options->hosts_path)
|
||||||
|
return ARES_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
channel->optmask = optmask;
|
channel->optmask = optmask;
|
||||||
|
|
||||||
return ARES_SUCCESS;
|
return ARES_SUCCESS;
|
||||||
|
@ -608,227 +644,6 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* get_REG_SZ_9X()
|
|
||||||
*
|
|
||||||
* Functionally identical to get_REG_SZ()
|
|
||||||
*
|
|
||||||
* Supported on Windows 95, 98 and ME.
|
|
||||||
*/
|
|
||||||
static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
|
|
||||||
{
|
|
||||||
DWORD dataType = 0;
|
|
||||||
DWORD size = 0;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
|
|
||||||
/* Find out size of string stored in registry */
|
|
||||||
res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, NULL, &size);
|
|
||||||
if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Allocate buffer of indicated size plus one given that string
|
|
||||||
might have been stored without null termination */
|
|
||||||
*outptr = ares_malloc(size+1);
|
|
||||||
if (!*outptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Get the value for real */
|
|
||||||
res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType,
|
|
||||||
(unsigned char *)*outptr, &size);
|
|
||||||
if ((res != ERROR_SUCCESS) || (size == 1))
|
|
||||||
{
|
|
||||||
ares_free(*outptr);
|
|
||||||
*outptr = NULL;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Null terminate buffer allways */
|
|
||||||
*(*outptr + size) = '\0';
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get_enum_REG_SZ()
|
|
||||||
*
|
|
||||||
* Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
|
|
||||||
* pointer to the name of the registry leaf key to be queried, parent key
|
|
||||||
* is enumerated searching in child keys for given leaf key name and its
|
|
||||||
* associated string value. When located, this returns a pointer in *outptr
|
|
||||||
* to a newly allocated memory area holding it as a null-terminated string.
|
|
||||||
*
|
|
||||||
* Returns 0 and nullifies *outptr upon inability to return a string value.
|
|
||||||
*
|
|
||||||
* Returns 1 and sets *outptr when returning a dynamically allocated string.
|
|
||||||
*
|
|
||||||
* Supported on Windows NT 3.5 and newer.
|
|
||||||
*/
|
|
||||||
static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
|
|
||||||
char **outptr)
|
|
||||||
{
|
|
||||||
char enumKeyName[256];
|
|
||||||
DWORD enumKeyNameBuffSize;
|
|
||||||
DWORD enumKeyIdx = 0;
|
|
||||||
HKEY hKeyEnum;
|
|
||||||
int gotString;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
enumKeyNameBuffSize = sizeof(enumKeyName);
|
|
||||||
res = RegEnumKeyExA(hKeyParent, enumKeyIdx++, enumKeyName,
|
|
||||||
&enumKeyNameBuffSize, 0, NULL, NULL, NULL);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
break;
|
|
||||||
res = RegOpenKeyExA(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
|
|
||||||
&hKeyEnum);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
continue;
|
|
||||||
gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
|
|
||||||
RegCloseKey(hKeyEnum);
|
|
||||||
if (gotString)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*outptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get_DNS_Registry_9X()
|
|
||||||
*
|
|
||||||
* Functionally identical to get_DNS_Registry()
|
|
||||||
*
|
|
||||||
* Implementation supports Windows 95, 98 and ME.
|
|
||||||
*/
|
|
||||||
static int get_DNS_Registry_9X(char **outptr)
|
|
||||||
{
|
|
||||||
HKEY hKey_VxD_MStcp;
|
|
||||||
int gotString;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
|
|
||||||
res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
|
|
||||||
&hKey_VxD_MStcp);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
|
|
||||||
RegCloseKey(hKey_VxD_MStcp);
|
|
||||||
|
|
||||||
if (!gotString || !*outptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get_DNS_Registry_NT()
|
|
||||||
*
|
|
||||||
* Functionally identical to get_DNS_Registry()
|
|
||||||
*
|
|
||||||
* Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
|
|
||||||
*
|
|
||||||
* Implementation supports Windows NT 3.5 and newer.
|
|
||||||
*/
|
|
||||||
static int get_DNS_Registry_NT(char **outptr)
|
|
||||||
{
|
|
||||||
HKEY hKey_Interfaces = NULL;
|
|
||||||
HKEY hKey_Tcpip_Parameters;
|
|
||||||
int gotString;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
|
|
||||||
res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
|
|
||||||
&hKey_Tcpip_Parameters);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Global DNS settings override adapter specific parameters when both
|
|
||||||
** are set. Additionally static DNS settings override DHCP-configured
|
|
||||||
** parameters when both are set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Global DNS static parameters */
|
|
||||||
gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
|
|
||||||
if (gotString)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Global DNS DHCP-configured parameters */
|
|
||||||
gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
|
|
||||||
if (gotString)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Try adapter specific parameters */
|
|
||||||
res = RegOpenKeyExA(hKey_Tcpip_Parameters, "Interfaces", 0,
|
|
||||||
KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
|
|
||||||
&hKey_Interfaces);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
hKey_Interfaces = NULL;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Adapter specific DNS static parameters */
|
|
||||||
gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
|
|
||||||
if (gotString)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* Adapter specific DNS DHCP-configured parameters */
|
|
||||||
gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (hKey_Interfaces)
|
|
||||||
RegCloseKey(hKey_Interfaces);
|
|
||||||
|
|
||||||
RegCloseKey(hKey_Tcpip_Parameters);
|
|
||||||
|
|
||||||
if (!gotString || !*outptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* get_DNS_Registry()
|
|
||||||
*
|
|
||||||
* Locates DNS info in the registry. When located, this returns a pointer
|
|
||||||
* in *outptr to a newly allocated memory area holding a null-terminated
|
|
||||||
* string with a space or comma seperated list of DNS IP addresses.
|
|
||||||
*
|
|
||||||
* Returns 0 and nullifies *outptr upon inability to return DNSes string.
|
|
||||||
*
|
|
||||||
* Returns 1 and sets *outptr when returning a dynamically allocated string.
|
|
||||||
*/
|
|
||||||
static int get_DNS_Registry(char **outptr)
|
|
||||||
{
|
|
||||||
win_platform platform;
|
|
||||||
int gotString = 0;
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
|
|
||||||
platform = ares__getplatform();
|
|
||||||
|
|
||||||
if (platform == WIN_NT)
|
|
||||||
gotString = get_DNS_Registry_NT(outptr);
|
|
||||||
else if (platform == WIN_9X)
|
|
||||||
gotString = get_DNS_Registry_9X(outptr);
|
|
||||||
|
|
||||||
if (!gotString)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void commanjoin(char** dst, const char* const src, const size_t len)
|
static void commanjoin(char** dst, const char* const src, const size_t len)
|
||||||
{
|
{
|
||||||
char *newbuf;
|
char *newbuf;
|
||||||
|
@ -857,106 +672,6 @@ static void commajoin(char **dst, const char *src)
|
||||||
commanjoin(dst, src, strlen(src));
|
commanjoin(dst, src, strlen(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* get_DNS_NetworkParams()
|
|
||||||
*
|
|
||||||
* Locates DNS info using GetNetworkParams() function from the Internet
|
|
||||||
* Protocol Helper (IP Helper) API. When located, this returns a pointer
|
|
||||||
* in *outptr to a newly allocated memory area holding a null-terminated
|
|
||||||
* string with a space or comma seperated list of DNS IP addresses.
|
|
||||||
*
|
|
||||||
* Returns 0 and nullifies *outptr upon inability to return DNSes string.
|
|
||||||
*
|
|
||||||
* Returns 1 and sets *outptr when returning a dynamically allocated string.
|
|
||||||
*
|
|
||||||
* Implementation supports Windows 98 and newer.
|
|
||||||
*
|
|
||||||
* Note: Ancient PSDK required in order to build a W98 target.
|
|
||||||
*/
|
|
||||||
static int get_DNS_NetworkParams(char **outptr)
|
|
||||||
{
|
|
||||||
FIXED_INFO *fi, *newfi;
|
|
||||||
struct ares_addr namesrvr;
|
|
||||||
char *txtaddr;
|
|
||||||
IP_ADDR_STRING *ipAddr;
|
|
||||||
int res;
|
|
||||||
DWORD size = sizeof (*fi);
|
|
||||||
|
|
||||||
*outptr = NULL;
|
|
||||||
|
|
||||||
/* Verify run-time availability of GetNetworkParams() */
|
|
||||||
if (ares_fpGetNetworkParams == ZERO_NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fi = ares_malloc(size);
|
|
||||||
if (!fi)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
res = (*ares_fpGetNetworkParams) (fi, &size);
|
|
||||||
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
newfi = ares_realloc(fi, size);
|
|
||||||
if (!newfi)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
fi = newfi;
|
|
||||||
res = (*ares_fpGetNetworkParams) (fi, &size);
|
|
||||||
if (res != ERROR_SUCCESS)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
|
|
||||||
{
|
|
||||||
txtaddr = &ipAddr->IpAddress.String[0];
|
|
||||||
|
|
||||||
/* Validate converting textual address to binary format. */
|
|
||||||
if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
|
|
||||||
{
|
|
||||||
if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
|
|
||||||
(namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
|
|
||||||
{
|
|
||||||
if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
|
|
||||||
sizeof(namesrvr.addrV6)) == 0)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
|
|
||||||
commajoin(outptr, txtaddr);
|
|
||||||
|
|
||||||
if (!*outptr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (fi)
|
|
||||||
ares_free(fi);
|
|
||||||
|
|
||||||
if (!*outptr)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL ares_IsWindowsVistaOrGreater(void)
|
|
||||||
{
|
|
||||||
OSVERSIONINFO vinfo;
|
|
||||||
memset(&vinfo, 0, sizeof(vinfo));
|
|
||||||
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */
|
|
||||||
#endif
|
|
||||||
if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6)
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A structure to hold the string form of IPv4 and IPv6 addresses so we can
|
/* A structure to hold the string form of IPv4 and IPv6 addresses so we can
|
||||||
* sort them by a metric.
|
* sort them by a metric.
|
||||||
|
@ -1033,21 +748,20 @@ static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
|
||||||
/* On this interface, get the best route to that destination. */
|
/* On this interface, get the best route to that destination. */
|
||||||
MIB_IPFORWARD_ROW2 row;
|
MIB_IPFORWARD_ROW2 row;
|
||||||
SOCKADDR_INET ignored;
|
SOCKADDR_INET ignored;
|
||||||
if(!ares_fpGetBestRoute2 ||
|
if(GetBestRoute2(/* The interface to use. The index is ignored since we are
|
||||||
ares_fpGetBestRoute2(/* The interface to use. The index is ignored since we are
|
* passing a LUID.
|
||||||
* passing a LUID.
|
*/
|
||||||
*/
|
luid, 0,
|
||||||
luid, 0,
|
/* No specific source address. */
|
||||||
/* No specific source address. */
|
NULL,
|
||||||
NULL,
|
/* Our destination address. */
|
||||||
/* Our destination address. */
|
dest,
|
||||||
dest,
|
/* No options. */
|
||||||
/* No options. */
|
0,
|
||||||
0,
|
/* The route row. */
|
||||||
/* The route row. */
|
&row,
|
||||||
&row,
|
/* The best source address, which we don't need. */
|
||||||
/* The best source address, which we don't need. */
|
&ignored) != NO_ERROR
|
||||||
&ignored) != NO_ERROR
|
|
||||||
/* If the metric is "unused" (-1) or too large for us to add the two
|
/* If the metric is "unused" (-1) or too large for us to add the two
|
||||||
* metrics, use the worst possible, thus sorting this last.
|
* metrics, use the worst possible, thus sorting this last.
|
||||||
*/
|
*/
|
||||||
|
@ -1067,7 +781,7 @@ static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_DNS_AdaptersAddresses()
|
* get_DNS_Windows()
|
||||||
*
|
*
|
||||||
* Locates DNS info using GetAdaptersAddresses() function from the Internet
|
* Locates DNS info using GetAdaptersAddresses() function from the Internet
|
||||||
* Protocol Helper (IP Helper) API. When located, this returns a pointer
|
* Protocol Helper (IP Helper) API. When located, this returns a pointer
|
||||||
|
@ -1082,7 +796,7 @@ static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
|
||||||
*/
|
*/
|
||||||
#define IPAA_INITIAL_BUF_SZ 15 * 1024
|
#define IPAA_INITIAL_BUF_SZ 15 * 1024
|
||||||
#define IPAA_MAX_TRIES 3
|
#define IPAA_MAX_TRIES 3
|
||||||
static int get_DNS_AdaptersAddresses(char **outptr)
|
static int get_DNS_Windows(char **outptr)
|
||||||
{
|
{
|
||||||
IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
|
IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
|
||||||
IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
|
IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
|
||||||
|
@ -1107,10 +821,6 @@ static int get_DNS_AdaptersAddresses(char **outptr)
|
||||||
|
|
||||||
*outptr = NULL;
|
*outptr = NULL;
|
||||||
|
|
||||||
/* Verify run-time availability of GetAdaptersAddresses() */
|
|
||||||
if (ares_fpGetAdaptersAddresses == ZERO_NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ipaa = ares_malloc(Bufsz);
|
ipaa = ares_malloc(Bufsz);
|
||||||
if (!ipaa)
|
if (!ipaa)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1127,8 +837,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Usually this call suceeds with initial buffer size */
|
/* Usually this call suceeds with initial buffer size */
|
||||||
res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
|
res = GetAdaptersAddresses(AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz);
|
||||||
ipaa, &ReqBufsz);
|
|
||||||
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
|
if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -1142,8 +851,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
|
||||||
Bufsz = ReqBufsz;
|
Bufsz = ReqBufsz;
|
||||||
ipaa = newipaa;
|
ipaa = newipaa;
|
||||||
}
|
}
|
||||||
res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
|
res = GetAdaptersAddresses(AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz);
|
||||||
ipaa, &ReqBufsz);
|
|
||||||
if (res == ERROR_SUCCESS)
|
if (res == ERROR_SUCCESS)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1185,26 +893,17 @@ static int get_DNS_AdaptersAddresses(char **outptr)
|
||||||
addressesSize = newSize;
|
addressesSize = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vista required for Luid or Ipv4Metric */
|
addresses[addressesIndex].metric =
|
||||||
if (ares_IsWindowsVistaOrGreater())
|
getBestRouteMetric(&ipaaEntry->Luid,
|
||||||
{
|
(SOCKADDR_INET*)(namesrvr.sa),
|
||||||
/* Save the address as the next element in addresses. */
|
ipaaEntry->Ipv4Metric);
|
||||||
addresses[addressesIndex].metric =
|
|
||||||
getBestRouteMetric(&ipaaEntry->Luid,
|
|
||||||
(SOCKADDR_INET*)(namesrvr.sa),
|
|
||||||
ipaaEntry->Ipv4Metric);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addresses[addressesIndex].metric = (ULONG)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Record insertion index to make qsort stable */
|
/* Record insertion index to make qsort stable */
|
||||||
addresses[addressesIndex].orig_idx = addressesIndex;
|
addresses[addressesIndex].orig_idx = addressesIndex;
|
||||||
|
|
||||||
if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
|
if (!ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
|
||||||
addresses[addressesIndex].text,
|
addresses[addressesIndex].text,
|
||||||
sizeof(addresses[0].text))) {
|
sizeof(addresses[0].text))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++addressesIndex;
|
++addressesIndex;
|
||||||
|
@ -1227,26 +926,17 @@ static int get_DNS_AdaptersAddresses(char **outptr)
|
||||||
addressesSize = newSize;
|
addressesSize = newSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Vista required for Luid or Ipv4Metric */
|
addresses[addressesIndex].metric =
|
||||||
if (ares_IsWindowsVistaOrGreater())
|
getBestRouteMetric(&ipaaEntry->Luid,
|
||||||
{
|
(SOCKADDR_INET*)(namesrvr.sa),
|
||||||
/* Save the address as the next element in addresses. */
|
ipaaEntry->Ipv6Metric);
|
||||||
addresses[addressesIndex].metric =
|
|
||||||
getBestRouteMetric(&ipaaEntry->Luid,
|
|
||||||
(SOCKADDR_INET*)(namesrvr.sa),
|
|
||||||
ipaaEntry->Ipv6Metric);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
addresses[addressesIndex].metric = (ULONG)-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Record insertion index to make qsort stable */
|
/* Record insertion index to make qsort stable */
|
||||||
addresses[addressesIndex].orig_idx = addressesIndex;
|
addresses[addressesIndex].orig_idx = addressesIndex;
|
||||||
|
|
||||||
if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
|
if (!ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
|
||||||
addresses[addressesIndex].text,
|
addresses[addressesIndex].text,
|
||||||
sizeof(addresses[0].text))) {
|
sizeof(addresses[0].text))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++addressesIndex;
|
++addressesIndex;
|
||||||
|
@ -1294,35 +984,6 @@ done:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* get_DNS_Windows()
|
|
||||||
*
|
|
||||||
* Locates DNS info from Windows employing most suitable methods available at
|
|
||||||
* run-time no matter which Windows version it is. When located, this returns
|
|
||||||
* a pointer in *outptr to a newly allocated memory area holding a string with
|
|
||||||
* a space or comma seperated list of DNS IP addresses, null-terminated.
|
|
||||||
*
|
|
||||||
* Returns 0 and nullifies *outptr upon inability to return DNSes string.
|
|
||||||
*
|
|
||||||
* Returns 1 and sets *outptr when returning a dynamically allocated string.
|
|
||||||
*
|
|
||||||
* Implementation supports Windows 95 and newer.
|
|
||||||
*/
|
|
||||||
static int get_DNS_Windows(char **outptr)
|
|
||||||
{
|
|
||||||
/* Try using IP helper API GetAdaptersAddresses(). IPv4 + IPv6, also sorts
|
|
||||||
* DNS servers by interface route metrics to try to use the best DNS server. */
|
|
||||||
if (get_DNS_AdaptersAddresses(outptr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Try using IP helper API GetNetworkParams(). IPv4 only. */
|
|
||||||
if (get_DNS_NetworkParams(outptr))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Fall-back to registry information */
|
|
||||||
return get_DNS_Registry(outptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_SuffixList_Windows()
|
* get_SuffixList_Windows()
|
||||||
*
|
*
|
||||||
|
@ -1686,8 +1347,12 @@ static int init_by_resolv_conf(ares_channel channel)
|
||||||
channel->tries = res.retry;
|
channel->tries = res.retry;
|
||||||
if (channel->rotate == -1)
|
if (channel->rotate == -1)
|
||||||
channel->rotate = res.options & RES_ROTATE;
|
channel->rotate = res.options & RES_ROTATE;
|
||||||
if (channel->timeout == -1)
|
if (channel->timeout == -1) {
|
||||||
channel->timeout = res.retrans * 1000;
|
channel->timeout = res.retrans * 1000;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
channel->timeout /= (res.retry + 1) * (res.nscount > 0 ? res.nscount : 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
res_ndestroy(&res);
|
res_ndestroy(&res);
|
||||||
}
|
}
|
||||||
|
@ -2021,6 +1686,11 @@ static int init_by_defaults(ares_channel channel)
|
||||||
ares_free(channel->resolvconf_path);
|
ares_free(channel->resolvconf_path);
|
||||||
channel->resolvconf_path = NULL;
|
channel->resolvconf_path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(channel->hosts_path) {
|
||||||
|
ares_free(channel->hosts_path);
|
||||||
|
channel->hosts_path = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(hostname)
|
if(hostname)
|
||||||
|
@ -2243,6 +1913,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||||
q = str;
|
q = str;
|
||||||
while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
|
while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
|
||||||
q++;
|
q++;
|
||||||
|
if (q-str >= 16)
|
||||||
|
return ARES_EBADSTR;
|
||||||
memcpy(ipbuf, str, q-str);
|
memcpy(ipbuf, str, q-str);
|
||||||
ipbuf[q-str] = '\0';
|
ipbuf[q-str] = '\0';
|
||||||
/* Find the prefix */
|
/* Find the prefix */
|
||||||
|
@ -2251,6 +1923,8 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||||
const char *str2 = q+1;
|
const char *str2 = q+1;
|
||||||
while (*q && *q != ';' && !ISSPACE(*q))
|
while (*q && *q != ';' && !ISSPACE(*q))
|
||||||
q++;
|
q++;
|
||||||
|
if (q-str >= 32)
|
||||||
|
return ARES_EBADSTR;
|
||||||
memcpy(ipbufpfx, str, q-str);
|
memcpy(ipbufpfx, str, q-str);
|
||||||
ipbufpfx[q-str] = '\0';
|
ipbufpfx[q-str] = '\0';
|
||||||
str = str2;
|
str = str2;
|
||||||
|
@ -2325,12 +1999,12 @@ static int set_search(ares_channel channel, const char *str)
|
||||||
if(channel->ndomains != -1) {
|
if(channel->ndomains != -1) {
|
||||||
/* LCOV_EXCL_START: all callers check ndomains == -1 */
|
/* LCOV_EXCL_START: all callers check ndomains == -1 */
|
||||||
/* if we already have some domains present, free them first */
|
/* if we already have some domains present, free them first */
|
||||||
ares_strsplit_free(channel->domains, channel->ndomains);
|
ares__strsplit_free(channel->domains, channel->ndomains);
|
||||||
channel->domains = NULL;
|
channel->domains = NULL;
|
||||||
channel->ndomains = -1;
|
channel->ndomains = -1;
|
||||||
} /* LCOV_EXCL_STOP */
|
} /* LCOV_EXCL_STOP */
|
||||||
|
|
||||||
channel->domains = ares_strsplit(str, ", ", 1, &cnt);
|
channel->domains = ares__strsplit(str, ", ", &cnt);
|
||||||
channel->ndomains = (int)cnt;
|
channel->ndomains = (int)cnt;
|
||||||
if (channel->domains == NULL || channel->ndomains == 0) {
|
if (channel->domains == NULL || channel->ndomains == 0) {
|
||||||
channel->domains = NULL;
|
channel->domains = NULL;
|
||||||
|
@ -2495,12 +2169,10 @@ static int sortlist_alloc(struct apattern **sortlist, int *nsort,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* initialize an rc4 key. If possible a cryptographically secure random key
|
/* initialize an rc4 key. If possible a cryptographically secure random key
|
||||||
is generated using a suitable function (for example win32's RtlGenRandom as
|
is generated using a suitable function otherwise the code defaults to
|
||||||
described in
|
cross-platform albeit less secure mechanism using rand
|
||||||
http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
|
|
||||||
otherwise the code defaults to cross-platform albeit less secure mechanism
|
|
||||||
using rand
|
|
||||||
*/
|
*/
|
||||||
static void randomize_key(unsigned char* key,int key_data_len)
|
static void randomize_key(unsigned char* key,int key_data_len)
|
||||||
{
|
{
|
||||||
|
@ -2508,21 +2180,20 @@ static void randomize_key(unsigned char* key,int key_data_len)
|
||||||
int counter=0;
|
int counter=0;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
BOOLEAN res;
|
BOOLEAN res;
|
||||||
if (ares_fpSystemFunction036)
|
|
||||||
{
|
res = RtlGenRandom(key, key_data_len);
|
||||||
res = (*ares_fpSystemFunction036) (key, key_data_len);
|
if (res)
|
||||||
if (res)
|
randomized = 1;
|
||||||
randomized = 1;
|
|
||||||
}
|
|
||||||
#else /* !WIN32 */
|
#else /* !WIN32 */
|
||||||
#ifdef CARES_RANDOM_FILE
|
# ifdef CARES_RANDOM_FILE
|
||||||
FILE *f = fopen(CARES_RANDOM_FILE, "rb");
|
FILE *f = fopen(CARES_RANDOM_FILE, "rb");
|
||||||
if(f) {
|
if(f) {
|
||||||
setvbuf(f, NULL, _IONBF, 0);
|
setvbuf(f, NULL, _IONBF, 0);
|
||||||
counter = aresx_uztosi(fread(key, 1, key_data_len, f));
|
counter = aresx_uztosi(fread(key, 1, key_data_len, f));
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
#endif
|
# endif
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
if (!randomized) {
|
if (!randomized) {
|
||||||
|
|
|
@ -18,18 +18,10 @@
|
||||||
#include "ares_setup.h"
|
#include "ares_setup.h"
|
||||||
|
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_library_init.h"
|
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
/* library-private global and unique instance vars */
|
/* library-private global and unique instance vars */
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL;
|
|
||||||
fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL;
|
|
||||||
fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL;
|
|
||||||
fpGetBestRoute2_t ares_fpGetBestRoute2 = ZERO_NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ANDROID) || defined(__ANDROID__)
|
#if defined(ANDROID) || defined(__ANDROID__)
|
||||||
#include "ares_android.h"
|
#include "ares_android.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -59,81 +51,8 @@ void *(*ares_malloc)(size_t size) = default_malloc;
|
||||||
void *(*ares_realloc)(void *ptr, size_t size) = default_realloc;
|
void *(*ares_realloc)(void *ptr, size_t size) = default_realloc;
|
||||||
void (*ares_free)(void *ptr) = default_free;
|
void (*ares_free)(void *ptr) = default_free;
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
static HMODULE hnd_iphlpapi;
|
|
||||||
static HMODULE hnd_advapi32;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static int ares_win32_init(void)
|
|
||||||
{
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
|
|
||||||
hnd_iphlpapi = 0;
|
|
||||||
hnd_iphlpapi = LoadLibraryW(L"iphlpapi.dll");
|
|
||||||
if (!hnd_iphlpapi)
|
|
||||||
return ARES_ELOADIPHLPAPI;
|
|
||||||
|
|
||||||
ares_fpGetNetworkParams = (fpGetNetworkParams_t)
|
|
||||||
GetProcAddress(hnd_iphlpapi, "GetNetworkParams");
|
|
||||||
if (!ares_fpGetNetworkParams)
|
|
||||||
{
|
|
||||||
FreeLibrary(hnd_iphlpapi);
|
|
||||||
return ARES_EADDRGETNETWORKPARAMS;
|
|
||||||
}
|
|
||||||
|
|
||||||
ares_fpGetAdaptersAddresses = (fpGetAdaptersAddresses_t)
|
|
||||||
GetProcAddress(hnd_iphlpapi, "GetAdaptersAddresses");
|
|
||||||
if (!ares_fpGetAdaptersAddresses)
|
|
||||||
{
|
|
||||||
/* This can happen on clients before WinXP, I don't
|
|
||||||
think it should be an error, unless we don't want to
|
|
||||||
support Windows 2000 anymore */
|
|
||||||
}
|
|
||||||
|
|
||||||
ares_fpGetBestRoute2 = (fpGetBestRoute2_t)
|
|
||||||
GetProcAddress(hnd_iphlpapi, "GetBestRoute2");
|
|
||||||
if (!ares_fpGetBestRoute2)
|
|
||||||
{
|
|
||||||
/* This can happen on clients before Vista, I don't
|
|
||||||
think it should be an error, unless we don't want to
|
|
||||||
support Windows XP anymore */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036,
|
|
||||||
* also known as RtlGenRandom, which is the case for Windows versions prior
|
|
||||||
* to WinXP then c-ares uses portable rand() function. Then don't error here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
hnd_advapi32 = 0;
|
|
||||||
hnd_advapi32 = LoadLibraryW(L"advapi32.dll");
|
|
||||||
if (hnd_advapi32)
|
|
||||||
{
|
|
||||||
ares_fpSystemFunction036 = (fpSystemFunction036_t)
|
|
||||||
GetProcAddress(hnd_advapi32, "SystemFunction036");
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
return ARES_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ares_win32_cleanup(void)
|
|
||||||
{
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
if (hnd_advapi32)
|
|
||||||
FreeLibrary(hnd_advapi32);
|
|
||||||
if (hnd_iphlpapi)
|
|
||||||
FreeLibrary(hnd_iphlpapi);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ares_library_init(int flags)
|
int ares_library_init(int flags)
|
||||||
{
|
{
|
||||||
int res;
|
|
||||||
|
|
||||||
if (ares_initialized)
|
if (ares_initialized)
|
||||||
{
|
{
|
||||||
ares_initialized++;
|
ares_initialized++;
|
||||||
|
@ -141,12 +60,7 @@ int ares_library_init(int flags)
|
||||||
}
|
}
|
||||||
ares_initialized++;
|
ares_initialized++;
|
||||||
|
|
||||||
if (flags & ARES_LIB_INIT_WIN32)
|
/* NOTE: ARES_LIB_INIT_WIN32 flag no longer used */
|
||||||
{
|
|
||||||
res = ares_win32_init();
|
|
||||||
if (res != ARES_SUCCESS)
|
|
||||||
return res; /* LCOV_EXCL_LINE: can't test Win32 init failure */
|
|
||||||
}
|
|
||||||
|
|
||||||
ares_init_flags = flags;
|
ares_init_flags = flags;
|
||||||
|
|
||||||
|
@ -176,8 +90,7 @@ void ares_library_cleanup(void)
|
||||||
if (ares_initialized)
|
if (ares_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ares_init_flags & ARES_LIB_INIT_WIN32)
|
/* NOTE: ARES_LIB_INIT_WIN32 flag no longer used */
|
||||||
ares_win32_cleanup();
|
|
||||||
|
|
||||||
#if defined(ANDROID) || defined(__ANDROID__)
|
#if defined(ANDROID) || defined(__ANDROID__)
|
||||||
ares_library_cleanup_android();
|
ares_library_cleanup_android();
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
#ifndef HEADER_CARES_LIBRARY_INIT_H
|
|
||||||
#define HEADER_CARES_LIBRARY_INIT_H
|
|
||||||
|
|
||||||
|
|
||||||
/* Copyright 1998 by the Massachusetts Institute of Technology.
|
|
||||||
* Copyright (C) 2004-2011 by Daniel Stenberg
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this
|
|
||||||
* software and its documentation for any purpose and without
|
|
||||||
* fee is hereby granted, provided that the above copyright
|
|
||||||
* notice appear in all copies and that both that copyright
|
|
||||||
* notice and this permission notice appear in supporting
|
|
||||||
* documentation, and that the name of M.I.T. not be used in
|
|
||||||
* advertising or publicity pertaining to distribution of the
|
|
||||||
* software without specific, written prior permission.
|
|
||||||
* M.I.T. makes no representations about the suitability of
|
|
||||||
* this software for any purpose. It is provided "as is"
|
|
||||||
* without express or implied warranty.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ares_setup.h"
|
|
||||||
|
|
||||||
#ifdef USE_WINSOCK
|
|
||||||
|
|
||||||
#include <iphlpapi.h>
|
|
||||||
#include "ares_iphlpapi.h"
|
|
||||||
|
|
||||||
typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*);
|
|
||||||
typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG);
|
|
||||||
typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* );
|
|
||||||
typedef NETIO_STATUS (WINAPI *fpGetBestRoute2_t) ( NET_LUID *, NET_IFINDEX, const SOCKADDR_INET *, const SOCKADDR_INET *, ULONG, PMIB_IPFORWARD_ROW2, SOCKADDR_INET * );
|
|
||||||
/* Forward-declaration of variables defined in ares_library_init.c */
|
|
||||||
/* that are global and unique instances for whole c-ares library. */
|
|
||||||
|
|
||||||
extern fpGetNetworkParams_t ares_fpGetNetworkParams;
|
|
||||||
extern fpSystemFunction036_t ares_fpSystemFunction036;
|
|
||||||
extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses;
|
|
||||||
extern fpGetBestRoute2_t ares_fpGetBestRoute2;
|
|
||||||
|
|
||||||
#endif /* USE_WINSOCK */
|
|
||||||
|
|
||||||
#endif /* HEADER_CARES_LIBRARY_INIT_H */
|
|
||||||
|
|
|
@ -339,6 +339,9 @@ struct ares_channeldata {
|
||||||
|
|
||||||
/* Path for resolv.conf file, configurable via ares_options */
|
/* Path for resolv.conf file, configurable via ares_options */
|
||||||
char *resolvconf_path;
|
char *resolvconf_path;
|
||||||
|
|
||||||
|
/* Path for hosts file, configurable via ares_options */
|
||||||
|
char *hosts_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Does the domain end in ".onion" or ".onion."? Case-insensitive. */
|
/* Does the domain end in ".onion" or ".onion."? Case-insensitive. */
|
||||||
|
|
|
@ -209,6 +209,17 @@ static void write_tcp_data(ares_channel channel,
|
||||||
ares_ssize_t scount;
|
ares_ssize_t scount;
|
||||||
ares_ssize_t wcount;
|
ares_ssize_t wcount;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
/* From writev manpage: An implementation can advertise its limit by defining
|
||||||
|
IOV_MAX in <limits.h> or at run time via the return value from
|
||||||
|
sysconf(_SC_IOV_MAX). On modern Linux systems, the limit is 1024. Back in
|
||||||
|
Linux 2.0 days, this limit was 16. */
|
||||||
|
#if defined(IOV_MAX)
|
||||||
|
const size_t maxn = IOV_MAX; /* FreeBSD */
|
||||||
|
#elif defined(_SC_IOV_MAX)
|
||||||
|
const size_t maxn = sysconf(_SC_IOV_MAX); /* Linux */
|
||||||
|
#else
|
||||||
|
const size_t maxn = 16; /* Safe default */
|
||||||
|
#endif
|
||||||
|
|
||||||
if(!write_fds && (write_fd == ARES_SOCKET_BAD))
|
if(!write_fds && (write_fd == ARES_SOCKET_BAD))
|
||||||
/* no possible action */
|
/* no possible action */
|
||||||
|
@ -256,6 +267,8 @@ static void write_tcp_data(ares_channel channel,
|
||||||
vec[n].iov_base = (char *) sendreq->data;
|
vec[n].iov_base = (char *) sendreq->data;
|
||||||
vec[n].iov_len = sendreq->len;
|
vec[n].iov_len = sendreq->len;
|
||||||
n++;
|
n++;
|
||||||
|
if(n >= maxn)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
wcount = socket_writev(channel, server->tcp_socket, vec, (int)n);
|
wcount = socket_writev(channel, server->tcp_socket, vec, (int)n);
|
||||||
ares_free(vec);
|
ares_free(vec);
|
||||||
|
|
|
@ -22,47 +22,7 @@
|
||||||
#include "ares.h"
|
#include "ares.h"
|
||||||
#include "ares_private.h"
|
#include "ares_private.h"
|
||||||
|
|
||||||
static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive)
|
void ares__strsplit_free(char **elms, size_t num_elm)
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
len = strlen(str);
|
|
||||||
for (i=0; i<num_elem; i++)
|
|
||||||
{
|
|
||||||
if (insensitive)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
if (strnicmp(list[i], str, len) == 0)
|
|
||||||
#else
|
|
||||||
if (strncasecmp(list[i], str, len) == 0)
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (strncmp(list[i], str, len) == 0)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_delim(char c, const char *delims, size_t num_delims)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i=0; i<num_delims; i++)
|
|
||||||
{
|
|
||||||
if (c == delims[i])
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ares_strsplit_free(char **elms, size_t num_elm)
|
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
@ -74,105 +34,67 @@ void ares_strsplit_free(char **elms, size_t num_elm)
|
||||||
ares_free(elms);
|
ares_free(elms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **ares__strsplit(const char *in, const char *delms, size_t *num_elm) {
|
||||||
char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm)
|
const char *p;
|
||||||
{
|
char **table;
|
||||||
char *parsestr;
|
void *tmp;
|
||||||
char **temp;
|
size_t i, j, k, count;
|
||||||
char **out;
|
|
||||||
size_t cnt;
|
|
||||||
size_t nelms;
|
|
||||||
size_t in_len;
|
|
||||||
size_t num_delims;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (in == NULL || delms == NULL || num_elm == NULL)
|
if (in == NULL || delms == NULL || num_elm == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
*num_elm = 0;
|
*num_elm = 0;
|
||||||
|
|
||||||
in_len = strlen(in);
|
/* count non-empty delimited substrings */
|
||||||
num_delims = strlen(delms);
|
count = 0;
|
||||||
|
p = in;
|
||||||
|
do {
|
||||||
|
i = strcspn(p, delms);
|
||||||
|
if (i != 0) {
|
||||||
|
/* string is non-empty */
|
||||||
|
count++;
|
||||||
|
p += i;
|
||||||
|
}
|
||||||
|
} while(*p++ != 0);
|
||||||
|
|
||||||
/* Figure out how many elements. */
|
if (count == 0)
|
||||||
nelms = 1;
|
return NULL;
|
||||||
for (i=0; i<in_len; i++)
|
table = ares_malloc(count * sizeof(*table));
|
||||||
{
|
if (table == NULL)
|
||||||
if (is_delim(in[i], delms, num_delims))
|
return NULL;
|
||||||
{
|
|
||||||
nelms++;
|
j = 0; /* current table entry */
|
||||||
|
/* re-calculate indices and allocate new strings for table */
|
||||||
|
for (p = in; j < count; p += i + 1) {
|
||||||
|
i = strcspn(p, delms);
|
||||||
|
if (i != 0) {
|
||||||
|
for (k = 0; k < j; k++) {
|
||||||
|
#ifdef WIN32
|
||||||
|
if (strnicmp(table[k], p, i) == 0 && table[k][i] == 0)
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
if (strncasecmp(table[k], p, i) == 0 && table[k][i] == 0)
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (k == j) {
|
||||||
|
/* copy unique strings only */
|
||||||
|
table[j] = ares_malloc(i + 1);
|
||||||
|
if (table[j] == NULL) {
|
||||||
|
ares__strsplit_free(table, j);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
strncpy(table[j], p, i);
|
||||||
|
table[j++][i] = 0;
|
||||||
|
} else
|
||||||
|
count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy of input so we can cut it up. */
|
tmp = ares_realloc(table, count * sizeof (*table));
|
||||||
parsestr = ares_strdup(in);
|
if (tmp != NULL)
|
||||||
if (parsestr == NULL)
|
table = tmp;
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Temporary array to store locations of start of each element
|
*num_elm = count;
|
||||||
* within parsestr. */
|
return table;
|
||||||
temp = ares_malloc(nelms * sizeof(*temp));
|
|
||||||
if (temp == NULL)
|
|
||||||
{
|
|
||||||
ares_free(parsestr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
temp[0] = parsestr;
|
|
||||||
cnt = 1;
|
|
||||||
for (i=0; i<in_len && cnt<nelms; i++)
|
|
||||||
{
|
|
||||||
if (!is_delim(parsestr[i], delms, num_delims))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Replace sep with NULL. */
|
|
||||||
parsestr[i] = '\0';
|
|
||||||
/* Add the pointer to the array of elements */
|
|
||||||
temp[cnt] = parsestr+i+1;
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy each element to our output array. */
|
|
||||||
out = ares_malloc(nelms * sizeof(*out));
|
|
||||||
if (out == NULL)
|
|
||||||
{
|
|
||||||
ares_free(parsestr);
|
|
||||||
ares_free(temp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
nelms = 0;
|
|
||||||
for (i=0; i<cnt; i++)
|
|
||||||
{
|
|
||||||
if (temp[i][0] == '\0')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (make_set && list_contains(out, nelms, temp[i], 1))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
out[nelms] = ares_strdup(temp[i]);
|
|
||||||
if (out[nelms] == NULL)
|
|
||||||
{
|
|
||||||
ares_strsplit_free(out, nelms);
|
|
||||||
ares_free(parsestr);
|
|
||||||
ares_free(temp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
nelms++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If there are no elements don't return an empty allocated
|
|
||||||
* array. */
|
|
||||||
if (nelms == 0)
|
|
||||||
{
|
|
||||||
ares_strsplit_free(out, nelms);
|
|
||||||
out = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the true number of elements (recalculated because of make_set) */
|
|
||||||
*num_elm = nelms;
|
|
||||||
|
|
||||||
ares_free(parsestr);
|
|
||||||
ares_free(temp);
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,25 +18,24 @@
|
||||||
|
|
||||||
#include "ares_setup.h"
|
#include "ares_setup.h"
|
||||||
|
|
||||||
/* Split a string on delem skipping empty elements.
|
/* Split a string on delms skipping empty or duplicate elements.
|
||||||
*
|
*
|
||||||
* param in String to split.
|
* param in String to split.
|
||||||
* param delims String of characters to treat as a delimitor.
|
* param delms String of characters to treat as a delimitor.
|
||||||
* Each character in the string is a delimitor so
|
* Each character in the string is a delimitor so
|
||||||
* there can be multiple delimitors to split on.
|
* there can be multiple delimitors to split on.
|
||||||
* E.g. ", " will split on all comma's and spaces.
|
* E.g. ", " will split on all comma's and spaces.
|
||||||
* param make_set Have the list be a Set where there are no
|
* Duplicate entries are removed.
|
||||||
* duplicate entries. 1 for true, 0 or false.
|
|
||||||
* param num_elm Return parameter of the number of elements
|
* param num_elm Return parameter of the number of elements
|
||||||
* in the result array.
|
* in the result array.
|
||||||
*
|
*
|
||||||
* returns an allocated array of allocated string elements.
|
* returns an allocated array of allocated string elements.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm);
|
char **ares__strsplit(const char *in, const char *delms, size_t *num_elm);
|
||||||
|
|
||||||
/* Frees the result returned from ares_strsplit(). */
|
/* Frees the result returned from ares__strsplit(). */
|
||||||
void ares_strsplit_free(char **elms, size_t num_elm);
|
void ares__strsplit_free(char **elms, size_t num_elm);
|
||||||
|
|
||||||
|
|
||||||
#endif /* HEADER_CARES_STRSPLIT_H */
|
#endif /* HEADER_CARES_STRSPLIT_H */
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// require C++17+
|
||||||
#ifndef SIMDSOFT__NTCVT_HPP
|
#ifndef SIMDSOFT__NTCVT_HPP
|
||||||
#define SIMDSOFT__NTCVT_HPP
|
#define SIMDSOFT__NTCVT_HPP
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ public:
|
||||||
// std::string: use memset (usually implemented with SIMD)
|
// std::string: use memset (usually implemented with SIMD)
|
||||||
// std::wstring: for loop (slow performance)
|
// std::wstring: for loop (slow performance)
|
||||||
// only works on msvc currently
|
// only works on msvc currently
|
||||||
_Elem* resize_nofill(size_t len)
|
_Elem* resize_for_overwrite(size_t len)
|
||||||
{
|
{
|
||||||
this->reserve(len);
|
this->reserve(len);
|
||||||
#if _MSC_VER >= 1920 // VS2019+
|
#if _MSC_VER >= 1920 // VS2019+
|
||||||
|
@ -62,7 +63,7 @@ auto prepare(_Cont& str, size_t size)
|
||||||
{
|
{
|
||||||
using _Elem = typename _Cont::value_type;
|
using _Elem = typename _Cont::value_type;
|
||||||
intrusive_string<_Elem>& helper = (intrusive_string<_Elem>&)str;
|
intrusive_string<_Elem>& helper = (intrusive_string<_Elem>&)str;
|
||||||
return helper.resize_nofill(size);
|
return helper.resize_for_overwrite(size);
|
||||||
}
|
}
|
||||||
#if defined(_AFX)
|
#if defined(_AFX)
|
||||||
template <> inline
|
template <> inline
|
||||||
|
@ -130,12 +131,12 @@ inline wchar_t* mcbs2wdup(const char* mcb, int len, int* wbuf_len, UINT cp = NTC
|
||||||
#if _HAS_CXX17
|
#if _HAS_CXX17
|
||||||
inline std::string from_chars(const std::wstring_view& wcb, UINT cp = NTCVT_CP_DEFAULT)
|
inline std::string from_chars(const std::wstring_view& wcb, UINT cp = NTCVT_CP_DEFAULT)
|
||||||
{
|
{
|
||||||
return wcbs2a<std::string>(wcb.data(), wcb.length(), cp);
|
return wcbs2a<std::string>(wcb.data(), static_cast<int>(wcb.length()), cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::wstring from_chars(const std::string_view& mcb, UINT cp = NTCVT_CP_DEFAULT)
|
inline std::wstring from_chars(const std::string_view& mcb, UINT cp = NTCVT_CP_DEFAULT)
|
||||||
{
|
{
|
||||||
return mcbs2w<std::wstring>(mcb.data(), mcb.length(), cp);
|
return mcbs2w<std::wstring>(mcb.data(), static_cast<int>(mcb.length()), cp);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline std::string from_chars(const std::wstring& wcb, UINT cp = NTCVT_CP_DEFAULT)
|
inline std::string from_chars(const std::wstring& wcb, UINT cp = NTCVT_CP_DEFAULT)
|
||||||
|
@ -170,7 +171,7 @@ namespace afx
|
||||||
# if _HAS_CXX17
|
# if _HAS_CXX17
|
||||||
inline CStringW from_chars(std::string_view mcb, UINT cp = NTCVT_CP_DEFAULT)
|
inline CStringW from_chars(std::string_view mcb, UINT cp = NTCVT_CP_DEFAULT)
|
||||||
{
|
{
|
||||||
return mcbs2w<CStringW>(mcb.data(), mcb.length(), cp);
|
return mcbs2w<CStringW>(mcb.data(), static_cast<int>(mcb.length()), cp);
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
inline CStringW from_chars(const char* str, UINT cp = NTCVT_CP_DEFAULT)
|
inline CStringW from_chars(const char* str, UINT cp = NTCVT_CP_DEFAULT)
|
||||||
|
@ -179,7 +180,7 @@ inline CStringW from_chars(const char* str, UINT cp = NTCVT_CP_DEFAULT)
|
||||||
}
|
}
|
||||||
inline CStringW from_chars(const std::string& mcb, UINT cp = NTCVT_CP_DEFAULT)
|
inline CStringW from_chars(const std::string& mcb, UINT cp = NTCVT_CP_DEFAULT)
|
||||||
{
|
{
|
||||||
return mcbs2w<CStringW>(mcb.c_str(), mcb.length(), cp);
|
return mcbs2w<CStringW>(mcb.c_str(), static_cast<int>(mcb.length()), cp);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
} // namespace afx
|
} // namespace afx
|
||||||
|
|
|
@ -30,6 +30,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||||
|
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||||
|
|
||||||
if(COMMAND CMAKE_POLICY)
|
if(COMMAND CMAKE_POLICY)
|
||||||
cmake_policy(SET CMP0003 NEW)
|
cmake_policy(SET CMP0003 NEW)
|
||||||
cmake_policy(SET CMP0005 NEW)
|
cmake_policy(SET CMP0005 NEW)
|
||||||
|
@ -42,6 +45,12 @@ if(COMMAND CMAKE_POLICY)
|
||||||
if(POLICY CMP0054)
|
if(POLICY CMP0054)
|
||||||
cmake_policy(SET CMP0054 NEW)
|
cmake_policy(SET CMP0054 NEW)
|
||||||
endif(POLICY CMP0054)
|
endif(POLICY CMP0054)
|
||||||
|
if(POLICY CMP0058)
|
||||||
|
cmake_policy(SET CMP0058 NEW)
|
||||||
|
endif(POLICY CMP0058)
|
||||||
|
if(POLICY CMP0063)
|
||||||
|
cmake_policy(SET CMP0063 NEW)
|
||||||
|
endif(POLICY CMP0063)
|
||||||
if(POLICY CMP0075)
|
if(POLICY CMP0075)
|
||||||
cmake_policy(SET CMP0075 NEW)
|
cmake_policy(SET CMP0075 NEW)
|
||||||
endif(POLICY CMP0075)
|
endif(POLICY CMP0075)
|
||||||
|
@ -161,8 +170,8 @@ if(NOT LIBTYPE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(LIB_MAJOR_VERSION "1")
|
set(LIB_MAJOR_VERSION "1")
|
||||||
set(LIB_MINOR_VERSION "22")
|
set(LIB_MINOR_VERSION "23")
|
||||||
set(LIB_REVISION "2")
|
set(LIB_REVISION "0")
|
||||||
set(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}")
|
set(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_REVISION}")
|
||||||
set(LIB_VERSION_NUM ${LIB_MAJOR_VERSION},${LIB_MINOR_VERSION},${LIB_REVISION},0)
|
set(LIB_VERSION_NUM ${LIB_MAJOR_VERSION},${LIB_MINOR_VERSION},${LIB_REVISION},0)
|
||||||
|
|
||||||
|
@ -170,7 +179,7 @@ set(EXPORT_DECL "")
|
||||||
|
|
||||||
|
|
||||||
# Require C++14
|
# Require C++14
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||||
|
|
||||||
# Prefer C11, but support C99 and C90 too.
|
# Prefer C11, but support C99 and C90 too.
|
||||||
|
@ -230,7 +239,7 @@ if(MSVC)
|
||||||
if(HAVE_PERMISSIVE_SWITCH)
|
if(HAVE_PERMISSIVE_SWITCH)
|
||||||
set(C_FLAGS ${C_FLAGS} $<$<COMPILE_LANGUAGE:CXX>:/permissive->)
|
set(C_FLAGS ${C_FLAGS} $<$<COMPILE_LANGUAGE:CXX>:/permissive->)
|
||||||
endif()
|
endif()
|
||||||
set(C_FLAGS ${C_FLAGS} /W4 /w14640 /wd4065 /wd4127 /wd4268 /wd4324 /wd5030)
|
set(C_FLAGS ${C_FLAGS} /W4 /w14640 /wd4065 /wd4127 /wd4268 /wd4324 /wd5030 /wd5051)
|
||||||
|
|
||||||
if(NOT DXSDK_DIR)
|
if(NOT DXSDK_DIR)
|
||||||
string(REGEX REPLACE "\\\\" "/" DXSDK_DIR "$ENV{DXSDK_DIR}")
|
string(REGEX REPLACE "\\\\" "/" DXSDK_DIR "$ENV{DXSDK_DIR}")
|
||||||
|
@ -258,6 +267,16 @@ else()
|
||||||
-Wpedantic
|
-Wpedantic
|
||||||
$<$<COMPILE_LANGUAGE:CXX>:-Wold-style-cast -Wnon-virtual-dtor -Woverloaded-virtual>)
|
$<$<COMPILE_LANGUAGE:CXX>:-Wold-style-cast -Wnon-virtual-dtor -Woverloaded-virtual>)
|
||||||
|
|
||||||
|
check_cxx_compiler_flag(-Wno-c++20-attribute-extensions HAVE_WNO_CXX20_ATTR_EXT)
|
||||||
|
if(HAVE_WNO_CXX20_ATTR_EXT)
|
||||||
|
set(C_FLAGS ${C_FLAGS} $<$<COMPILE_LANGUAGE:CXX>:-Wno-c++20-attribute-extensions>)
|
||||||
|
else()
|
||||||
|
check_cxx_compiler_flag(-Wno-c++20-extensions HAVE_WNO_CXX20_EXT)
|
||||||
|
if(HAVE_WNO_CXX20_EXT)
|
||||||
|
set(C_FLAGS ${C_FLAGS} $<$<COMPILE_LANGUAGE:CXX>:-Wno-c++20-extensions>)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(ALSOFT_WERROR)
|
if(ALSOFT_WERROR)
|
||||||
set(C_FLAGS ${C_FLAGS} -Werror)
|
set(C_FLAGS ${C_FLAGS} -Werror)
|
||||||
endif()
|
endif()
|
||||||
|
@ -346,13 +365,6 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(HAVE_GCC_PROTECTED_VISIBILITY OR HAVE_GCC_DEFAULT_VISIBILITY)
|
|
||||||
check_c_compiler_flag(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN_SWITCH)
|
|
||||||
if(HAVE_VISIBILITY_HIDDEN_SWITCH)
|
|
||||||
set(C_FLAGS ${C_FLAGS} -fvisibility=hidden)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}")
|
set(CMAKE_REQUIRED_FLAGS "${OLD_REQUIRED_FLAGS}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -472,7 +484,7 @@ if(CMAKE_SIZEOF_VOID_P MATCHES "4" AND HAVE_SSE2)
|
||||||
# assumes the stack is suitably aligned. Older Linux code or other
|
# assumes the stack is suitably aligned. Older Linux code or other
|
||||||
# OSs don't guarantee this on 32-bit, so externally-callable
|
# OSs don't guarantee this on 32-bit, so externally-callable
|
||||||
# functions need to ensure an aligned stack.
|
# functions need to ensure an aligned stack.
|
||||||
set(EXPORT_DECL "${EXPORT_DECL} __attribute__((force_align_arg_pointer))")
|
set(EXPORT_DECL "${EXPORT_DECL}__attribute__((force_align_arg_pointer))")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -1051,8 +1063,8 @@ if(PULSEAUDIO_FOUND)
|
||||||
set(HAVE_PULSEAUDIO 1)
|
set(HAVE_PULSEAUDIO 1)
|
||||||
set(BACKENDS "${BACKENDS} PulseAudio${IS_LINKED},")
|
set(BACKENDS "${BACKENDS} PulseAudio${IS_LINKED},")
|
||||||
set(ALC_OBJS ${ALC_OBJS} alc/backends/pulseaudio.cpp alc/backends/pulseaudio.h)
|
set(ALC_OBJS ${ALC_OBJS} alc/backends/pulseaudio.cpp alc/backends/pulseaudio.h)
|
||||||
add_backend_libs(${PULSEAUDIO_LIBRARIES})
|
add_backend_libs(${PULSEAUDIO_LIBRARY})
|
||||||
set(INC_PATHS ${INC_PATHS} ${PULSEAUDIO_INCLUDE_DIRS})
|
set(INC_PATHS ${INC_PATHS} ${PULSEAUDIO_INCLUDE_DIR})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(ALSOFT_REQUIRE_PULSEAUDIO AND NOT HAVE_PULSEAUDIO)
|
if(ALSOFT_REQUIRE_PULSEAUDIO AND NOT HAVE_PULSEAUDIO)
|
||||||
|
@ -1086,19 +1098,22 @@ if(COREAUDIO_FRAMEWORK AND AUDIOUNIT_INCLUDE_DIR)
|
||||||
set(HAVE_COREAUDIO 1)
|
set(HAVE_COREAUDIO 1)
|
||||||
set(ALC_OBJS ${ALC_OBJS} alc/backends/coreaudio.cpp alc/backends/coreaudio.h)
|
set(ALC_OBJS ${ALC_OBJS} alc/backends/coreaudio.cpp alc/backends/coreaudio.h)
|
||||||
set(BACKENDS "${BACKENDS} CoreAudio,")
|
set(BACKENDS "${BACKENDS} CoreAudio,")
|
||||||
|
|
||||||
|
set(EXTRA_LIBS -Wl,-framework,CoreAudio ${EXTRA_LIBS})
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "^(iOS|tvOS)$")
|
if(CMAKE_SYSTEM_NAME MATCHES "^(iOS|tvOS)$")
|
||||||
find_library(COREFOUNDATION_FRAMEWORK NAMES CoreFoundation)
|
find_library(COREFOUNDATION_FRAMEWORK NAMES CoreFoundation)
|
||||||
set(EXTRA_LIBS ${COREAUDIO_FRAMEWORK} ${COREFOUNDATION_FRAMEWORK} ${EXTRA_LIBS})
|
if(COREFOUNDATION_FRAMEWORK)
|
||||||
|
set(EXTRA_LIBS -Wl,-framework,CoreFoundation ${EXTRA_LIBS})
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
set(EXTRA_LIBS ${COREAUDIO_FRAMEWORK} /System/Library/Frameworks/AudioUnit.framework
|
set(EXTRA_LIBS -Wl,-framework,AudioUnit,-framework,ApplicationServices ${EXTRA_LIBS})
|
||||||
/System/Library/Frameworks/ApplicationServices.framework ${EXTRA_LIBS})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Some versions of OSX may need the AudioToolbox framework. Add it if
|
# Some versions of OSX may need the AudioToolbox framework. Add it if
|
||||||
# it's found.
|
# it's found.
|
||||||
find_library(AUDIOTOOLBOX_LIBRARY NAMES AudioToolbox)
|
find_library(AUDIOTOOLBOX_LIBRARY NAMES AudioToolbox)
|
||||||
if(AUDIOTOOLBOX_LIBRARY)
|
if(AUDIOTOOLBOX_LIBRARY)
|
||||||
set(EXTRA_LIBS ${AUDIOTOOLBOX_LIBRARY} ${EXTRA_LIBS})
|
set(EXTRA_LIBS -Wl,-framework,AudioToolbox ${EXTRA_LIBS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(INC_PATHS ${INC_PATHS} ${AUDIOUNIT_INCLUDE_DIR})
|
set(INC_PATHS ${INC_PATHS} ${AUDIOUNIT_INCLUDE_DIR})
|
||||||
|
@ -1129,17 +1144,7 @@ set(OBOE_TARGET )
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
set(OBOE_SOURCE "" CACHE STRING "Source directory for Oboe.")
|
set(OBOE_SOURCE "" CACHE STRING "Source directory for Oboe.")
|
||||||
if(OBOE_SOURCE)
|
if(OBOE_SOURCE)
|
||||||
# Force Oboe to build with hidden symbols. Don't want to be exporting
|
|
||||||
# them from OpenAL.
|
|
||||||
set(OLD_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
|
||||||
check_cxx_compiler_flag(-fvisibility=hidden HAVE_VISIBILITY_HIDDEN_SWITCH)
|
|
||||||
if(HAVE_VISIBILITY_HIDDEN_SWITCH)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
|
||||||
endif()
|
|
||||||
add_subdirectory(${OBOE_SOURCE} ./oboe)
|
add_subdirectory(${OBOE_SOURCE} ./oboe)
|
||||||
set(CMAKE_CXX_FLAGS ${OLD_CXX_FLAGS})
|
|
||||||
unset(OLD_CXX_FLAGS)
|
|
||||||
|
|
||||||
set(OBOE_TARGET oboe)
|
set(OBOE_TARGET oboe)
|
||||||
else()
|
else()
|
||||||
find_package(oboe CONFIG)
|
find_package(oboe CONFIG)
|
||||||
|
@ -1168,7 +1173,7 @@ endif()
|
||||||
|
|
||||||
# Check for SDL2 backend
|
# Check for SDL2 backend
|
||||||
option(ALSOFT_REQUIRE_SDL2 "Require SDL2 backend" OFF)
|
option(ALSOFT_REQUIRE_SDL2 "Require SDL2 backend" OFF)
|
||||||
find_package(SDL2)
|
find_package(SDL2 QUIET)
|
||||||
if(SDL2_FOUND)
|
if(SDL2_FOUND)
|
||||||
# Off by default, since it adds a runtime dependency
|
# Off by default, since it adds a runtime dependency
|
||||||
option(ALSOFT_BACKEND_SDL2 "Enable SDL2 backend" OFF)
|
option(ALSOFT_BACKEND_SDL2 "Enable SDL2 backend" OFF)
|
||||||
|
@ -1176,9 +1181,10 @@ if(SDL2_FOUND)
|
||||||
set(HAVE_SDL2 1)
|
set(HAVE_SDL2 1)
|
||||||
set(ALC_OBJS ${ALC_OBJS} alc/backends/sdl2.cpp alc/backends/sdl2.h)
|
set(ALC_OBJS ${ALC_OBJS} alc/backends/sdl2.cpp alc/backends/sdl2.h)
|
||||||
set(BACKENDS "${BACKENDS} SDL2,")
|
set(BACKENDS "${BACKENDS} SDL2,")
|
||||||
set(EXTRA_LIBS ${SDL2_LIBRARY} ${EXTRA_LIBS})
|
set(EXTRA_LIBS ${EXTRA_LIBS} SDL2::SDL2)
|
||||||
set(INC_PATHS ${INC_PATHS} ${SDL2_INCLUDE_DIR})
|
|
||||||
endif()
|
endif()
|
||||||
|
else()
|
||||||
|
message(STATUS "Could NOT find SDL2")
|
||||||
endif()
|
endif()
|
||||||
if(ALSOFT_REQUIRE_SDL2 AND NOT SDL2_FOUND)
|
if(ALSOFT_REQUIRE_SDL2 AND NOT SDL2_FOUND)
|
||||||
message(FATAL_ERROR "Failed to enabled required SDL2 backend")
|
message(FATAL_ERROR "Failed to enabled required SDL2 backend")
|
||||||
|
@ -1199,13 +1205,19 @@ set(BACKENDS "${BACKENDS} Null")
|
||||||
find_package(Git)
|
find_package(Git)
|
||||||
if(ALSOFT_UPDATE_BUILD_VERSION AND GIT_FOUND AND EXISTS "${OpenAL_SOURCE_DIR}/.git")
|
if(ALSOFT_UPDATE_BUILD_VERSION AND GIT_FOUND AND EXISTS "${OpenAL_SOURCE_DIR}/.git")
|
||||||
# Get the current working branch and its latest abbreviated commit hash
|
# Get the current working branch and its latest abbreviated commit hash
|
||||||
add_custom_target(build_version
|
add_custom_command(OUTPUT "${OpenAL_BINARY_DIR}/version_witness.txt"
|
||||||
${CMAKE_COMMAND} -D GIT_EXECUTABLE=${GIT_EXECUTABLE} -D LIB_VERSION=${LIB_VERSION}
|
BYPRODUCTS "${OpenAL_BINARY_DIR}/version.h"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -D GIT_EXECUTABLE=${GIT_EXECUTABLE} -D LIB_VERSION=${LIB_VERSION}
|
||||||
-D LIB_VERSION_NUM=${LIB_VERSION_NUM} -D SRC=${OpenAL_SOURCE_DIR}/version.h.in
|
-D LIB_VERSION_NUM=${LIB_VERSION_NUM} -D SRC=${OpenAL_SOURCE_DIR}/version.h.in
|
||||||
-D DST=${OpenAL_BINARY_DIR}/version.h -P ${OpenAL_SOURCE_DIR}/version.cmake
|
-D DST=${OpenAL_BINARY_DIR}/version.h -P ${OpenAL_SOURCE_DIR}/version.cmake
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch "${OpenAL_BINARY_DIR}/version_witness.txt"
|
||||||
WORKING_DIRECTORY "${OpenAL_SOURCE_DIR}"
|
WORKING_DIRECTORY "${OpenAL_SOURCE_DIR}"
|
||||||
|
MAIN_DEPENDENCY "${OpenAL_SOURCE_DIR}/version.h.in"
|
||||||
|
DEPENDS "${OpenAL_SOURCE_DIR}/.git/index" "${OpenAL_SOURCE_DIR}/version.cmake"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_custom_target(build_version DEPENDS "${OpenAL_BINARY_DIR}/version_witness.txt")
|
||||||
else()
|
else()
|
||||||
set(GIT_BRANCH "UNKNOWN")
|
set(GIT_BRANCH "UNKNOWN")
|
||||||
set(GIT_COMMIT_HASH "unknown")
|
set(GIT_COMMIT_HASH "unknown")
|
||||||
|
@ -1219,11 +1231,11 @@ option(ALSOFT_EMBED_HRTF_DATA "Embed the HRTF data files (increases library foot
|
||||||
if(ALSOFT_EMBED_HRTF_DATA)
|
if(ALSOFT_EMBED_HRTF_DATA)
|
||||||
macro(make_hrtf_header FILENAME VARNAME)
|
macro(make_hrtf_header FILENAME VARNAME)
|
||||||
set(infile "${OpenAL_SOURCE_DIR}/hrtf/${FILENAME}")
|
set(infile "${OpenAL_SOURCE_DIR}/hrtf/${FILENAME}")
|
||||||
set(outfile "${OpenAL_BINARY_DIR}/${VARNAME}.h")
|
set(outfile "${OpenAL_BINARY_DIR}/${VARNAME}.txt")
|
||||||
|
|
||||||
add_custom_command(OUTPUT "${outfile}"
|
add_custom_command(OUTPUT "${outfile}"
|
||||||
COMMAND ${CMAKE_COMMAND} -D "INPUT_FILE=${infile}" -D "OUTPUT_FILE=${outfile}"
|
COMMAND ${CMAKE_COMMAND} -D "INPUT_FILE=${infile}" -D "OUTPUT_FILE=${outfile}"
|
||||||
-D "VARIABLE_NAME=${VARNAME}" -P "${CMAKE_MODULE_PATH}/bin2h.script.cmake"
|
-P "${CMAKE_MODULE_PATH}/bin2h.script.cmake"
|
||||||
WORKING_DIRECTORY "${OpenAL_SOURCE_DIR}"
|
WORKING_DIRECTORY "${OpenAL_SOURCE_DIR}"
|
||||||
DEPENDS "${infile}" "${CMAKE_MODULE_PATH}/bin2h.script.cmake"
|
DEPENDS "${infile}" "${CMAKE_MODULE_PATH}/bin2h.script.cmake"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
|
@ -1231,7 +1243,7 @@ if(ALSOFT_EMBED_HRTF_DATA)
|
||||||
set(ALC_OBJS ${ALC_OBJS} "${outfile}")
|
set(ALC_OBJS ${ALC_OBJS} "${outfile}")
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
||||||
make_hrtf_header("Default HRTF.mhr" "hrtf_default")
|
make_hrtf_header("Default HRTF.mhr" "default_hrtf")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1246,7 +1258,6 @@ if(ALSOFT_UTILS)
|
||||||
endif()
|
endif()
|
||||||
if(ALSOFT_UTILS OR ALSOFT_EXAMPLES)
|
if(ALSOFT_UTILS OR ALSOFT_EXAMPLES)
|
||||||
find_package(SndFile)
|
find_package(SndFile)
|
||||||
find_package(SDL2)
|
|
||||||
if(SDL2_FOUND)
|
if(SDL2_FOUND)
|
||||||
find_package(FFmpeg COMPONENTS AVFORMAT AVCODEC AVUTIL SWSCALE SWRESAMPLE)
|
find_package(FFmpeg COMPONENTS AVFORMAT AVCODEC AVUTIL SWSCALE SWRESAMPLE)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1271,9 +1282,12 @@ if(LIBTYPE STREQUAL "STATIC")
|
||||||
set(PKG_CONFIG_CFLAGS -DAL_LIBTYPE_STATIC)
|
set(PKG_CONFIG_CFLAGS -DAL_LIBTYPE_STATIC)
|
||||||
foreach(FLAG ${LINKER_FLAGS} ${EXTRA_LIBS} ${MATH_LIB})
|
foreach(FLAG ${LINKER_FLAGS} ${EXTRA_LIBS} ${MATH_LIB})
|
||||||
# If this is already a linker flag, or is a full path+file, add it
|
# If this is already a linker flag, or is a full path+file, add it
|
||||||
# as-is. Otherwise, it's a name intended to be dressed as -lname.
|
# as-is. If it's an SDL2 target, add the link flag for it. Otherwise,
|
||||||
|
# it's a name intended to be dressed as -lname.
|
||||||
if(FLAG MATCHES "^-.*" OR EXISTS "${FLAG}")
|
if(FLAG MATCHES "^-.*" OR EXISTS "${FLAG}")
|
||||||
set(PKG_CONFIG_PRIVATE_LIBS "${PKG_CONFIG_PRIVATE_LIBS} ${FLAG}")
|
set(PKG_CONFIG_PRIVATE_LIBS "${PKG_CONFIG_PRIVATE_LIBS} ${FLAG}")
|
||||||
|
elseif(FLAG MATCHES "^SDL2::SDL2")
|
||||||
|
set(PKG_CONFIG_PRIVATE_LIBS "${PKG_CONFIG_PRIVATE_LIBS} -lSDL2")
|
||||||
else()
|
else()
|
||||||
set(PKG_CONFIG_PRIVATE_LIBS "${PKG_CONFIG_PRIVATE_LIBS} -l${FLAG}")
|
set(PKG_CONFIG_PRIVATE_LIBS "${PKG_CONFIG_PRIVATE_LIBS} -l${FLAG}")
|
||||||
endif()
|
endif()
|
||||||
|
@ -1352,7 +1366,8 @@ else()
|
||||||
|
|
||||||
# !important: for osx framework public header works, the headers must be in
|
# !important: for osx framework public header works, the headers must be in
|
||||||
# the project
|
# the project
|
||||||
set(TARGET_PUBLIC_HEADERS include/AL/al.h include/AL/alc.h include/AL/alext.h include/AL/efx.h)
|
set(TARGET_PUBLIC_HEADERS include/AL/al.h include/AL/alc.h include/AL/alext.h include/AL/efx.h
|
||||||
|
include/AL/efx-presets.h)
|
||||||
add_library(${IMPL_TARGET} SHARED ${OPENAL_OBJS} ${ALC_OBJS} ${CORE_OBJS} ${RC_CONFIG}
|
add_library(${IMPL_TARGET} SHARED ${OPENAL_OBJS} ${ALC_OBJS} ${CORE_OBJS} ${RC_CONFIG}
|
||||||
${TARGET_PUBLIC_HEADERS})
|
${TARGET_PUBLIC_HEADERS})
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
@ -1364,7 +1379,7 @@ else()
|
||||||
# Sets framework name to soft_oal to avoid ambiguity with the system OpenAL.framework
|
# Sets framework name to soft_oal to avoid ambiguity with the system OpenAL.framework
|
||||||
set(LIBNAME "soft_oal")
|
set(LIBNAME "soft_oal")
|
||||||
if(GIT_FOUND)
|
if(GIT_FOUND)
|
||||||
EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-list --count head
|
EXECUTE_PROCESS(COMMAND ${GIT_EXECUTABLE} rev-list --count HEAD
|
||||||
TIMEOUT 5
|
TIMEOUT 5
|
||||||
OUTPUT_VARIABLE BUNDLE_VERSION
|
OUTPUT_VARIABLE BUNDLE_VERSION
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
@ -1385,8 +1400,8 @@ else()
|
||||||
FRAMEWORK_VERSION C
|
FRAMEWORK_VERSION C
|
||||||
MACOSX_FRAMEWORK_NAME "${IMPL_TARGET}"
|
MACOSX_FRAMEWORK_NAME "${IMPL_TARGET}"
|
||||||
MACOSX_FRAMEWORK_IDENTIFIER "org.openal-soft.openal"
|
MACOSX_FRAMEWORK_IDENTIFIER "org.openal-soft.openal"
|
||||||
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${LIB_VERSION}
|
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${LIB_VERSION}"
|
||||||
MACOSX_FRAMEWORK_BUNDLE_VERSION ${BUNDLE_VERSION}
|
MACOSX_FRAMEWORK_BUNDLE_VERSION "${BUNDLE_VERSION}"
|
||||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
||||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
|
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
|
||||||
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
|
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
|
||||||
|
@ -1438,6 +1453,11 @@ if(WIN32 AND MINGW AND ALSOFT_BUILD_IMPORT_LIB AND NOT LIBTYPE STREQUAL "STATIC"
|
||||||
add_custom_command(TARGET OpenAL POST_BUILD
|
add_custom_command(TARGET OpenAL POST_BUILD
|
||||||
COMMAND "${SED_EXECUTABLE}" -i -e "s/ @[^ ]*//" OpenAL32.def
|
COMMAND "${SED_EXECUTABLE}" -i -e "s/ @[^ ]*//" OpenAL32.def
|
||||||
COMMAND "${CMAKE_DLLTOOL}" -d OpenAL32.def -l OpenAL32.lib -D OpenAL32.dll
|
COMMAND "${CMAKE_DLLTOOL}" -d OpenAL32.def -l OpenAL32.lib -D OpenAL32.dll
|
||||||
|
# Technically OpenAL32.def was created by the build, but cmake
|
||||||
|
# doesn't recognize it due to -Wl,--output-def,OpenAL32.def being
|
||||||
|
# manually specified. But declaring the file here allows it to be
|
||||||
|
# properly cleaned, e.g. during make clean.
|
||||||
|
BYPRODUCTS OpenAL32.def OpenAL32.lib
|
||||||
COMMENT "Stripping ordinals from OpenAL32.def and generating OpenAL32.lib..."
|
COMMENT "Stripping ordinals from OpenAL32.def and generating OpenAL32.lib..."
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
|
@ -1668,9 +1688,8 @@ if(ALSOFT_EXAMPLES)
|
||||||
|
|
||||||
if(SDL2_FOUND)
|
if(SDL2_FOUND)
|
||||||
add_executable(alloopback examples/alloopback.c)
|
add_executable(alloopback examples/alloopback.c)
|
||||||
target_include_directories(alloopback PRIVATE ${SDL2_INCLUDE_DIR})
|
|
||||||
target_link_libraries(alloopback
|
target_link_libraries(alloopback
|
||||||
PRIVATE ${LINKER_FLAGS} ${SDL2_LIBRARY} ex-common ${MATH_LIB})
|
PRIVATE ${LINKER_FLAGS} SDL2::SDL2 ex-common ${MATH_LIB})
|
||||||
|
|
||||||
if(ALSOFT_INSTALL_EXAMPLES)
|
if(ALSOFT_INSTALL_EXAMPLES)
|
||||||
set(EXTRA_INSTALLS ${EXTRA_INSTALLS} alloopback)
|
set(EXTRA_INSTALLS ${EXTRA_INSTALLS} alloopback)
|
||||||
|
@ -1681,33 +1700,32 @@ if(ALSOFT_EXAMPLES)
|
||||||
set(FFVER_OK FALSE)
|
set(FFVER_OK FALSE)
|
||||||
if(FFMPEG_FOUND)
|
if(FFMPEG_FOUND)
|
||||||
set(FFVER_OK TRUE)
|
set(FFVER_OK TRUE)
|
||||||
if(AVFORMAT_VERSION VERSION_LESS "57.56.101")
|
if(AVFORMAT_VERSION VERSION_LESS "59.27.100")
|
||||||
message(STATUS "libavformat is too old! (${AVFORMAT_VERSION}, wanted 57.56.101)")
|
message(STATUS "libavformat is too old! (${AVFORMAT_VERSION}, wanted 59.27.100)")
|
||||||
set(FFVER_OK FALSE)
|
set(FFVER_OK FALSE)
|
||||||
endif()
|
endif()
|
||||||
if(AVCODEC_VERSION VERSION_LESS "57.64.101")
|
if(AVCODEC_VERSION VERSION_LESS "59.37.100")
|
||||||
message(STATUS "libavcodec is too old! (${AVCODEC_VERSION}, wanted 57.64.101)")
|
message(STATUS "libavcodec is too old! (${AVCODEC_VERSION}, wanted 59.37.100)")
|
||||||
set(FFVER_OK FALSE)
|
set(FFVER_OK FALSE)
|
||||||
endif()
|
endif()
|
||||||
if(AVUTIL_VERSION VERSION_LESS "55.34.101")
|
if(AVUTIL_VERSION VERSION_LESS "57.28.100")
|
||||||
message(STATUS "libavutil is too old! (${AVUTIL_VERSION}, wanted 55.34.101)")
|
message(STATUS "libavutil is too old! (${AVUTIL_VERSION}, wanted 57.28.100)")
|
||||||
set(FFVER_OK FALSE)
|
set(FFVER_OK FALSE)
|
||||||
endif()
|
endif()
|
||||||
if(SWSCALE_VERSION VERSION_LESS "4.2.100")
|
if(SWSCALE_VERSION VERSION_LESS "6.7.100")
|
||||||
message(STATUS "libswscale is too old! (${SWSCALE_VERSION}, wanted 4.2.100)")
|
message(STATUS "libswscale is too old! (${SWSCALE_VERSION}, wanted 6.7.100)")
|
||||||
set(FFVER_OK FALSE)
|
set(FFVER_OK FALSE)
|
||||||
endif()
|
endif()
|
||||||
if(SWRESAMPLE_VERSION VERSION_LESS "2.3.100")
|
if(SWRESAMPLE_VERSION VERSION_LESS "4.7.100")
|
||||||
message(STATUS "libswresample is too old! (${SWRESAMPLE_VERSION}, wanted 2.3.100)")
|
message(STATUS "libswresample is too old! (${SWRESAMPLE_VERSION}, wanted 4.7.100)")
|
||||||
set(FFVER_OK FALSE)
|
set(FFVER_OK FALSE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(FFVER_OK)
|
if(FFVER_OK)
|
||||||
add_executable(alffplay examples/alffplay.cpp)
|
add_executable(alffplay examples/alffplay.cpp)
|
||||||
target_include_directories(alffplay
|
target_include_directories(alffplay PRIVATE ${FFMPEG_INCLUDE_DIRS})
|
||||||
PRIVATE ${SDL2_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS})
|
|
||||||
target_link_libraries(alffplay
|
target_link_libraries(alffplay
|
||||||
PRIVATE ${LINKER_FLAGS} ${SDL2_LIBRARY} ${FFMPEG_LIBRARIES} ex-common)
|
PRIVATE ${LINKER_FLAGS} SDL2::SDL2 ${FFMPEG_LIBRARIES} ex-common)
|
||||||
|
|
||||||
if(ALSOFT_INSTALL_EXAMPLES)
|
if(ALSOFT_INSTALL_EXAMPLES)
|
||||||
set(EXTRA_INSTALLS ${EXTRA_INSTALLS} alffplay)
|
set(EXTRA_INSTALLS ${EXTRA_INSTALLS} alffplay)
|
||||||
|
|
|
@ -1,3 +1,55 @@
|
||||||
|
openal-soft-1.23.0:
|
||||||
|
|
||||||
|
Fixed CoreAudio capture support.
|
||||||
|
|
||||||
|
Fixed handling per-version EAX properties.
|
||||||
|
|
||||||
|
Fixed interpolating changes to the Super Stereo width source property.
|
||||||
|
|
||||||
|
Fixed detection of the update and buffer size from PipeWire.
|
||||||
|
|
||||||
|
Fixed resuming playback devices with OpenSL.
|
||||||
|
|
||||||
|
Fixed support for certain OpenAL implementations with the router.
|
||||||
|
|
||||||
|
Improved reverb environment transitions.
|
||||||
|
|
||||||
|
Improved performance of convolution reverb.
|
||||||
|
|
||||||
|
Improved quality and performance of the pitch shifter effect slightly.
|
||||||
|
|
||||||
|
Improved sub-sample precision for resampled sources.
|
||||||
|
|
||||||
|
Improved blending spatialized multi-channel sources that use the source
|
||||||
|
radius property.
|
||||||
|
|
||||||
|
Improved mixing 2D ambisonic sources for higher-order 3D ambisonic mixing.
|
||||||
|
|
||||||
|
Improved quadraphonic and 7.1 surround sound output slightly.
|
||||||
|
|
||||||
|
Added config options for UHJ encoding/decoding quality. Including Super
|
||||||
|
Stereo processing.
|
||||||
|
|
||||||
|
Added a config option for specifying the speaker distance.
|
||||||
|
|
||||||
|
Added a compatibility config option for specifying the NFC distance
|
||||||
|
scaling.
|
||||||
|
|
||||||
|
Added a config option for mixing on PipeWire's non-real-time thread.
|
||||||
|
|
||||||
|
Added support for virtual source nodes with PipeWire capture.
|
||||||
|
|
||||||
|
Added the ability for the WASAPI backend to use different playback rates.
|
||||||
|
|
||||||
|
Added support for SOFA files that define per-response delays in makemhr.
|
||||||
|
|
||||||
|
Changed the default fallback playback sample rate to 48khz. This doesn't
|
||||||
|
affect most backends, which can detect a default rate from the system.
|
||||||
|
|
||||||
|
Changed the default resampler to cubic.
|
||||||
|
|
||||||
|
Changed the default HRTF size from 32 to 64 points.
|
||||||
|
|
||||||
openal-soft-1.22.2:
|
openal-soft-1.22.2:
|
||||||
|
|
||||||
Fixed PipeWire version check.
|
Fixed PipeWire version check.
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
OpenAL soft
|
OpenAL Soft
|
||||||
===========
|
===========
|
||||||
|
|
||||||
`master` branch CI status : [![Build Status](https://travis-ci.org/kcat/openal-soft.svg?branch=master)](https://travis-ci.org/kcat/openal-soft) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/kcat/openal-soft?branch=master&svg=true)](https://ci.appveyor.com/api/projects/status/github/kcat/openal-soft?branch=master&svg=true)
|
`master` branch CI status : [![GitHub Actions Status](https://github.com/kcat/openal-soft/actions/workflows/ci.yml/badge.svg)](https://github.com/kcat/openal-soft/actions) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/kcat/openal-soft?branch=master&svg=true)](https://ci.appveyor.com/api/projects/status/github/kcat/openal-soft?branch=master&svg=true)
|
||||||
|
|
||||||
OpenAL Soft is an LGPL-licensed, cross-platform, software implementation of the OpenAL 3D audio API. It's forked from the open-sourced Windows version available originally from openal.org's SVN repository (now defunct).
|
OpenAL Soft is an LGPL-licensed, cross-platform, software implementation of the OpenAL 3D audio API. It's forked from the open-sourced Windows version available originally from openal.org's SVN repository (now defunct).
|
||||||
OpenAL provides capabilities for playing audio in a virtual 3D environment. Distance attenuation, doppler shift, and directional sound emitters are among the features handled by the API. More advanced effects, including air absorption, occlusion, and environmental reverb, are available through the EFX extension. It also facilitates streaming audio, multi-channel buffers, and audio capture.
|
OpenAL provides capabilities for playing audio in a virtual 3D environment. Distance attenuation, doppler shift, and directional sound emitters are among the features handled by the API. More advanced effects, including air absorption, occlusion, and environmental reverb, are available through the EFX extension. It also facilitates streaming audio, multi-channel buffers, and audio capture.
|
||||||
|
|
||||||
More information is available on the [official website](http://openal-soft.org/)
|
More information is available on the [official website](http://openal-soft.org/).
|
||||||
|
|
||||||
Source Install
|
Source Install
|
||||||
-------------
|
-------------
|
||||||
|
@ -17,20 +17,37 @@ directory, and run:
|
||||||
cmake ..
|
cmake ..
|
||||||
```
|
```
|
||||||
|
|
||||||
Assuming configuration went well, you can then build it, typically using GNU
|
Alternatively, you can use any available CMake front-end, like cmake-gui,
|
||||||
Make (KDevelop, MSVC, and others are possible depending on your system setup
|
ccmake, or your preferred IDE's CMake project parser.
|
||||||
and CMake configuration).
|
|
||||||
|
Assuming configuration went well, you can then build it. The command
|
||||||
|
`cmake --build .` will instruct CMake to build the project with the toolchain
|
||||||
|
chosen during configuration (often GNU Make or NMake, although others are
|
||||||
|
possible).
|
||||||
|
|
||||||
Please Note: Double check that the appropriate backends were detected. Often,
|
Please Note: Double check that the appropriate backends were detected. Often,
|
||||||
complaints of no sound, crashing, and missing devices can be solved by making
|
complaints of no sound, crashing, and missing devices can be solved by making
|
||||||
sure the correct backends are being used. CMake's output will identify which
|
sure the correct backends are being used. CMake's output will identify which
|
||||||
backends were enabled.
|
backends were enabled.
|
||||||
|
|
||||||
For most systems, you will likely want to make sure ALSA, OSS, and PulseAudio
|
For most systems, you will likely want to make sure PipeWire, PulseAudio, and
|
||||||
were detected (if your target system uses them). For Windows, make sure
|
ALSA were detected (if your target system uses them). For Windows, make sure
|
||||||
DirectSound was detected.
|
WASAPI was detected.
|
||||||
|
|
||||||
|
|
||||||
|
Building openal-soft - Using vcpkg
|
||||||
|
----------------------------------
|
||||||
|
|
||||||
|
You can download and install openal-soft using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||||
|
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
|
cd vcpkg
|
||||||
|
./bootstrap-vcpkg.sh
|
||||||
|
./vcpkg integrate install
|
||||||
|
./vcpkg install openal-soft
|
||||||
|
|
||||||
|
The openal-soft port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||||
|
|
||||||
Utilities
|
Utilities
|
||||||
---------
|
---------
|
||||||
The source package comes with an informational utility, openal-info, and is
|
The source package comes with an informational utility, openal-info, and is
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,13 +20,23 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "eax/call.h"
|
#include "eax/call.h"
|
||||||
#include "eax/effect.h"
|
#include "eax/effect.h"
|
||||||
|
#include "eax/exception.h"
|
||||||
#include "eax/fx_slot_index.h"
|
#include "eax/fx_slot_index.h"
|
||||||
|
#include "eax/utils.h"
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
|
|
||||||
struct ALbuffer;
|
struct ALbuffer;
|
||||||
struct ALeffect;
|
struct ALeffect;
|
||||||
struct WetBuffer;
|
struct WetBuffer;
|
||||||
|
|
||||||
|
#ifdef ALSOFT_EAX
|
||||||
|
class EaxFxSlotException : public EaxException {
|
||||||
|
public:
|
||||||
|
explicit EaxFxSlotException(const char* message)
|
||||||
|
: EaxException{"EAX_FX_SLOT", message}
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
#endif // ALSOFT_EAX
|
||||||
|
|
||||||
enum class SlotState : ALenum {
|
enum class SlotState : ALenum {
|
||||||
Initial = AL_INITIAL,
|
Initial = AL_INITIAL,
|
||||||
|
@ -53,12 +63,12 @@ struct ALeffectslot {
|
||||||
|
|
||||||
RefCount ref{0u};
|
RefCount ref{0u};
|
||||||
|
|
||||||
EffectSlot mSlot;
|
EffectSlot *mSlot{nullptr};
|
||||||
|
|
||||||
/* Self ID */
|
/* Self ID */
|
||||||
ALuint id{};
|
ALuint id{};
|
||||||
|
|
||||||
ALeffectslot();
|
ALeffectslot(ALCcontext *context);
|
||||||
ALeffectslot(const ALeffectslot&) = delete;
|
ALeffectslot(const ALeffectslot&) = delete;
|
||||||
ALeffectslot& operator=(const ALeffectslot&) = delete;
|
ALeffectslot& operator=(const ALeffectslot&) = delete;
|
||||||
~ALeffectslot();
|
~ALeffectslot();
|
||||||
|
@ -72,169 +82,289 @@ struct ALeffectslot {
|
||||||
|
|
||||||
#ifdef ALSOFT_EAX
|
#ifdef ALSOFT_EAX
|
||||||
public:
|
public:
|
||||||
void eax_initialize(
|
void eax_initialize(ALCcontext& al_context, EaxFxSlotIndexValue index);
|
||||||
const EaxCall& call,
|
|
||||||
ALCcontext& al_context,
|
|
||||||
EaxFxSlotIndexValue index);
|
|
||||||
|
|
||||||
const EAX50FXSLOTPROPERTIES& eax_get_eax_fx_slot() const noexcept;
|
EaxFxSlotIndexValue eax_get_index() const noexcept { return eax_fx_slot_index_; }
|
||||||
|
const EAX50FXSLOTPROPERTIES& eax_get_eax_fx_slot() const noexcept
|
||||||
|
{ return eax_; }
|
||||||
|
|
||||||
|
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_dispatch(const EaxCall& call)
|
bool eax_dispatch(const EaxCall& call)
|
||||||
{ return call.is_get() ? eax_get(call) : eax_set(call); }
|
{ return call.is_get() ? eax_get(call) : eax_set(call); }
|
||||||
|
|
||||||
|
void eax_commit();
|
||||||
void eax_unlock_legacy() noexcept;
|
|
||||||
|
|
||||||
void eax_commit() { eax_apply_deferred(); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static constexpr auto eax_load_effect_dirty_bit = EaxDirtyFlags{1} << 0;
|
||||||
|
static constexpr auto eax_volume_dirty_bit = EaxDirtyFlags{1} << 1;
|
||||||
|
static constexpr auto eax_lock_dirty_bit = EaxDirtyFlags{1} << 2;
|
||||||
|
static constexpr auto eax_flags_dirty_bit = EaxDirtyFlags{1} << 3;
|
||||||
|
static constexpr auto eax_occlusion_dirty_bit = EaxDirtyFlags{1} << 4;
|
||||||
|
static constexpr auto eax_occlusion_lf_ratio_dirty_bit = EaxDirtyFlags{1} << 5;
|
||||||
|
|
||||||
|
using Exception = EaxFxSlotException;
|
||||||
|
|
||||||
|
using Eax4Props = EAX40FXSLOTPROPERTIES;
|
||||||
|
|
||||||
|
struct Eax4State {
|
||||||
|
Eax4Props i; // Immediate.
|
||||||
|
};
|
||||||
|
|
||||||
|
using Eax5Props = EAX50FXSLOTPROPERTIES;
|
||||||
|
|
||||||
|
struct Eax5State {
|
||||||
|
Eax5Props i; // Immediate.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EaxRangeValidator {
|
||||||
|
template<typename TValue>
|
||||||
|
void operator()(
|
||||||
|
const char* name,
|
||||||
|
const TValue& value,
|
||||||
|
const TValue& min_value,
|
||||||
|
const TValue& max_value) const
|
||||||
|
{
|
||||||
|
eax_validate_range<Exception>(name, value, min_value, max_value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax4GuidLoadEffectValidator {
|
||||||
|
void operator()(const GUID& guidLoadEffect) const
|
||||||
|
{
|
||||||
|
if (guidLoadEffect != EAX_NULL_GUID &&
|
||||||
|
guidLoadEffect != EAX_REVERB_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_AGCCOMPRESSOR_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_AUTOWAH_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_CHORUS_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_DISTORTION_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_ECHO_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_EQUALIZER_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_FLANGER_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_FREQUENCYSHIFTER_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_VOCALMORPHER_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_PITCHSHIFTER_EFFECT &&
|
||||||
|
guidLoadEffect != EAX_RINGMODULATOR_EFFECT)
|
||||||
|
{
|
||||||
|
eax_fail_unknown_effect_id();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax4VolumeValidator {
|
||||||
|
void operator()(long lVolume) const
|
||||||
|
{
|
||||||
|
EaxRangeValidator{}(
|
||||||
|
"Volume",
|
||||||
|
lVolume,
|
||||||
|
EAXFXSLOT_MINVOLUME,
|
||||||
|
EAXFXSLOT_MAXVOLUME);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax4LockValidator {
|
||||||
|
void operator()(long lLock) const
|
||||||
|
{
|
||||||
|
EaxRangeValidator{}(
|
||||||
|
"Lock",
|
||||||
|
lLock,
|
||||||
|
EAXFXSLOT_MINLOCK,
|
||||||
|
EAXFXSLOT_MAXLOCK);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax4FlagsValidator {
|
||||||
|
void operator()(unsigned long ulFlags) const
|
||||||
|
{
|
||||||
|
EaxRangeValidator{}(
|
||||||
|
"Flags",
|
||||||
|
ulFlags,
|
||||||
|
0UL,
|
||||||
|
~EAX40FXSLOTFLAGS_RESERVED);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax4AllValidator {
|
||||||
|
void operator()(const EAX40FXSLOTPROPERTIES& all) const
|
||||||
|
{
|
||||||
|
Eax4GuidLoadEffectValidator{}(all.guidLoadEffect);
|
||||||
|
Eax4VolumeValidator{}(all.lVolume);
|
||||||
|
Eax4LockValidator{}(all.lLock);
|
||||||
|
Eax4FlagsValidator{}(all.ulFlags);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax5OcclusionValidator {
|
||||||
|
void operator()(long lOcclusion) const
|
||||||
|
{
|
||||||
|
EaxRangeValidator{}(
|
||||||
|
"Occlusion",
|
||||||
|
lOcclusion,
|
||||||
|
EAXFXSLOT_MINOCCLUSION,
|
||||||
|
EAXFXSLOT_MAXOCCLUSION);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax5OcclusionLfRatioValidator {
|
||||||
|
void operator()(float flOcclusionLFRatio) const
|
||||||
|
{
|
||||||
|
EaxRangeValidator{}(
|
||||||
|
"Occlusion LF Ratio",
|
||||||
|
flOcclusionLFRatio,
|
||||||
|
EAXFXSLOT_MINOCCLUSIONLFRATIO,
|
||||||
|
EAXFXSLOT_MAXOCCLUSIONLFRATIO);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax5FlagsValidator {
|
||||||
|
void operator()(unsigned long ulFlags) const
|
||||||
|
{
|
||||||
|
EaxRangeValidator{}(
|
||||||
|
"Flags",
|
||||||
|
ulFlags,
|
||||||
|
0UL,
|
||||||
|
~EAX50FXSLOTFLAGS_RESERVED);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Eax5AllValidator {
|
||||||
|
void operator()(const EAX50FXSLOTPROPERTIES& all) const
|
||||||
|
{
|
||||||
|
Eax4AllValidator{}(static_cast<const EAX40FXSLOTPROPERTIES&>(all));
|
||||||
|
Eax5OcclusionValidator{}(all.lOcclusion);
|
||||||
|
Eax5OcclusionLfRatioValidator{}(all.flOcclusionLFRatio);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ALCcontext* eax_al_context_{};
|
ALCcontext* eax_al_context_{};
|
||||||
|
|
||||||
EaxFxSlotIndexValue eax_fx_slot_index_{};
|
EaxFxSlotIndexValue eax_fx_slot_index_{};
|
||||||
|
int eax_version_{}; // Current EAX version.
|
||||||
EAX50FXSLOTPROPERTIES eax_eax_fx_slot_{};
|
EaxDirtyFlags eax_df_{}; // Dirty flags for the current EAX version.
|
||||||
|
|
||||||
EaxEffectUPtr eax_effect_{};
|
EaxEffectUPtr eax_effect_{};
|
||||||
bool eax_is_locked_{};
|
Eax5State eax123_{}; // EAX1/EAX2/EAX3 state.
|
||||||
|
Eax4State eax4_{}; // EAX4 state.
|
||||||
|
Eax5State eax5_{}; // EAX5 state.
|
||||||
|
Eax5Props eax_{}; // Current EAX state.
|
||||||
|
|
||||||
|
[[noreturn]] static void eax_fail(const char* message);
|
||||||
|
[[noreturn]] static void eax_fail_unknown_effect_id();
|
||||||
|
[[noreturn]] static void eax_fail_unknown_property_id();
|
||||||
|
[[noreturn]] static void eax_fail_unknown_version();
|
||||||
|
|
||||||
[[noreturn]]
|
// Gets a new value from EAX call,
|
||||||
static void eax_fail(
|
// validates it,
|
||||||
const char* message);
|
// sets a dirty flag only if the new value differs form the old one,
|
||||||
|
// and assigns the new value.
|
||||||
|
template<typename TValidator, EaxDirtyFlags TDirtyBit, typename TProperties>
|
||||||
|
static void eax_fx_slot_set(const EaxCall& call, TProperties& dst, EaxDirtyFlags& dirty_flags)
|
||||||
|
{
|
||||||
|
const auto& src = call.get_value<Exception, const TProperties>();
|
||||||
|
TValidator{}(src);
|
||||||
|
dirty_flags |= (dst != src ? TDirtyBit : EaxDirtyFlags{});
|
||||||
|
dst = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a new value from EAX call,
|
||||||
|
// validates it,
|
||||||
|
// sets a dirty flag without comparing the values,
|
||||||
|
// and assigns the new value.
|
||||||
|
template<typename TValidator, EaxDirtyFlags TDirtyBit, typename TProperties>
|
||||||
|
static void eax_fx_slot_set_dirty(const EaxCall& call, TProperties& dst,
|
||||||
|
EaxDirtyFlags& dirty_flags)
|
||||||
|
{
|
||||||
|
const auto& src = call.get_value<Exception, const TProperties>();
|
||||||
|
TValidator{}(src);
|
||||||
|
dirty_flags |= TDirtyBit;
|
||||||
|
dst = src;
|
||||||
|
}
|
||||||
|
|
||||||
GUID eax_get_eax_default_effect_guid() const noexcept;
|
constexpr bool eax4_fx_slot_is_legacy() const noexcept
|
||||||
|
{ return eax_fx_slot_index_ < 2; }
|
||||||
|
|
||||||
|
void eax4_fx_slot_ensure_unlocked() const;
|
||||||
|
|
||||||
|
static ALenum eax_get_efx_effect_type(const GUID& guid);
|
||||||
|
const GUID& eax_get_eax_default_effect_guid() const noexcept;
|
||||||
long eax_get_eax_default_lock() const noexcept;
|
long eax_get_eax_default_lock() const noexcept;
|
||||||
|
|
||||||
void eax_set_eax_fx_slot_defaults();
|
void eax4_fx_slot_set_defaults(Eax4Props& props) noexcept;
|
||||||
|
void eax5_fx_slot_set_defaults(Eax5Props& props) noexcept;
|
||||||
|
void eax4_fx_slot_set_current_defaults(const Eax4Props& props) noexcept;
|
||||||
|
void eax5_fx_slot_set_current_defaults(const Eax5Props& props) noexcept;
|
||||||
|
void eax_fx_slot_set_current_defaults();
|
||||||
|
void eax_fx_slot_set_defaults();
|
||||||
|
|
||||||
void eax_initialize_eax();
|
void eax4_fx_slot_get(const EaxCall& call, const Eax4Props& props) const;
|
||||||
|
void eax5_fx_slot_get(const EaxCall& call, const Eax5Props& props) const;
|
||||||
void eax_initialize_lock();
|
void eax_fx_slot_get(const EaxCall& call) const;
|
||||||
|
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||||
|
|
||||||
void eax_initialize_effects(const EaxCall& call);
|
|
||||||
|
|
||||||
|
|
||||||
void eax_get_fx_slot_all(const EaxCall& call) const;
|
|
||||||
|
|
||||||
void eax_get_fx_slot(const EaxCall& call) const;
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_get(const EaxCall& call);
|
bool eax_get(const EaxCall& call);
|
||||||
|
|
||||||
|
void eax_fx_slot_load_effect();
|
||||||
|
void eax_fx_slot_set_volume();
|
||||||
|
void eax_fx_slot_set_environment_flag();
|
||||||
|
void eax_fx_slot_set_flags();
|
||||||
|
|
||||||
void eax_set_fx_slot_effect(const EaxCall& call, ALenum effect_type);
|
void eax4_fx_slot_set_all(const EaxCall& call);
|
||||||
|
void eax5_fx_slot_set_all(const EaxCall& call);
|
||||||
|
|
||||||
void eax_set_fx_slot_effect(const EaxCall& call);
|
bool eax_fx_slot_should_update_sources() const noexcept;
|
||||||
|
|
||||||
|
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||||
void eax_set_efx_effect_slot_gain();
|
bool eax4_fx_slot_set(const EaxCall& call);
|
||||||
|
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||||
void eax_set_fx_slot_volume();
|
bool eax5_fx_slot_set(const EaxCall& call);
|
||||||
|
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||||
|
bool eax_fx_slot_set(const EaxCall& call);
|
||||||
void eax_set_effect_slot_send_auto();
|
// Returns `true` if all sources should be updated, or `false` otherwise.
|
||||||
|
|
||||||
void eax_set_fx_slot_flags();
|
|
||||||
|
|
||||||
|
|
||||||
void eax_ensure_is_unlocked() const;
|
|
||||||
|
|
||||||
void eax_validate_fx_slot_effect(const GUID& eax_effect_id);
|
|
||||||
void eax_validate_fx_slot_volume(long eax_volume);
|
|
||||||
void eax_validate_fx_slot_lock(long eax_lock);
|
|
||||||
void eax_validate_fx_slot_flags(const EaxCall& call, unsigned long eax_flags);
|
|
||||||
void eax_validate_fx_slot_occlusion(long eax_occlusion);
|
|
||||||
void eax_validate_fx_slot_occlusion_lf_ratio(float eax_occlusion_lf_ratio);
|
|
||||||
void eax_validate_fx_slot_all(const EaxCall& call, const EAX40FXSLOTPROPERTIES& fx_slot);
|
|
||||||
void eax_validate_fx_slot_all(const EaxCall& call, const EAX50FXSLOTPROPERTIES& fx_slot);
|
|
||||||
|
|
||||||
void eax_set_fx_slot_effect(const EaxCall& call, const GUID& eax_effect_id);
|
|
||||||
|
|
||||||
void eax_set_fx_slot_volume(
|
|
||||||
long eax_volume);
|
|
||||||
|
|
||||||
void eax_set_fx_slot_lock(
|
|
||||||
long eax_lock);
|
|
||||||
|
|
||||||
void eax_set_fx_slot_flags(
|
|
||||||
unsigned long eax_flags);
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_set_fx_slot_occlusion(
|
|
||||||
long eax_occlusion);
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_set_fx_slot_occlusion_lf_ratio(
|
|
||||||
float eax_occlusion_lf_ratio);
|
|
||||||
|
|
||||||
void eax_set_fx_slot_all(const EaxCall& call, const EAX40FXSLOTPROPERTIES& eax_fx_slot);
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_set_fx_slot_all(const EaxCall& call, const EAX50FXSLOTPROPERTIES& eax_fx_slot);
|
|
||||||
|
|
||||||
|
|
||||||
void eax_defer_fx_slot_effect(const EaxCall& call);
|
|
||||||
|
|
||||||
void eax_defer_fx_slot_volume(const EaxCall& call);
|
|
||||||
|
|
||||||
void eax_defer_fx_slot_lock(const EaxCall& call);
|
|
||||||
|
|
||||||
void eax_defer_fx_slot_flags(const EaxCall& call);
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_defer_fx_slot_occlusion(const EaxCall& call);
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_defer_fx_slot_occlusion_lf_ratio(const EaxCall& call);
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_defer_fx_slot_all(const EaxCall& call);
|
|
||||||
|
|
||||||
bool eax_set_fx_slot(const EaxCall& call);
|
|
||||||
|
|
||||||
void eax_apply_deferred();
|
|
||||||
|
|
||||||
// [[nodiscard]]
|
|
||||||
bool eax_set(const EaxCall& call);
|
bool eax_set(const EaxCall& call);
|
||||||
|
|
||||||
|
template<
|
||||||
|
EaxDirtyFlags TDirtyBit,
|
||||||
|
typename TMemberResult,
|
||||||
|
typename TProps,
|
||||||
|
typename TState>
|
||||||
|
void eax_fx_slot_commit_property(TState& state, EaxDirtyFlags& dst_df,
|
||||||
|
TMemberResult TProps::*member) noexcept
|
||||||
|
{
|
||||||
|
auto& src_i = state.i;
|
||||||
|
auto& dst_i = eax_;
|
||||||
|
|
||||||
|
if((eax_df_ & TDirtyBit) != EaxDirtyFlags{})
|
||||||
|
{
|
||||||
|
dst_df |= TDirtyBit;
|
||||||
|
dst_i.*member = src_i.*member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eax4_fx_slot_commit(EaxDirtyFlags& dst_df);
|
||||||
|
void eax5_fx_slot_commit(Eax5State& state, EaxDirtyFlags& dst_df);
|
||||||
|
|
||||||
void eax_dispatch_effect(const EaxCall& call);
|
void eax_dispatch_effect(const EaxCall& call);
|
||||||
|
|
||||||
|
|
||||||
// `alAuxiliaryEffectSloti(effect_slot, AL_EFFECTSLOT_EFFECT, effect)`
|
// `alAuxiliaryEffectSloti(effect_slot, AL_EFFECTSLOT_EFFECT, effect)`
|
||||||
void eax_set_effect_slot_effect(EaxEffect &effect);
|
void eax_set_efx_slot_effect(EaxEffect &effect);
|
||||||
|
|
||||||
// `alAuxiliaryEffectSloti(effect_slot, AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, value)`
|
// `alAuxiliaryEffectSloti(effect_slot, AL_EFFECTSLOT_AUXILIARY_SEND_AUTO, value)`
|
||||||
void eax_set_effect_slot_send_auto(bool is_send_auto);
|
void eax_set_efx_slot_send_auto(bool is_send_auto);
|
||||||
|
|
||||||
// `alAuxiliaryEffectSlotf(effect_slot, AL_EFFECTSLOT_GAIN, gain)`
|
// `alAuxiliaryEffectSlotf(effect_slot, AL_EFFECTSLOT_GAIN, gain)`
|
||||||
void eax_set_effect_slot_gain(ALfloat gain);
|
void eax_set_efx_slot_gain(ALfloat gain);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class EaxDeleter {
|
class EaxDeleter {
|
||||||
public:
|
public:
|
||||||
void operator()(ALeffectslot *effect_slot);
|
void operator()(ALeffectslot *effect_slot);
|
||||||
}; // EaxAlEffectSlotDeleter
|
};
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
};
|
};
|
||||||
|
|
||||||
void UpdateAllEffectSlotProps(ALCcontext *context);
|
void UpdateAllEffectSlotProps(ALCcontext *context);
|
||||||
|
|
||||||
#ifdef ALSOFT_EAX
|
#ifdef ALSOFT_EAX
|
||||||
|
|
||||||
using EaxAlEffectSlotUPtr = std::unique_ptr<ALeffectslot, ALeffectslot::EaxDeleter>;
|
using EaxAlEffectSlotUPtr = std::unique_ptr<ALeffectslot, ALeffectslot::EaxDeleter>;
|
||||||
|
|
||||||
|
EaxAlEffectSlotUPtr eax_create_al_effect_slot(ALCcontext& context);
|
||||||
EaxAlEffectSlotUPtr eax_create_al_effect_slot(
|
void eax_delete_al_effect_slot(ALCcontext& context, ALeffectslot& effect_slot);
|
||||||
ALCcontext& context);
|
|
||||||
|
|
||||||
void eax_delete_al_effect_slot(
|
|
||||||
ALCcontext& context,
|
|
||||||
ALeffectslot& effect_slot);
|
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -288,8 +288,8 @@ al::optional<AmbiLayout> AmbiLayoutFromEnum(ALenum layout)
|
||||||
{
|
{
|
||||||
switch(layout)
|
switch(layout)
|
||||||
{
|
{
|
||||||
case AL_FUMA_SOFT: return al::make_optional(AmbiLayout::FuMa);
|
case AL_FUMA_SOFT: return AmbiLayout::FuMa;
|
||||||
case AL_ACN_SOFT: return al::make_optional(AmbiLayout::ACN);
|
case AL_ACN_SOFT: return AmbiLayout::ACN;
|
||||||
}
|
}
|
||||||
return al::nullopt;
|
return al::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -307,9 +307,9 @@ al::optional<AmbiScaling> AmbiScalingFromEnum(ALenum scale)
|
||||||
{
|
{
|
||||||
switch(scale)
|
switch(scale)
|
||||||
{
|
{
|
||||||
case AL_FUMA_SOFT: return al::make_optional(AmbiScaling::FuMa);
|
case AL_FUMA_SOFT: return AmbiScaling::FuMa;
|
||||||
case AL_SN3D_SOFT: return al::make_optional(AmbiScaling::SN3D);
|
case AL_SN3D_SOFT: return AmbiScaling::SN3D;
|
||||||
case AL_N3D_SOFT: return al::make_optional(AmbiScaling::N3D);
|
case AL_N3D_SOFT: return AmbiScaling::N3D;
|
||||||
}
|
}
|
||||||
return al::nullopt;
|
return al::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -329,18 +329,18 @@ al::optional<FmtChannels> FmtFromUserFmt(UserFmtChannels chans)
|
||||||
{
|
{
|
||||||
switch(chans)
|
switch(chans)
|
||||||
{
|
{
|
||||||
case UserFmtMono: return al::make_optional(FmtMono);
|
case UserFmtMono: return FmtMono;
|
||||||
case UserFmtStereo: return al::make_optional(FmtStereo);
|
case UserFmtStereo: return FmtStereo;
|
||||||
case UserFmtRear: return al::make_optional(FmtRear);
|
case UserFmtRear: return FmtRear;
|
||||||
case UserFmtQuad: return al::make_optional(FmtQuad);
|
case UserFmtQuad: return FmtQuad;
|
||||||
case UserFmtX51: return al::make_optional(FmtX51);
|
case UserFmtX51: return FmtX51;
|
||||||
case UserFmtX61: return al::make_optional(FmtX61);
|
case UserFmtX61: return FmtX61;
|
||||||
case UserFmtX71: return al::make_optional(FmtX71);
|
case UserFmtX71: return FmtX71;
|
||||||
case UserFmtBFormat2D: return al::make_optional(FmtBFormat2D);
|
case UserFmtBFormat2D: return FmtBFormat2D;
|
||||||
case UserFmtBFormat3D: return al::make_optional(FmtBFormat3D);
|
case UserFmtBFormat3D: return FmtBFormat3D;
|
||||||
case UserFmtUHJ2: return al::make_optional(FmtUHJ2);
|
case UserFmtUHJ2: return FmtUHJ2;
|
||||||
case UserFmtUHJ3: return al::make_optional(FmtUHJ3);
|
case UserFmtUHJ3: return FmtUHJ3;
|
||||||
case UserFmtUHJ4: return al::make_optional(FmtUHJ4);
|
case UserFmtUHJ4: return FmtUHJ4;
|
||||||
}
|
}
|
||||||
return al::nullopt;
|
return al::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -348,12 +348,12 @@ al::optional<FmtType> FmtFromUserFmt(UserFmtType type)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case UserFmtUByte: return al::make_optional(FmtUByte);
|
case UserFmtUByte: return FmtUByte;
|
||||||
case UserFmtShort: return al::make_optional(FmtShort);
|
case UserFmtShort: return FmtShort;
|
||||||
case UserFmtFloat: return al::make_optional(FmtFloat);
|
case UserFmtFloat: return FmtFloat;
|
||||||
case UserFmtDouble: return al::make_optional(FmtDouble);
|
case UserFmtDouble: return FmtDouble;
|
||||||
case UserFmtMulaw: return al::make_optional(FmtMulaw);
|
case UserFmtMulaw: return FmtMulaw;
|
||||||
case UserFmtAlaw: return al::make_optional(FmtAlaw);
|
case UserFmtAlaw: return FmtAlaw;
|
||||||
/* ADPCM not handled here. */
|
/* ADPCM not handled here. */
|
||||||
case UserFmtIMA4: break;
|
case UserFmtIMA4: break;
|
||||||
case UserFmtMSADPCM: break;
|
case UserFmtMSADPCM: break;
|
||||||
|
@ -411,14 +411,14 @@ bool EnsureBuffers(ALCdevice *device, size_t needed)
|
||||||
|
|
||||||
while(needed > count)
|
while(needed > count)
|
||||||
{
|
{
|
||||||
if UNLIKELY(device->BufferList.size() >= 1<<25)
|
if(device->BufferList.size() >= 1<<25) [[unlikely]]
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
device->BufferList.emplace_back();
|
device->BufferList.emplace_back();
|
||||||
auto sublist = device->BufferList.end() - 1;
|
auto sublist = device->BufferList.end() - 1;
|
||||||
sublist->FreeMask = ~0_u64;
|
sublist->FreeMask = ~0_u64;
|
||||||
sublist->Buffers = static_cast<ALbuffer*>(al_calloc(alignof(ALbuffer), sizeof(ALbuffer)*64));
|
sublist->Buffers = static_cast<ALbuffer*>(al_calloc(alignof(ALbuffer), sizeof(ALbuffer)*64));
|
||||||
if UNLIKELY(!sublist->Buffers)
|
if(!sublist->Buffers) [[unlikely]]
|
||||||
{
|
{
|
||||||
device->BufferList.pop_back();
|
device->BufferList.pop_back();
|
||||||
return false;
|
return false;
|
||||||
|
@ -467,10 +467,10 @@ inline ALbuffer *LookupBuffer(ALCdevice *device, ALuint id)
|
||||||
const size_t lidx{(id-1) >> 6};
|
const size_t lidx{(id-1) >> 6};
|
||||||
const ALuint slidx{(id-1) & 0x3f};
|
const ALuint slidx{(id-1) & 0x3f};
|
||||||
|
|
||||||
if UNLIKELY(lidx >= device->BufferList.size())
|
if(lidx >= device->BufferList.size()) [[unlikely]]
|
||||||
return nullptr;
|
return nullptr;
|
||||||
BufferSubList &sublist = device->BufferList[lidx];
|
BufferSubList &sublist = device->BufferList[lidx];
|
||||||
if UNLIKELY(sublist.FreeMask & (1_u64 << slidx))
|
if(sublist.FreeMask & (1_u64 << slidx)) [[unlikely]]
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return sublist.Buffers + slidx;
|
return sublist.Buffers + slidx;
|
||||||
}
|
}
|
||||||
|
@ -531,14 +531,14 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||||
UserFmtChannels SrcChannels, UserFmtType SrcType, const al::byte *SrcData,
|
UserFmtChannels SrcChannels, UserFmtType SrcType, const al::byte *SrcData,
|
||||||
ALbitfieldSOFT access)
|
ALbitfieldSOFT access)
|
||||||
{
|
{
|
||||||
if UNLIKELY(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0)
|
if(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_OPERATION,, "Modifying storage for in-use buffer %u",
|
return context->setError(AL_INVALID_OPERATION, "Modifying storage for in-use buffer %u",
|
||||||
ALBuf->id);
|
ALBuf->id);
|
||||||
|
|
||||||
/* Currently no channel configurations need to be converted. */
|
/* Currently no channel configurations need to be converted. */
|
||||||
auto DstChannels = FmtFromUserFmt(SrcChannels);
|
auto DstChannels = FmtFromUserFmt(SrcChannels);
|
||||||
if UNLIKELY(!DstChannels)
|
if(!DstChannels) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_ENUM, , "Invalid format");
|
return context->setError(AL_INVALID_ENUM, "Invalid format");
|
||||||
|
|
||||||
/* IMA4 and MSADPCM convert to 16-bit short.
|
/* IMA4 and MSADPCM convert to 16-bit short.
|
||||||
*
|
*
|
||||||
|
@ -548,19 +548,19 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||||
*/
|
*/
|
||||||
if((access&MAP_READ_WRITE_FLAGS))
|
if((access&MAP_READ_WRITE_FLAGS))
|
||||||
{
|
{
|
||||||
if UNLIKELY(SrcType == UserFmtIMA4 || SrcType == UserFmtMSADPCM)
|
if(SrcType == UserFmtIMA4 || SrcType == UserFmtMSADPCM) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "%s samples cannot be mapped",
|
return context->setError(AL_INVALID_VALUE, "%s samples cannot be mapped",
|
||||||
NameFromUserFmtType(SrcType));
|
NameFromUserFmtType(SrcType));
|
||||||
}
|
}
|
||||||
auto DstType = (SrcType == UserFmtIMA4 || SrcType == UserFmtMSADPCM)
|
auto DstType = (SrcType == UserFmtIMA4 || SrcType == UserFmtMSADPCM)
|
||||||
? al::make_optional(FmtShort) : FmtFromUserFmt(SrcType);
|
? al::make_optional(FmtShort) : FmtFromUserFmt(SrcType);
|
||||||
if UNLIKELY(!DstType)
|
if(!DstType) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_ENUM, , "Invalid format");
|
return context->setError(AL_INVALID_ENUM, "Invalid format");
|
||||||
|
|
||||||
const ALuint unpackalign{ALBuf->UnpackAlign};
|
const ALuint unpackalign{ALBuf->UnpackAlign};
|
||||||
const ALuint align{SanitizeAlignment(SrcType, unpackalign)};
|
const ALuint align{SanitizeAlignment(SrcType, unpackalign)};
|
||||||
if UNLIKELY(align < 1)
|
if(align < 1) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "Invalid unpack alignment %u for %s samples",
|
return context->setError(AL_INVALID_VALUE, "Invalid unpack alignment %u for %s samples",
|
||||||
unpackalign, NameFromUserFmtType(SrcType));
|
unpackalign, NameFromUserFmtType(SrcType));
|
||||||
|
|
||||||
const ALuint ambiorder{IsBFormat(*DstChannels) ? ALBuf->UnpackAmbiOrder :
|
const ALuint ambiorder{IsBFormat(*DstChannels) ? ALBuf->UnpackAmbiOrder :
|
||||||
|
@ -569,12 +569,12 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||||
if((access&AL_PRESERVE_DATA_BIT_SOFT))
|
if((access&AL_PRESERVE_DATA_BIT_SOFT))
|
||||||
{
|
{
|
||||||
/* Can only preserve data with the same format and alignment. */
|
/* Can only preserve data with the same format and alignment. */
|
||||||
if UNLIKELY(ALBuf->mChannels != *DstChannels || ALBuf->OriginalType != SrcType)
|
if(ALBuf->mChannels != *DstChannels || ALBuf->OriginalType != SrcType) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched format");
|
return context->setError(AL_INVALID_VALUE, "Preserving data of mismatched format");
|
||||||
if UNLIKELY(ALBuf->OriginalAlign != align)
|
if(ALBuf->OriginalAlign != align) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched alignment");
|
return context->setError(AL_INVALID_VALUE, "Preserving data of mismatched alignment");
|
||||||
if(ALBuf->mAmbiOrder != ambiorder)
|
if(ALBuf->mAmbiOrder != ambiorder) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_VALUE,, "Preserving data of mismatched order");
|
return context->setError(AL_INVALID_VALUE, "Preserving data of mismatched order");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the input/source size in bytes to sample frames using the unpack
|
/* Convert the input/source size in bytes to sample frames using the unpack
|
||||||
|
@ -584,13 +584,13 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||||
((SrcType == UserFmtIMA4) ? (align-1)/2 + 4 :
|
((SrcType == UserFmtIMA4) ? (align-1)/2 + 4 :
|
||||||
(SrcType == UserFmtMSADPCM) ? (align-2)/2 + 7 :
|
(SrcType == UserFmtMSADPCM) ? (align-2)/2 + 7 :
|
||||||
(align * BytesFromUserFmt(SrcType)))};
|
(align * BytesFromUserFmt(SrcType)))};
|
||||||
if UNLIKELY((size%SrcByteAlign) != 0)
|
if((size%SrcByteAlign) != 0) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_VALUE,,
|
return context->setError(AL_INVALID_VALUE,
|
||||||
"Data size %d is not a multiple of frame size %d (%d unpack alignment)",
|
"Data size %d is not a multiple of frame size %d (%d unpack alignment)",
|
||||||
size, SrcByteAlign, align);
|
size, SrcByteAlign, align);
|
||||||
|
|
||||||
if UNLIKELY(size/SrcByteAlign > std::numeric_limits<ALsizei>::max()/align)
|
if(size/SrcByteAlign > std::numeric_limits<ALsizei>::max()/align) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_OUT_OF_MEMORY,,
|
return context->setError(AL_OUT_OF_MEMORY,
|
||||||
"Buffer size overflow, %d blocks x %d samples per block", size/SrcByteAlign, align);
|
"Buffer size overflow, %d blocks x %d samples per block", size/SrcByteAlign, align);
|
||||||
const ALuint frames{size / SrcByteAlign * align};
|
const ALuint frames{size / SrcByteAlign * align};
|
||||||
|
|
||||||
|
@ -599,8 +599,8 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||||
*/
|
*/
|
||||||
ALuint NumChannels{ChannelsFromFmt(*DstChannels, ambiorder)};
|
ALuint NumChannels{ChannelsFromFmt(*DstChannels, ambiorder)};
|
||||||
ALuint FrameSize{NumChannels * BytesFromFmt(*DstType)};
|
ALuint FrameSize{NumChannels * BytesFromFmt(*DstType)};
|
||||||
if UNLIKELY(frames > std::numeric_limits<size_t>::max()/FrameSize)
|
if(frames > std::numeric_limits<size_t>::max()/FrameSize) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_OUT_OF_MEMORY,,
|
return context->setError(AL_OUT_OF_MEMORY,
|
||||||
"Buffer size overflow, %d frames x %d bytes per frame", frames, FrameSize);
|
"Buffer size overflow, %d frames x %d bytes per frame", frames, FrameSize);
|
||||||
size_t newsize{static_cast<size_t>(frames) * FrameSize};
|
size_t newsize{static_cast<size_t>(frames) * FrameSize};
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||||
{
|
{
|
||||||
ALCdevice &device = *context->mALDevice;
|
ALCdevice &device = *context->mALDevice;
|
||||||
if(!eax_x_ram_check_availability(device, *ALBuf, size))
|
if(!eax_x_ram_check_availability(device, *ALBuf, size))
|
||||||
SETERR_RETURN(context, AL_OUT_OF_MEMORY,,
|
return context->setError(AL_OUT_OF_MEMORY,
|
||||||
"Out of X-RAM memory (avail: %u, needed: %u)", device.eax_x_ram_free_size, size);
|
"Out of X-RAM memory (avail: %u, needed: %u)", device.eax_x_ram_free_size, size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -631,6 +631,9 @@ void LoadData(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq, ALuint size,
|
||||||
}
|
}
|
||||||
newdata.swap(ALBuf->mData);
|
newdata.swap(ALBuf->mData);
|
||||||
}
|
}
|
||||||
|
#ifdef ALSOFT_EAX
|
||||||
|
eax_x_ram_clear(*context->mALDevice, *ALBuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(SrcType == UserFmtIMA4)
|
if(SrcType == UserFmtIMA4)
|
||||||
{
|
{
|
||||||
|
@ -683,19 +686,19 @@ void PrepareCallback(ALCcontext *context, ALbuffer *ALBuf, ALsizei freq,
|
||||||
UserFmtChannels SrcChannels, UserFmtType SrcType, ALBUFFERCALLBACKTYPESOFT callback,
|
UserFmtChannels SrcChannels, UserFmtType SrcType, ALBUFFERCALLBACKTYPESOFT callback,
|
||||||
void *userptr)
|
void *userptr)
|
||||||
{
|
{
|
||||||
if UNLIKELY(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0)
|
if(ReadRef(ALBuf->ref) != 0 || ALBuf->MappedAccess != 0) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_OPERATION,, "Modifying callback for in-use buffer %u",
|
return context->setError(AL_INVALID_OPERATION, "Modifying callback for in-use buffer %u",
|
||||||
ALBuf->id);
|
ALBuf->id);
|
||||||
|
|
||||||
/* Currently no channel configurations need to be converted. */
|
/* Currently no channel configurations need to be converted. */
|
||||||
auto DstChannels = FmtFromUserFmt(SrcChannels);
|
auto DstChannels = FmtFromUserFmt(SrcChannels);
|
||||||
if UNLIKELY(!DstChannels)
|
if(!DstChannels) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_ENUM,, "Invalid format");
|
return context->setError(AL_INVALID_ENUM, "Invalid format");
|
||||||
|
|
||||||
/* IMA4 and MSADPCM convert to 16-bit short. Not supported with callbacks. */
|
/* IMA4 and MSADPCM convert to 16-bit short. Not supported with callbacks. */
|
||||||
auto DstType = FmtFromUserFmt(SrcType);
|
auto DstType = FmtFromUserFmt(SrcType);
|
||||||
if UNLIKELY(!DstType)
|
if(!DstType) [[unlikely]]
|
||||||
SETERR_RETURN(context, AL_INVALID_ENUM,, "Unsupported callback format");
|
return context->setError(AL_INVALID_ENUM, "Unsupported callback format");
|
||||||
|
|
||||||
const ALuint ambiorder{IsBFormat(*DstChannels) ? ALBuf->UnpackAmbiOrder :
|
const ALuint ambiorder{IsBFormat(*DstChannels) ? ALBuf->UnpackAmbiOrder :
|
||||||
(IsUHJ(*DstChannels) ? 1 : 0)};
|
(IsUHJ(*DstChannels) ? 1 : 0)};
|
||||||
|
@ -820,11 +823,11 @@ AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
if UNLIKELY(n < 0)
|
if(n < 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Generating %d buffers", n);
|
context->setError(AL_INVALID_VALUE, "Generating %d buffers", n);
|
||||||
if UNLIKELY(n <= 0) return;
|
if(n <= 0) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
@ -834,7 +837,7 @@ START_API_FUNC
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if LIKELY(n == 1)
|
if(n == 1) [[likely]]
|
||||||
{
|
{
|
||||||
/* Special handling for the easy and normal case. */
|
/* Special handling for the easy and normal case. */
|
||||||
ALbuffer *buffer{AllocBuffer(device)};
|
ALbuffer *buffer{AllocBuffer(device)};
|
||||||
|
@ -860,11 +863,11 @@ AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
if UNLIKELY(n < 0)
|
if(n < 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Deleting %d buffers", n);
|
context->setError(AL_INVALID_VALUE, "Deleting %d buffers", n);
|
||||||
if UNLIKELY(n <= 0) return;
|
if(n <= 0) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
@ -874,12 +877,12 @@ START_API_FUNC
|
||||||
{
|
{
|
||||||
if(!bid) return true;
|
if(!bid) return true;
|
||||||
ALbuffer *ALBuf{LookupBuffer(device, bid)};
|
ALbuffer *ALBuf{LookupBuffer(device, bid)};
|
||||||
if UNLIKELY(!ALBuf)
|
if(!ALBuf) [[unlikely]]
|
||||||
{
|
{
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", bid);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", bid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if UNLIKELY(ReadRef(ALBuf->ref) != 0)
|
if(ReadRef(ALBuf->ref) != 0) [[unlikely]]
|
||||||
{
|
{
|
||||||
context->setError(AL_INVALID_OPERATION, "Deleting in-use buffer %u", bid);
|
context->setError(AL_INVALID_OPERATION, "Deleting in-use buffer %u", bid);
|
||||||
return false;
|
return false;
|
||||||
|
@ -888,7 +891,7 @@ START_API_FUNC
|
||||||
};
|
};
|
||||||
const ALuint *buffers_end = buffers + n;
|
const ALuint *buffers_end = buffers + n;
|
||||||
auto invbuf = std::find_if_not(buffers, buffers_end, validate_buffer);
|
auto invbuf = std::find_if_not(buffers, buffers_end, validate_buffer);
|
||||||
if UNLIKELY(invbuf != buffers_end) return;
|
if(invbuf != buffers_end) [[unlikely]] return;
|
||||||
|
|
||||||
/* All good. Delete non-0 buffer IDs. */
|
/* All good. Delete non-0 buffer IDs. */
|
||||||
auto delete_buffer = [device](const ALuint bid) -> void
|
auto delete_buffer = [device](const ALuint bid) -> void
|
||||||
|
@ -904,7 +907,7 @@ AL_API ALboolean AL_APIENTRY alIsBuffer(ALuint buffer)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if LIKELY(context)
|
if(context) [[likely]]
|
||||||
{
|
{
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
@ -925,28 +928,28 @@ AL_API void AL_APIENTRY alBufferStorageSOFT(ALuint buffer, ALenum format, const
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(size < 0)
|
else if(size < 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Negative storage size %d", size);
|
context->setError(AL_INVALID_VALUE, "Negative storage size %d", size);
|
||||||
else if UNLIKELY(freq < 1)
|
else if(freq < 1) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid sample rate %d", freq);
|
context->setError(AL_INVALID_VALUE, "Invalid sample rate %d", freq);
|
||||||
else if UNLIKELY((flags&INVALID_STORAGE_MASK) != 0)
|
else if((flags&INVALID_STORAGE_MASK) != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid storage flags 0x%x",
|
context->setError(AL_INVALID_VALUE, "Invalid storage flags 0x%x",
|
||||||
flags&INVALID_STORAGE_MASK);
|
flags&INVALID_STORAGE_MASK);
|
||||||
else if UNLIKELY((flags&AL_MAP_PERSISTENT_BIT_SOFT) && !(flags&MAP_READ_WRITE_FLAGS))
|
else if((flags&AL_MAP_PERSISTENT_BIT_SOFT) && !(flags&MAP_READ_WRITE_FLAGS)) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE,
|
context->setError(AL_INVALID_VALUE,
|
||||||
"Declaring persistently mapped storage without read or write access");
|
"Declaring persistently mapped storage without read or write access");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto usrfmt = DecomposeUserFormat(format);
|
auto usrfmt = DecomposeUserFormat(format);
|
||||||
if UNLIKELY(!usrfmt)
|
if(!usrfmt) [[unlikely]]
|
||||||
context->setError(AL_INVALID_ENUM, "Invalid format 0x%04x", format);
|
context->setError(AL_INVALID_ENUM, "Invalid format 0x%04x", format);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -961,39 +964,40 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return nullptr;
|
if(!context) [[unlikely]] return nullptr;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY((access&INVALID_MAP_FLAGS) != 0)
|
else if((access&INVALID_MAP_FLAGS) != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid map flags 0x%x", access&INVALID_MAP_FLAGS);
|
context->setError(AL_INVALID_VALUE, "Invalid map flags 0x%x", access&INVALID_MAP_FLAGS);
|
||||||
else if UNLIKELY(!(access&MAP_READ_WRITE_FLAGS))
|
else if(!(access&MAP_READ_WRITE_FLAGS)) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Mapping buffer %u without read or write access",
|
context->setError(AL_INVALID_VALUE, "Mapping buffer %u without read or write access",
|
||||||
buffer);
|
buffer);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ALbitfieldSOFT unavailable = (albuf->Access^access) & access;
|
ALbitfieldSOFT unavailable = (albuf->Access^access) & access;
|
||||||
if UNLIKELY(ReadRef(albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT))
|
if(ReadRef(albuf->ref) != 0 && !(access&AL_MAP_PERSISTENT_BIT_SOFT)) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION,
|
context->setError(AL_INVALID_OPERATION,
|
||||||
"Mapping in-use buffer %u without persistent mapping", buffer);
|
"Mapping in-use buffer %u without persistent mapping", buffer);
|
||||||
else if UNLIKELY(albuf->MappedAccess != 0)
|
else if(albuf->MappedAccess != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION, "Mapping already-mapped buffer %u", buffer);
|
context->setError(AL_INVALID_OPERATION, "Mapping already-mapped buffer %u", buffer);
|
||||||
else if UNLIKELY((unavailable&AL_MAP_READ_BIT_SOFT))
|
else if((unavailable&AL_MAP_READ_BIT_SOFT)) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE,
|
context->setError(AL_INVALID_VALUE,
|
||||||
"Mapping buffer %u for reading without read access", buffer);
|
"Mapping buffer %u for reading without read access", buffer);
|
||||||
else if UNLIKELY((unavailable&AL_MAP_WRITE_BIT_SOFT))
|
else if((unavailable&AL_MAP_WRITE_BIT_SOFT)) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE,
|
context->setError(AL_INVALID_VALUE,
|
||||||
"Mapping buffer %u for writing without write access", buffer);
|
"Mapping buffer %u for writing without write access", buffer);
|
||||||
else if UNLIKELY((unavailable&AL_MAP_PERSISTENT_BIT_SOFT))
|
else if((unavailable&AL_MAP_PERSISTENT_BIT_SOFT)) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE,
|
context->setError(AL_INVALID_VALUE,
|
||||||
"Mapping buffer %u persistently without persistent access", buffer);
|
"Mapping buffer %u persistently without persistent access", buffer);
|
||||||
else if UNLIKELY(offset < 0 || length <= 0
|
else if(offset < 0 || length <= 0
|
||||||
|| static_cast<ALuint>(offset) >= albuf->OriginalSize
|
|| static_cast<ALuint>(offset) >= albuf->OriginalSize
|
||||||
|| static_cast<ALuint>(length) > albuf->OriginalSize - static_cast<ALuint>(offset))
|
|| static_cast<ALuint>(length) > albuf->OriginalSize - static_cast<ALuint>(offset))
|
||||||
|
[[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Mapping invalid range %d+%d for buffer %u",
|
context->setError(AL_INVALID_VALUE, "Mapping invalid range %d+%d for buffer %u",
|
||||||
offset, length, buffer);
|
offset, length, buffer);
|
||||||
else
|
else
|
||||||
|
@ -1014,15 +1018,15 @@ AL_API void AL_APIENTRY alUnmapBufferSOFT(ALuint buffer)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(albuf->MappedAccess == 0)
|
else if(albuf->MappedAccess == 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION, "Unmapping unmapped buffer %u", buffer);
|
context->setError(AL_INVALID_OPERATION, "Unmapping unmapped buffer %u", buffer);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1037,20 +1041,20 @@ AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, A
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT))
|
else if(!(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT)) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION, "Flushing buffer %u while not mapped for writing",
|
context->setError(AL_INVALID_OPERATION, "Flushing buffer %u while not mapped for writing",
|
||||||
buffer);
|
buffer);
|
||||||
else if UNLIKELY(offset < albuf->MappedOffset || length <= 0
|
else if(offset < albuf->MappedOffset || length <= 0
|
||||||
|| offset >= albuf->MappedOffset+albuf->MappedSize
|
|| offset >= albuf->MappedOffset+albuf->MappedSize
|
||||||
|| length > albuf->MappedOffset+albuf->MappedSize-offset)
|
|| length > albuf->MappedOffset+albuf->MappedSize-offset) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Flushing invalid range %d+%d on buffer %u", offset,
|
context->setError(AL_INVALID_VALUE, "Flushing invalid range %d+%d on buffer %u", offset,
|
||||||
length, buffer);
|
length, buffer);
|
||||||
else
|
else
|
||||||
|
@ -1069,20 +1073,20 @@ AL_API void AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
{
|
{
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto usrfmt = DecomposeUserFormat(format);
|
auto usrfmt = DecomposeUserFormat(format);
|
||||||
if UNLIKELY(!usrfmt)
|
if(!usrfmt) [[unlikely]]
|
||||||
{
|
{
|
||||||
context->setError(AL_INVALID_ENUM, "Invalid format 0x%04x", format);
|
context->setError(AL_INVALID_ENUM, "Invalid format 0x%04x", format);
|
||||||
return;
|
return;
|
||||||
|
@ -1090,18 +1094,18 @@ START_API_FUNC
|
||||||
|
|
||||||
ALuint unpack_align{albuf->UnpackAlign};
|
ALuint unpack_align{albuf->UnpackAlign};
|
||||||
ALuint align{SanitizeAlignment(usrfmt->type, unpack_align)};
|
ALuint align{SanitizeAlignment(usrfmt->type, unpack_align)};
|
||||||
if UNLIKELY(align < 1)
|
if(align < 1) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid unpack alignment %u", unpack_align);
|
context->setError(AL_INVALID_VALUE, "Invalid unpack alignment %u", unpack_align);
|
||||||
else if UNLIKELY(long{usrfmt->channels} != long{albuf->mChannels}
|
else if(al::to_underlying(usrfmt->channels) != al::to_underlying(albuf->mChannels)
|
||||||
|| usrfmt->type != albuf->OriginalType)
|
|| usrfmt->type != albuf->OriginalType) [[unlikely]]
|
||||||
context->setError(AL_INVALID_ENUM, "Unpacking data with mismatched format");
|
context->setError(AL_INVALID_ENUM, "Unpacking data with mismatched format");
|
||||||
else if UNLIKELY(align != albuf->OriginalAlign)
|
else if(align != albuf->OriginalAlign) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE,
|
context->setError(AL_INVALID_VALUE,
|
||||||
"Unpacking data with alignment %u does not match original alignment %u", align,
|
"Unpacking data with alignment %u does not match original alignment %u", align,
|
||||||
albuf->OriginalAlign);
|
albuf->OriginalAlign);
|
||||||
else if UNLIKELY(albuf->isBFormat() && albuf->UnpackAmbiOrder != albuf->mAmbiOrder)
|
else if(albuf->isBFormat() && albuf->UnpackAmbiOrder != albuf->mAmbiOrder) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Unpacking data with mismatched ambisonic order");
|
context->setError(AL_INVALID_VALUE, "Unpacking data with mismatched ambisonic order");
|
||||||
else if UNLIKELY(albuf->MappedAccess != 0)
|
else if(albuf->MappedAccess != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION, "Unpacking data into mapped buffer %u", buffer);
|
context->setError(AL_INVALID_OPERATION, "Unpacking data into mapped buffer %u", buffer);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1113,15 +1117,16 @@ START_API_FUNC
|
||||||
(align * frame_size)
|
(align * frame_size)
|
||||||
};
|
};
|
||||||
|
|
||||||
if UNLIKELY(offset < 0 || length < 0 || static_cast<ALuint>(offset) > albuf->OriginalSize
|
if(offset < 0 || length < 0 || static_cast<ALuint>(offset) > albuf->OriginalSize
|
||||||
|| static_cast<ALuint>(length) > albuf->OriginalSize-static_cast<ALuint>(offset))
|
|| static_cast<ALuint>(length) > albuf->OriginalSize-static_cast<ALuint>(offset))
|
||||||
|
[[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid data sub-range %d+%d on buffer %u",
|
context->setError(AL_INVALID_VALUE, "Invalid data sub-range %d+%d on buffer %u",
|
||||||
offset, length, buffer);
|
offset, length, buffer);
|
||||||
else if UNLIKELY((static_cast<ALuint>(offset)%byte_align) != 0)
|
else if((static_cast<ALuint>(offset)%byte_align) != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE,
|
context->setError(AL_INVALID_VALUE,
|
||||||
"Sub-range offset %d is not a multiple of frame size %d (%d unpack alignment)",
|
"Sub-range offset %d is not a multiple of frame size %d (%d unpack alignment)",
|
||||||
offset, byte_align, align);
|
offset, byte_align, align);
|
||||||
else if UNLIKELY((static_cast<ALuint>(length)%byte_align) != 0)
|
else if((static_cast<ALuint>(length)%byte_align) != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE,
|
context->setError(AL_INVALID_VALUE,
|
||||||
"Sub-range length %d is not a multiple of frame size %d (%d unpack alignment)",
|
"Sub-range length %d is not a multiple of frame size %d (%d unpack alignment)",
|
||||||
length, byte_align, align);
|
length, byte_align, align);
|
||||||
|
@ -1140,7 +1145,7 @@ START_API_FUNC
|
||||||
static_cast<const al::byte*>(data), num_chans, samplen, align);
|
static_cast<const al::byte*>(data), num_chans, samplen, align);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(long{usrfmt->type} == long{albuf->mType});
|
assert(al::to_underlying(usrfmt->type) == al::to_underlying(albuf->mType));
|
||||||
memcpy(dst, data, size_t{samplen} * frame_size);
|
memcpy(dst, data, size_t{samplen} * frame_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1155,7 +1160,7 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint /*buffer*/, ALuint /*samplera
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
context->setError(AL_INVALID_OPERATION, "alBufferSamplesSOFT not supported");
|
context->setError(AL_INVALID_OPERATION, "alBufferSamplesSOFT not supported");
|
||||||
}
|
}
|
||||||
|
@ -1166,7 +1171,7 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint /*buffer*/, ALsizei /*offs
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
context->setError(AL_INVALID_OPERATION, "alBufferSubSamplesSOFT not supported");
|
context->setError(AL_INVALID_OPERATION, "alBufferSubSamplesSOFT not supported");
|
||||||
}
|
}
|
||||||
|
@ -1177,7 +1182,7 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint /*buffer*/, ALsizei /*offs
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
context->setError(AL_INVALID_OPERATION, "alGetBufferSamplesSOFT not supported");
|
context->setError(AL_INVALID_OPERATION, "alGetBufferSamplesSOFT not supported");
|
||||||
}
|
}
|
||||||
|
@ -1187,7 +1192,7 @@ AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum /*format*/)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return AL_FALSE;
|
if(!context) [[unlikely]] return AL_FALSE;
|
||||||
|
|
||||||
context->setError(AL_INVALID_OPERATION, "alIsBufferFormatSupportedSOFT not supported");
|
context->setError(AL_INVALID_OPERATION, "alIsBufferFormatSupportedSOFT not supported");
|
||||||
return AL_FALSE;
|
return AL_FALSE;
|
||||||
|
@ -1199,12 +1204,12 @@ AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum param, ALfloat /*value*/
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1219,12 +1224,12 @@ AL_API void AL_APIENTRY alBuffer3f(ALuint buffer, ALenum param,
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1238,14 +1243,14 @@ AL_API void AL_APIENTRY alBufferfv(ALuint buffer, ALenum param, const ALfloat *v
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!values)
|
else if(!values) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1260,52 +1265,53 @@ AL_API void AL_APIENTRY alBufferi(ALuint buffer, ALenum param, ALint value)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
|
case AL_UNPACK_BLOCK_ALIGNMENT_SOFT:
|
||||||
if UNLIKELY(value < 0)
|
if(value < 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid unpack block alignment %d", value);
|
context->setError(AL_INVALID_VALUE, "Invalid unpack block alignment %d", value);
|
||||||
else
|
else
|
||||||
albuf->UnpackAlign = static_cast<ALuint>(value);
|
albuf->UnpackAlign = static_cast<ALuint>(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AL_PACK_BLOCK_ALIGNMENT_SOFT:
|
case AL_PACK_BLOCK_ALIGNMENT_SOFT:
|
||||||
if UNLIKELY(value < 0)
|
if(value < 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid pack block alignment %d", value);
|
context->setError(AL_INVALID_VALUE, "Invalid pack block alignment %d", value);
|
||||||
else
|
else
|
||||||
albuf->PackAlign = static_cast<ALuint>(value);
|
albuf->PackAlign = static_cast<ALuint>(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AL_AMBISONIC_LAYOUT_SOFT:
|
case AL_AMBISONIC_LAYOUT_SOFT:
|
||||||
if UNLIKELY(ReadRef(albuf->ref) != 0)
|
if(ReadRef(albuf->ref) != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's ambisonic layout",
|
context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's ambisonic layout",
|
||||||
buffer);
|
buffer);
|
||||||
else if UNLIKELY(value != AL_FUMA_SOFT && value != AL_ACN_SOFT)
|
else if(value != AL_FUMA_SOFT && value != AL_ACN_SOFT) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic layout %04x", value);
|
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic layout %04x", value);
|
||||||
else
|
else
|
||||||
albuf->mAmbiLayout = AmbiLayoutFromEnum(value).value();
|
albuf->mAmbiLayout = AmbiLayoutFromEnum(value).value();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AL_AMBISONIC_SCALING_SOFT:
|
case AL_AMBISONIC_SCALING_SOFT:
|
||||||
if UNLIKELY(ReadRef(albuf->ref) != 0)
|
if(ReadRef(albuf->ref) != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's ambisonic scaling",
|
context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's ambisonic scaling",
|
||||||
buffer);
|
buffer);
|
||||||
else if UNLIKELY(value != AL_FUMA_SOFT && value != AL_SN3D_SOFT && value != AL_N3D_SOFT)
|
else if(value != AL_FUMA_SOFT && value != AL_SN3D_SOFT && value != AL_N3D_SOFT)
|
||||||
|
[[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic scaling %04x", value);
|
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic scaling %04x", value);
|
||||||
else
|
else
|
||||||
albuf->mAmbiScaling = AmbiScalingFromEnum(value).value();
|
albuf->mAmbiScaling = AmbiScalingFromEnum(value).value();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AL_UNPACK_AMBISONIC_ORDER_SOFT:
|
case AL_UNPACK_AMBISONIC_ORDER_SOFT:
|
||||||
if UNLIKELY(value < 1 || value > 14)
|
if(value < 1 || value > 14) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic order %d", value);
|
context->setError(AL_INVALID_VALUE, "Invalid unpack ambisonic order %d", value);
|
||||||
else
|
else
|
||||||
albuf->UnpackAmbiOrder = static_cast<ALuint>(value);
|
albuf->UnpackAmbiOrder = static_cast<ALuint>(value);
|
||||||
|
@ -1322,12 +1328,12 @@ AL_API void AL_APIENTRY alBuffer3i(ALuint buffer, ALenum param,
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1355,24 +1361,24 @@ START_API_FUNC
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!values)
|
else if(!values) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
case AL_LOOP_POINTS_SOFT:
|
case AL_LOOP_POINTS_SOFT:
|
||||||
if UNLIKELY(ReadRef(albuf->ref) != 0)
|
if(ReadRef(albuf->ref) != 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's loop points",
|
context->setError(AL_INVALID_OPERATION, "Modifying in-use buffer %u's loop points",
|
||||||
buffer);
|
buffer);
|
||||||
else if UNLIKELY(values[0] < 0 || values[0] >= values[1]
|
else if(values[0] < 0 || values[0] >= values[1]
|
||||||
|| static_cast<ALuint>(values[1]) > albuf->mSampleLen)
|
|| static_cast<ALuint>(values[1]) > albuf->mSampleLen) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid loop point range %d -> %d on buffer %u",
|
context->setError(AL_INVALID_VALUE, "Invalid loop point range %d -> %d on buffer %u",
|
||||||
values[0], values[1], buffer);
|
values[0], values[1], buffer);
|
||||||
else
|
else
|
||||||
|
@ -1393,15 +1399,15 @@ AL_API void AL_APIENTRY alGetBufferf(ALuint buffer, ALenum param, ALfloat *value
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!value)
|
else if(!value) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1415,14 +1421,14 @@ AL_API void AL_APIENTRY alGetBuffer3f(ALuint buffer, ALenum param, ALfloat *valu
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!value1 || !value2 || !value3)
|
else if(!value1 || !value2 || !value3) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1443,14 +1449,14 @@ START_API_FUNC
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!values)
|
else if(!values) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1465,14 +1471,14 @@ AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!value)
|
else if(!value) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1522,13 +1528,13 @@ AL_API void AL_APIENTRY alGetBuffer3i(ALuint buffer, ALenum param, ALint *value1
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!value1 || !value2 || !value3)
|
else if(!value1 || !value2 || !value3) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1560,14 +1566,14 @@ START_API_FUNC
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!values)
|
else if(!values) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1588,22 +1594,22 @@ AL_API void AL_APIENTRY alBufferCallbackSOFT(ALuint buffer, ALenum format, ALsiz
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
|
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(freq < 1)
|
else if(freq < 1) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Invalid sample rate %d", freq);
|
context->setError(AL_INVALID_VALUE, "Invalid sample rate %d", freq);
|
||||||
else if UNLIKELY(callback == nullptr)
|
else if(callback == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL callback");
|
context->setError(AL_INVALID_VALUE, "NULL callback");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto usrfmt = DecomposeUserFormat(format);
|
auto usrfmt = DecomposeUserFormat(format);
|
||||||
if UNLIKELY(!usrfmt)
|
if(!usrfmt) [[unlikely]]
|
||||||
context->setError(AL_INVALID_ENUM, "Invalid format 0x%04x", format);
|
context->setError(AL_INVALID_ENUM, "Invalid format 0x%04x", format);
|
||||||
else
|
else
|
||||||
PrepareCallback(context.get(), albuf, freq, usrfmt->channels, usrfmt->type, callback,
|
PrepareCallback(context.get(), albuf, freq, usrfmt->channels, usrfmt->type, callback,
|
||||||
|
@ -1616,14 +1622,14 @@ AL_API void AL_APIENTRY alGetBufferPtrSOFT(ALuint buffer, ALenum param, ALvoid *
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
ALbuffer *albuf = LookupBuffer(device, buffer);
|
ALbuffer *albuf = LookupBuffer(device, buffer);
|
||||||
if UNLIKELY(!albuf)
|
if(!albuf) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!value)
|
else if(!value) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1644,13 +1650,13 @@ AL_API void AL_APIENTRY alGetBuffer3PtrSOFT(ALuint buffer, ALenum param, ALvoid
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!value1 || !value2 || !value3)
|
else if(!value1 || !value2 || !value3) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1672,13 +1678,13 @@ START_API_FUNC
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->BufferLock};
|
std::lock_guard<std::mutex> _{device->BufferLock};
|
||||||
if UNLIKELY(LookupBuffer(device, buffer) == nullptr)
|
if(LookupBuffer(device, buffer) == nullptr) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
context->setError(AL_INVALID_NAME, "Invalid buffer ID %u", buffer);
|
||||||
else if UNLIKELY(!values)
|
else if(!values) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
context->setError(AL_INVALID_VALUE, "NULL pointer");
|
||||||
else switch(param)
|
else switch(param)
|
||||||
{
|
{
|
||||||
|
@ -1763,7 +1769,7 @@ START_API_FUNC
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const auto al_buffer = LookupBuffer(device, buffer);
|
const auto al_buffer = LookupBuffer(device, buffer);
|
||||||
if (!al_buffer)
|
if(!al_buffer) [[unlikely]]
|
||||||
{
|
{
|
||||||
ERR(EAX_PREFIX "Invalid buffer ID %u.\n", buffer);
|
ERR(EAX_PREFIX "Invalid buffer ID %u.\n", buffer);
|
||||||
return ALC_FALSE;
|
return ALC_FALSE;
|
||||||
|
@ -1779,7 +1785,7 @@ START_API_FUNC
|
||||||
* buffer ID is specified multiple times in the provided list, it
|
* buffer ID is specified multiple times in the provided list, it
|
||||||
* counts each instance as more memory that needs to fit in X-RAM.
|
* counts each instance as more memory that needs to fit in X-RAM.
|
||||||
*/
|
*/
|
||||||
if(unlikely(std::numeric_limits<size_t>::max()-al_buffer->OriginalSize < total_needed))
|
if(std::numeric_limits<size_t>::max()-al_buffer->OriginalSize < total_needed) [[unlikely]]
|
||||||
{
|
{
|
||||||
context->setError(AL_OUT_OF_MEMORY, EAX_PREFIX "Buffer size overflow (%u + %zu)\n",
|
context->setError(AL_OUT_OF_MEMORY, EAX_PREFIX "Buffer size overflow (%u + %zu)\n",
|
||||||
al_buffer->OriginalSize, total_needed);
|
al_buffer->OriginalSize, total_needed);
|
||||||
|
|
|
@ -269,7 +269,8 @@ const GUID EAX_RINGMODULATOR_EFFECT =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const GUID EAXCONTEXT_DEFAULTPRIMARYFXSLOTID = EAXPROPERTYID_EAX40_FXSlot0;
|
const GUID EAX40CONTEXT_DEFAULTPRIMARYFXSLOTID = EAXPROPERTYID_EAX40_FXSlot0;
|
||||||
|
const GUID EAX50CONTEXT_DEFAULTPRIMARYFXSLOTID = EAXPROPERTYID_EAX50_FXSlot0;
|
||||||
|
|
||||||
const EAX40ACTIVEFXSLOTS EAX40SOURCE_DEFAULTACTIVEFXSLOTID = EAX40ACTIVEFXSLOTS
|
const EAX40ACTIVEFXSLOTS EAX40SOURCE_DEFAULTACTIVEFXSLOTID = EAX40ACTIVEFXSLOTS
|
||||||
{{
|
{{
|
||||||
|
|
|
@ -28,11 +28,14 @@ typedef struct _GUID {
|
||||||
std::uint8_t Data4[8];
|
std::uint8_t Data4[8];
|
||||||
} GUID;
|
} GUID;
|
||||||
|
|
||||||
|
#ifndef _SYS_GUID_OPERATOR_EQ_
|
||||||
|
#define _SYS_GUID_OPERATOR_EQ_
|
||||||
inline bool operator==(const GUID& lhs, const GUID& rhs) noexcept
|
inline bool operator==(const GUID& lhs, const GUID& rhs) noexcept
|
||||||
{ return std::memcmp(&lhs, &rhs, sizeof(GUID)) == 0; }
|
{ return std::memcmp(&lhs, &rhs, sizeof(GUID)) == 0; }
|
||||||
|
|
||||||
inline bool operator!=(const GUID& lhs, const GUID& rhs) noexcept
|
inline bool operator!=(const GUID& lhs, const GUID& rhs) noexcept
|
||||||
{ return !(lhs == rhs); }
|
{ return !(lhs == rhs); }
|
||||||
|
#endif // _SYS_GUID_OPERATOR_EQ_
|
||||||
#endif // GUID_DEFINED
|
#endif // GUID_DEFINED
|
||||||
|
|
||||||
|
|
||||||
|
@ -287,21 +290,19 @@ extern const GUID EAXPROPERTYID_EAX40_Context;
|
||||||
extern const GUID EAXPROPERTYID_EAX50_Context;
|
extern const GUID EAXPROPERTYID_EAX50_Context;
|
||||||
|
|
||||||
// EAX50
|
// EAX50
|
||||||
enum : unsigned long
|
constexpr auto HEADPHONES = 0UL;
|
||||||
{
|
constexpr auto SPEAKERS_2 = 1UL;
|
||||||
HEADPHONES = 0,
|
constexpr auto SPEAKERS_4 = 2UL;
|
||||||
SPEAKERS_2,
|
constexpr auto SPEAKERS_5 = 3UL; // 5.1 speakers
|
||||||
SPEAKERS_4,
|
constexpr auto SPEAKERS_6 = 4UL; // 6.1 speakers
|
||||||
SPEAKERS_5, // 5.1 speakers
|
constexpr auto SPEAKERS_7 = 5UL; // 7.1 speakers
|
||||||
SPEAKERS_6, // 6.1 speakers
|
|
||||||
SPEAKERS_7, // 7.1 speakers
|
constexpr auto EAXCONTEXT_MINSPEAKERCONFIG = HEADPHONES;
|
||||||
};
|
constexpr auto EAXCONTEXT_MAXSPEAKERCONFIG = SPEAKERS_7;
|
||||||
|
|
||||||
// EAX50
|
// EAX50
|
||||||
enum : unsigned long {
|
constexpr auto EAX_40 = 5UL; // EAX 4.0
|
||||||
EAX_40 = 5, // EAX 4.0
|
constexpr auto EAX_50 = 6UL; // EAX 5.0
|
||||||
EAX_50 = 6, // EAX 5.0
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr auto EAXCONTEXT_MINEAXSESSION = EAX_40;
|
constexpr auto EAXCONTEXT_MINEAXSESSION = EAX_40;
|
||||||
constexpr auto EAXCONTEXT_MAXEAXSESSION = EAX_50;
|
constexpr auto EAXCONTEXT_MAXEAXSESSION = EAX_50;
|
||||||
|
@ -370,7 +371,8 @@ extern const GUID EAXPROPERTYID_EAX50_FXSlot2;
|
||||||
extern const GUID EAXPROPERTYID_EAX40_FXSlot3;
|
extern const GUID EAXPROPERTYID_EAX40_FXSlot3;
|
||||||
extern const GUID EAXPROPERTYID_EAX50_FXSlot3;
|
extern const GUID EAXPROPERTYID_EAX50_FXSlot3;
|
||||||
|
|
||||||
extern const GUID EAXCONTEXT_DEFAULTPRIMARYFXSLOTID;
|
extern const GUID EAX40CONTEXT_DEFAULTPRIMARYFXSLOTID;
|
||||||
|
extern const GUID EAX50CONTEXT_DEFAULTPRIMARYFXSLOTID;
|
||||||
|
|
||||||
enum EAXFXSLOT_PROPERTY : unsigned int {
|
enum EAXFXSLOT_PROPERTY : unsigned int {
|
||||||
EAXFXSLOT_PARAMETER = 0,
|
EAXFXSLOT_PARAMETER = 0,
|
||||||
|
|
|
@ -23,6 +23,7 @@ EaxCall::EaxCall(
|
||||||
ALvoid* property_buffer,
|
ALvoid* property_buffer,
|
||||||
ALuint property_size)
|
ALuint property_size)
|
||||||
: type_{type}, version_{0}, property_set_id_{EaxCallPropertySetId::none}
|
: type_{type}, version_{0}, property_set_id_{EaxCallPropertySetId::none}
|
||||||
|
, is_deferred_{(property_id & deferred_flag) != 0}
|
||||||
, property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
|
, property_id_{property_id & ~deferred_flag}, property_source_id_{property_source_id}
|
||||||
, property_buffer_{property_buffer}, property_size_{property_size}
|
, property_buffer_{property_buffer}, property_size_{property_size}
|
||||||
{
|
{
|
||||||
|
@ -150,7 +151,28 @@ EaxCall::EaxCall(
|
||||||
fail("EAX version out of range.");
|
fail("EAX version out of range.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(property_id&deferred_flag))
|
switch(property_id)
|
||||||
|
{
|
||||||
|
case EAXCONTEXT_LASTERROR:
|
||||||
|
case EAXCONTEXT_SPEAKERCONFIG:
|
||||||
|
case EAXCONTEXT_EAXSESSION:
|
||||||
|
case EAXFXSLOT_NONE:
|
||||||
|
case EAXFXSLOT_ALLPARAMETERS:
|
||||||
|
case EAXFXSLOT_LOADEFFECT:
|
||||||
|
case EAXFXSLOT_VOLUME:
|
||||||
|
case EAXFXSLOT_LOCK:
|
||||||
|
case EAXFXSLOT_FLAGS:
|
||||||
|
case EAXFXSLOT_OCCLUSION:
|
||||||
|
case EAXFXSLOT_OCCLUSIONLFRATIO:
|
||||||
|
// EAX allow to set "defer" flag on immediate-only properties.
|
||||||
|
// If we don't clear our flag then "applyAllUpdates" in EAX context won't be called.
|
||||||
|
is_deferred_ = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_deferred_)
|
||||||
{
|
{
|
||||||
if(property_set_id_ != EaxCallPropertySetId::fx_slot && property_id_ != 0)
|
if(property_set_id_ != EaxCallPropertySetId::fx_slot && property_id_ != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@ public:
|
||||||
ALuint property_size);
|
ALuint property_size);
|
||||||
|
|
||||||
bool is_get() const noexcept { return type_ == EaxCallType::get; }
|
bool is_get() const noexcept { return type_ == EaxCallType::get; }
|
||||||
|
bool is_deferred() const noexcept { return is_deferred_; }
|
||||||
int get_version() const noexcept { return version_; }
|
int get_version() const noexcept { return version_; }
|
||||||
EaxCallPropertySetId get_property_set_id() const noexcept { return property_set_id_; }
|
EaxCallPropertySetId get_property_set_id() const noexcept { return property_set_id_; }
|
||||||
ALuint get_property_id() const noexcept { return property_id_; }
|
ALuint get_property_id() const noexcept { return property_id_; }
|
||||||
|
@ -76,6 +77,7 @@ private:
|
||||||
int version_;
|
int version_;
|
||||||
EaxFxSlotIndex fx_slot_index_;
|
EaxFxSlotIndex fx_slot_index_;
|
||||||
EaxCallPropertySetId property_set_id_;
|
EaxCallPropertySetId property_set_id_;
|
||||||
|
bool is_deferred_;
|
||||||
|
|
||||||
ALuint property_id_;
|
ALuint property_id_;
|
||||||
ALuint property_source_id_;
|
ALuint property_source_id_;
|
||||||
|
|
|
@ -35,8 +35,8 @@ template<typename TException, typename TProps>
|
||||||
class EaxEffect4 : public EaxEffect
|
class EaxEffect4 : public EaxEffect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EaxEffect4(ALenum type, const EaxCall& call)
|
EaxEffect4(ALenum type, int eax_version)
|
||||||
: EaxEffect{type}, version_{clamp(call.get_version(), 4, 5)}
|
: EaxEffect{type}, version_{clamp(eax_version, 4, 5)}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
|
@ -70,10 +70,10 @@ protected:
|
||||||
Props d; // Deferred.
|
Props d; // Deferred.
|
||||||
}; // State
|
}; // State
|
||||||
|
|
||||||
int version_;
|
int version_{};
|
||||||
Props props_;
|
Props props_{};
|
||||||
State state4_;
|
State state4_{};
|
||||||
State state5_;
|
State state5_{};
|
||||||
|
|
||||||
template<typename TValidator, typename TProperty>
|
template<typename TValidator, typename TProperty>
|
||||||
static void defer(const EaxCall& call, TProperty& property)
|
static void defer(const EaxCall& call, TProperty& property)
|
||||||
|
@ -149,25 +149,25 @@ using EaxEffectUPtr = std::unique_ptr<EaxEffect>;
|
||||||
|
|
||||||
// Creates EAX4+ effect.
|
// Creates EAX4+ effect.
|
||||||
template<typename TEffect>
|
template<typename TEffect>
|
||||||
EaxEffectUPtr eax_create_eax4_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax4_effect(int eax_version)
|
||||||
{
|
{
|
||||||
auto effect = std::make_unique<TEffect>(call);
|
auto effect = std::make_unique<TEffect>(eax_version);
|
||||||
effect->initialize();
|
effect->initialize();
|
||||||
return effect;
|
return effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
EaxEffectUPtr eax_create_eax_null_effect();
|
EaxEffectUPtr eax_create_eax_null_effect();
|
||||||
EaxEffectUPtr eax_create_eax_chorus_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_chorus_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_distortion_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_distortion_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_echo_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_echo_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_flanger_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_flanger_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_frequency_shifter_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_frequency_shifter_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_vocal_morpher_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_vocal_morpher_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_pitch_shifter_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_pitch_shifter_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_ring_modulator_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_ring_modulator_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_auto_wah_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_auto_wah_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_compressor_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_compressor_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_equalizer_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_equalizer_effect(int eax_version);
|
||||||
EaxEffectUPtr eax_create_eax_reverb_effect(const EaxCall& call);
|
EaxEffectUPtr eax_create_eax_reverb_effect(int eax_version);
|
||||||
|
|
||||||
#endif // !EAX_EFFECT_INCLUDED
|
#endif // !EAX_EFFECT_INCLUDED
|
||||||
|
|
|
@ -6,17 +6,14 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
EaxException::EaxException(
|
EaxException::EaxException(const char *context, const char *message)
|
||||||
const char* context,
|
: std::runtime_error{make_message(context, message)}
|
||||||
const char* message)
|
|
||||||
:
|
|
||||||
std::runtime_error{make_message(context, message)}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
EaxException::~EaxException() = default;
|
||||||
|
|
||||||
std::string EaxException::make_message(
|
|
||||||
const char* context,
|
std::string EaxException::make_message(const char *context, const char *message)
|
||||||
const char* message)
|
|
||||||
{
|
{
|
||||||
const auto context_size = (context ? std::string::traits_type::length(context) : 0);
|
const auto context_size = (context ? std::string::traits_type::length(context) : 0);
|
||||||
const auto has_contex = (context_size > 0);
|
const auto has_contex = (context_size > 0);
|
||||||
|
|
|
@ -6,19 +6,12 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
class EaxException :
|
class EaxException : public std::runtime_error {
|
||||||
public std::runtime_error
|
static std::string make_message(const char *context, const char *message);
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
EaxException(
|
EaxException(const char *context, const char *message);
|
||||||
const char* context,
|
~EaxException() override;
|
||||||
const char* message);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
static std::string make_message(
|
|
||||||
const char* context,
|
|
||||||
const char* message);
|
|
||||||
}; // EaxException
|
}; // EaxException
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,11 +28,9 @@ public:
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
void EaxFxSlots::initialize(
|
void EaxFxSlots::initialize(ALCcontext& al_context)
|
||||||
const EaxCall& call,
|
|
||||||
ALCcontext& al_context)
|
|
||||||
{
|
{
|
||||||
initialize_fx_slots(call, al_context);
|
initialize_fx_slots(al_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EaxFxSlots::uninitialize() noexcept
|
void EaxFxSlots::uninitialize() noexcept
|
||||||
|
@ -57,12 +55,6 @@ ALeffectslot& EaxFxSlots::get(EaxFxSlotIndex index)
|
||||||
return *fx_slots_[index.value()];
|
return *fx_slots_[index.value()];
|
||||||
}
|
}
|
||||||
|
|
||||||
void EaxFxSlots::unlock_legacy() noexcept
|
|
||||||
{
|
|
||||||
fx_slots_[0]->eax_unlock_legacy();
|
|
||||||
fx_slots_[1]->eax_unlock_legacy();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[noreturn]]
|
[[noreturn]]
|
||||||
void EaxFxSlots::fail(
|
void EaxFxSlots::fail(
|
||||||
const char* message)
|
const char* message)
|
||||||
|
@ -70,16 +62,14 @@ void EaxFxSlots::fail(
|
||||||
throw EaxFxSlotsException{message};
|
throw EaxFxSlotsException{message};
|
||||||
}
|
}
|
||||||
|
|
||||||
void EaxFxSlots::initialize_fx_slots(
|
void EaxFxSlots::initialize_fx_slots(ALCcontext& al_context)
|
||||||
const EaxCall& call,
|
|
||||||
ALCcontext& al_context)
|
|
||||||
{
|
{
|
||||||
auto fx_slot_index = EaxFxSlotIndexValue{};
|
auto fx_slot_index = EaxFxSlotIndexValue{};
|
||||||
|
|
||||||
for (auto& fx_slot : fx_slots_)
|
for (auto& fx_slot : fx_slots_)
|
||||||
{
|
{
|
||||||
fx_slot = eax_create_al_effect_slot(al_context);
|
fx_slot = eax_create_al_effect_slot(al_context);
|
||||||
fx_slot->eax_initialize(call, al_context, fx_slot_index);
|
fx_slot->eax_initialize(al_context, fx_slot_index);
|
||||||
fx_slot_index += 1;
|
fx_slot_index += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,7 @@
|
||||||
class EaxFxSlots
|
class EaxFxSlots
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void initialize(
|
void initialize(ALCcontext& al_context);
|
||||||
const EaxCall& call,
|
|
||||||
ALCcontext& al_context);
|
|
||||||
|
|
||||||
void uninitialize() noexcept;
|
void uninitialize() noexcept;
|
||||||
|
|
||||||
|
@ -33,9 +31,6 @@ public:
|
||||||
ALeffectslot& get(
|
ALeffectslot& get(
|
||||||
EaxFxSlotIndex index);
|
EaxFxSlotIndex index);
|
||||||
|
|
||||||
void unlock_legacy() noexcept;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Items = std::array<EaxAlEffectSlotUPtr, EAX_MAX_FXSLOTS>;
|
using Items = std::array<EaxAlEffectSlotUPtr, EAX_MAX_FXSLOTS>;
|
||||||
|
|
||||||
|
@ -47,9 +42,7 @@ private:
|
||||||
static void fail(
|
static void fail(
|
||||||
const char* message);
|
const char* message);
|
||||||
|
|
||||||
void initialize_fx_slots(
|
void initialize_fx_slots(ALCcontext& al_context);
|
||||||
const EaxCall& call,
|
|
||||||
ALCcontext& al_context);
|
|
||||||
}; // EaxFxSlots
|
}; // EaxFxSlots
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,29 +8,19 @@
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
|
|
||||||
|
|
||||||
void eax_log_exception(
|
void eax_log_exception(const char *message) noexcept
|
||||||
const char* message) noexcept
|
|
||||||
{
|
{
|
||||||
const auto exception_ptr = std::current_exception();
|
const auto exception_ptr = std::current_exception();
|
||||||
|
|
||||||
assert(exception_ptr);
|
assert(exception_ptr);
|
||||||
|
|
||||||
if (message)
|
try {
|
||||||
{
|
|
||||||
ERR("%s\n", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
std::rethrow_exception(exception_ptr);
|
std::rethrow_exception(exception_ptr);
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch(const std::exception& ex) {
|
||||||
{
|
|
||||||
const auto ex_message = ex.what();
|
const auto ex_message = ex.what();
|
||||||
ERR("%s\n", ex_message);
|
ERR("%s %s\n", message ? message : "", ex_message);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch(...) {
|
||||||
{
|
ERR("%s %s\n", message ? message : "", "Generic exception.");
|
||||||
ERR("%s\n", "Generic exception.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,14 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
using EaxDirtyFlags = unsigned int;
|
||||||
|
|
||||||
struct EaxAlLowPassParam {
|
struct EaxAlLowPassParam {
|
||||||
float gain;
|
float gain;
|
||||||
float gain_hf;
|
float gain_hf;
|
||||||
};
|
};
|
||||||
|
|
||||||
void eax_log_exception(const char* message = nullptr) noexcept;
|
void eax_log_exception(const char *message) noexcept;
|
||||||
|
|
||||||
template<typename TException, typename TValue>
|
template<typename TException, typename TValue>
|
||||||
void eax_validate_range(
|
void eax_validate_range(
|
||||||
|
|
|
@ -86,6 +86,7 @@ effect_exception::effect_exception(ALenum code, const char *msg, ...) : mErrorCo
|
||||||
setMessage(msg, args);
|
setMessage(msg, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
effect_exception::~effect_exception() = default;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -139,7 +140,7 @@ const EffectPropsItem *getEffectPropsItemByType(ALenum type)
|
||||||
auto iter = std::find_if(std::begin(EffectPropsList), std::end(EffectPropsList),
|
auto iter = std::find_if(std::begin(EffectPropsList), std::end(EffectPropsList),
|
||||||
[type](const EffectPropsItem &item) noexcept -> bool
|
[type](const EffectPropsItem &item) noexcept -> bool
|
||||||
{ return item.Type == type; });
|
{ return item.Type == type; });
|
||||||
return (iter != std::end(EffectPropsList)) ? std::addressof(*iter) : nullptr;
|
return (iter != std::end(EffectPropsList)) ? al::to_address(iter) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitEffectParams(ALeffect *effect, ALenum type)
|
void InitEffectParams(ALeffect *effect, ALenum type)
|
||||||
|
@ -166,14 +167,14 @@ bool EnsureEffects(ALCdevice *device, size_t needed)
|
||||||
|
|
||||||
while(needed > count)
|
while(needed > count)
|
||||||
{
|
{
|
||||||
if UNLIKELY(device->EffectList.size() >= 1<<25)
|
if(device->EffectList.size() >= 1<<25) [[unlikely]]
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
device->EffectList.emplace_back();
|
device->EffectList.emplace_back();
|
||||||
auto sublist = device->EffectList.end() - 1;
|
auto sublist = device->EffectList.end() - 1;
|
||||||
sublist->FreeMask = ~0_u64;
|
sublist->FreeMask = ~0_u64;
|
||||||
sublist->Effects = static_cast<ALeffect*>(al_calloc(alignof(ALeffect), sizeof(ALeffect)*64));
|
sublist->Effects = static_cast<ALeffect*>(al_calloc(alignof(ALeffect), sizeof(ALeffect)*64));
|
||||||
if UNLIKELY(!sublist->Effects)
|
if(!sublist->Effects) [[unlikely]]
|
||||||
{
|
{
|
||||||
device->EffectList.pop_back();
|
device->EffectList.pop_back();
|
||||||
return false;
|
return false;
|
||||||
|
@ -219,10 +220,10 @@ inline ALeffect *LookupEffect(ALCdevice *device, ALuint id)
|
||||||
const size_t lidx{(id-1) >> 6};
|
const size_t lidx{(id-1) >> 6};
|
||||||
const ALuint slidx{(id-1) & 0x3f};
|
const ALuint slidx{(id-1) & 0x3f};
|
||||||
|
|
||||||
if UNLIKELY(lidx >= device->EffectList.size())
|
if(lidx >= device->EffectList.size()) [[unlikely]]
|
||||||
return nullptr;
|
return nullptr;
|
||||||
EffectSubList &sublist = device->EffectList[lidx];
|
EffectSubList &sublist = device->EffectList[lidx];
|
||||||
if UNLIKELY(sublist.FreeMask & (1_u64 << slidx))
|
if(sublist.FreeMask & (1_u64 << slidx)) [[unlikely]]
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return sublist.Effects + slidx;
|
return sublist.Effects + slidx;
|
||||||
}
|
}
|
||||||
|
@ -233,11 +234,11 @@ AL_API void AL_APIENTRY alGenEffects(ALsizei n, ALuint *effects)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
if UNLIKELY(n < 0)
|
if(n < 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Generating %d effects", n);
|
context->setError(AL_INVALID_VALUE, "Generating %d effects", n);
|
||||||
if UNLIKELY(n <= 0) return;
|
if(n <= 0) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
@ -247,7 +248,7 @@ START_API_FUNC
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if LIKELY(n == 1)
|
if(n == 1) [[likely]]
|
||||||
{
|
{
|
||||||
/* Special handling for the easy and normal case. */
|
/* Special handling for the easy and normal case. */
|
||||||
ALeffect *effect{AllocEffect(device)};
|
ALeffect *effect{AllocEffect(device)};
|
||||||
|
@ -273,11 +274,11 @@ AL_API void AL_APIENTRY alDeleteEffects(ALsizei n, const ALuint *effects)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
if UNLIKELY(n < 0)
|
if(n < 0) [[unlikely]]
|
||||||
context->setError(AL_INVALID_VALUE, "Deleting %d effects", n);
|
context->setError(AL_INVALID_VALUE, "Deleting %d effects", n);
|
||||||
if UNLIKELY(n <= 0) return;
|
if(n <= 0) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
@ -288,7 +289,7 @@ START_API_FUNC
|
||||||
|
|
||||||
const ALuint *effects_end = effects + n;
|
const ALuint *effects_end = effects + n;
|
||||||
auto inveffect = std::find_if_not(effects, effects_end, validate_effect);
|
auto inveffect = std::find_if_not(effects, effects_end, validate_effect);
|
||||||
if UNLIKELY(inveffect != effects_end)
|
if(inveffect != effects_end) [[unlikely]]
|
||||||
{
|
{
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", *inveffect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", *inveffect);
|
||||||
return;
|
return;
|
||||||
|
@ -308,7 +309,7 @@ AL_API ALboolean AL_APIENTRY alIsEffect(ALuint effect)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if LIKELY(context)
|
if(context) [[likely]]
|
||||||
{
|
{
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
@ -323,13 +324,13 @@ AL_API void AL_APIENTRY alEffecti(ALuint effect, ALenum param, ALint value)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else if(param == AL_EFFECT_TYPE)
|
else if(param == AL_EFFECT_TYPE)
|
||||||
{
|
{
|
||||||
|
@ -373,13 +374,13 @@ START_API_FUNC
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else try
|
else try
|
||||||
{
|
{
|
||||||
|
@ -396,13 +397,13 @@ AL_API void AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat value)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else try
|
else try
|
||||||
{
|
{
|
||||||
|
@ -419,13 +420,13 @@ AL_API void AL_APIENTRY alEffectfv(ALuint effect, ALenum param, const ALfloat *v
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
ALeffect *aleffect{LookupEffect(device, effect)};
|
ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else try
|
else try
|
||||||
{
|
{
|
||||||
|
@ -442,13 +443,13 @@ AL_API void AL_APIENTRY alGetEffecti(ALuint effect, ALenum param, ALint *value)
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else if(param == AL_EFFECT_TYPE)
|
else if(param == AL_EFFECT_TYPE)
|
||||||
*value = aleffect->type;
|
*value = aleffect->type;
|
||||||
|
@ -474,13 +475,13 @@ START_API_FUNC
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else try
|
else try
|
||||||
{
|
{
|
||||||
|
@ -497,13 +498,13 @@ AL_API void AL_APIENTRY alGetEffectf(ALuint effect, ALenum param, ALfloat *value
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else try
|
else try
|
||||||
{
|
{
|
||||||
|
@ -520,13 +521,13 @@ AL_API void AL_APIENTRY alGetEffectfv(ALuint effect, ALenum param, ALfloat *valu
|
||||||
START_API_FUNC
|
START_API_FUNC
|
||||||
{
|
{
|
||||||
ContextRef context{GetContextRef()};
|
ContextRef context{GetContextRef()};
|
||||||
if UNLIKELY(!context) return;
|
if(!context) [[unlikely]] return;
|
||||||
|
|
||||||
ALCdevice *device{context->mALDevice.get()};
|
ALCdevice *device{context->mALDevice.get()};
|
||||||
std::lock_guard<std::mutex> _{device->EffectLock};
|
std::lock_guard<std::mutex> _{device->EffectLock};
|
||||||
|
|
||||||
const ALeffect *aleffect{LookupEffect(device, effect)};
|
const ALeffect *aleffect{LookupEffect(device, effect)};
|
||||||
if UNLIKELY(!aleffect)
|
if(!aleffect) [[unlikely]]
|
||||||
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
context->setError(AL_INVALID_NAME, "Invalid effect ID %u", effect);
|
||||||
else try
|
else try
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,7 +127,7 @@ public:
|
||||||
|
|
||||||
class EaxAutoWahEffect final : public EaxEffect4<EaxAutoWahEffectException, EAXAUTOWAHPROPERTIES> {
|
class EaxAutoWahEffect final : public EaxEffect4<EaxAutoWahEffectException, EAXAUTOWAHPROPERTIES> {
|
||||||
public:
|
public:
|
||||||
EaxAutoWahEffect(const EaxCall& call);
|
EaxAutoWahEffect(int eax_version);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct AttackTimeValidator {
|
struct AttackTimeValidator {
|
||||||
|
@ -197,8 +197,8 @@ private:
|
||||||
bool commit_props(const Props& props) override;
|
bool commit_props(const Props& props) override;
|
||||||
}; // EaxAutoWahEffect
|
}; // EaxAutoWahEffect
|
||||||
|
|
||||||
EaxAutoWahEffect::EaxAutoWahEffect(const EaxCall& call)
|
EaxAutoWahEffect::EaxAutoWahEffect(int eax_version)
|
||||||
: EaxEffect4{AL_EFFECT_AUTOWAH, call}
|
: EaxEffect4{AL_EFFECT_AUTOWAH, eax_version}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void EaxAutoWahEffect::set_defaults(Props& props)
|
void EaxAutoWahEffect::set_defaults(Props& props)
|
||||||
|
@ -310,9 +310,9 @@ bool EaxAutoWahEffect::commit_props(const Props& props)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EaxEffectUPtr eax_create_eax_auto_wah_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax_auto_wah_effect(int eax_version)
|
||||||
{
|
{
|
||||||
return eax_create_eax4_effect<EaxAutoWahEffect>(call);
|
return eax_create_eax4_effect<EaxAutoWahEffect>(eax_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
|
|
|
@ -31,8 +31,8 @@ inline al::optional<ChorusWaveform> WaveformFromEnum(ALenum type)
|
||||||
{
|
{
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case AL_CHORUS_WAVEFORM_SINUSOID: return al::make_optional(ChorusWaveform::Sinusoid);
|
case AL_CHORUS_WAVEFORM_SINUSOID: return ChorusWaveform::Sinusoid;
|
||||||
case AL_CHORUS_WAVEFORM_TRIANGLE: return al::make_optional(ChorusWaveform::Triangle);
|
case AL_CHORUS_WAVEFORM_TRIANGLE: return ChorusWaveform::Triangle;
|
||||||
}
|
}
|
||||||
return al::nullopt;
|
return al::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ void Chorus_getParamf(const EffectProps *props, ALenum param, float *val)
|
||||||
void Chorus_getParamfv(const EffectProps *props, ALenum param, float *vals)
|
void Chorus_getParamfv(const EffectProps *props, ALenum param, float *vals)
|
||||||
{ Chorus_getParamf(props, param, vals); }
|
{ Chorus_getParamf(props, param, vals); }
|
||||||
|
|
||||||
const EffectProps genDefaultChorusProps() noexcept
|
EffectProps genDefaultChorusProps() noexcept
|
||||||
{
|
{
|
||||||
EffectProps props{};
|
EffectProps props{};
|
||||||
props.Chorus.Waveform = *WaveformFromEnum(AL_CHORUS_DEFAULT_WAVEFORM);
|
props.Chorus.Waveform = *WaveformFromEnum(AL_CHORUS_DEFAULT_WAVEFORM);
|
||||||
|
@ -433,8 +433,8 @@ public:
|
||||||
using typename Base::State;
|
using typename Base::State;
|
||||||
using Base::defer;
|
using Base::defer;
|
||||||
|
|
||||||
EaxChorusFlangerEffect(const EaxCall& call)
|
EaxChorusFlangerEffect(int eax_version)
|
||||||
: Base{Traits::efx_effect(), call}
|
: Base{Traits::efx_effect(), eax_version}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -712,23 +712,23 @@ private:
|
||||||
}; // EaxChorusFlangerEffect
|
}; // EaxChorusFlangerEffect
|
||||||
|
|
||||||
template<typename TTraits>
|
template<typename TTraits>
|
||||||
EaxEffectUPtr eax_create_eax_chorus_flanger_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax_chorus_flanger_effect(int eax_version)
|
||||||
{
|
{
|
||||||
return eax_create_eax4_effect<EaxChorusFlangerEffect<TTraits>>(call);
|
return eax_create_eax4_effect<EaxChorusFlangerEffect<TTraits>>(eax_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
EaxEffectUPtr eax_create_eax_chorus_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax_chorus_effect(int eax_version)
|
||||||
{
|
{
|
||||||
return eax_create_eax_chorus_flanger_effect<EaxChorusTraits>(call);
|
return eax_create_eax_chorus_flanger_effect<EaxChorusTraits>(eax_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
EaxEffectUPtr eax_create_eax_flanger_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax_flanger_effect(int eax_version)
|
||||||
{
|
{
|
||||||
return eax_create_eax_chorus_flanger_effect<EaxFlangerTraits>(call);
|
return eax_create_eax_chorus_flanger_effect<EaxFlangerTraits>(eax_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
|
|
|
@ -91,7 +91,7 @@ public:
|
||||||
class EaxCompressorEffect final : public EaxEffect4<EaxCompressorEffectException, EAXAGCCOMPRESSORPROPERTIES>
|
class EaxCompressorEffect final : public EaxEffect4<EaxCompressorEffectException, EAXAGCCOMPRESSORPROPERTIES>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EaxCompressorEffect(const EaxCall& call);
|
EaxCompressorEffect(int eax_version);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct OnOffValidator {
|
struct OnOffValidator {
|
||||||
|
@ -122,8 +122,8 @@ private:
|
||||||
bool commit_props(const Props& props) override;
|
bool commit_props(const Props& props) override;
|
||||||
}; // EaxCompressorEffect
|
}; // EaxCompressorEffect
|
||||||
|
|
||||||
EaxCompressorEffect::EaxCompressorEffect(const EaxCall& call)
|
EaxCompressorEffect::EaxCompressorEffect(int eax_version)
|
||||||
: EaxEffect4{AL_EFFECT_COMPRESSOR, call}
|
: EaxEffect4{AL_EFFECT_COMPRESSOR, eax_version}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void EaxCompressorEffect::set_defaults(Props& props)
|
void EaxCompressorEffect::set_defaults(Props& props)
|
||||||
|
@ -182,9 +182,9 @@ bool EaxCompressorEffect::commit_props(const Props& props)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EaxEffectUPtr eax_create_eax_compressor_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax_compressor_effect(int eax_version)
|
||||||
{
|
{
|
||||||
return eax_create_eax4_effect<EaxCompressorEffect>(call);
|
return eax_create_eax4_effect<EaxCompressorEffect>(eax_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
|
|
|
@ -133,7 +133,7 @@ public:
|
||||||
class EaxDistortionEffect final : public EaxEffect4<EaxDistortionEffectException, EAXDISTORTIONPROPERTIES>
|
class EaxDistortionEffect final : public EaxEffect4<EaxDistortionEffectException, EAXDISTORTIONPROPERTIES>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EaxDistortionEffect(const EaxCall& call);
|
EaxDistortionEffect(int eax_version);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct EdgeValidator {
|
struct EdgeValidator {
|
||||||
|
@ -216,8 +216,8 @@ private:
|
||||||
bool commit_props(const Props& props) override;
|
bool commit_props(const Props& props) override;
|
||||||
}; // EaxDistortionEffect
|
}; // EaxDistortionEffect
|
||||||
|
|
||||||
EaxDistortionEffect::EaxDistortionEffect(const EaxCall& call)
|
EaxDistortionEffect::EaxDistortionEffect(int eax_version)
|
||||||
: EaxEffect4{AL_EFFECT_DISTORTION, call}
|
: EaxEffect4{AL_EFFECT_DISTORTION, eax_version}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void EaxDistortionEffect::set_defaults(Props& props)
|
void EaxDistortionEffect::set_defaults(Props& props)
|
||||||
|
@ -347,9 +347,9 @@ bool EaxDistortionEffect::commit_props(const Props& props)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EaxEffectUPtr eax_create_eax_distortion_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax_distortion_effect(int eax_version)
|
||||||
{
|
{
|
||||||
return eax_create_eax4_effect<EaxDistortionEffect>(call);
|
return eax_create_eax4_effect<EaxDistortionEffect>(eax_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
|
|
|
@ -130,7 +130,7 @@ public:
|
||||||
class EaxEchoEffect final : public EaxEffect4<EaxEchoEffectException, EAXECHOPROPERTIES>
|
class EaxEchoEffect final : public EaxEffect4<EaxEchoEffectException, EAXECHOPROPERTIES>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EaxEchoEffect(const EaxCall& call);
|
EaxEchoEffect(int eax_version);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct DelayValidator {
|
struct DelayValidator {
|
||||||
|
@ -213,8 +213,8 @@ private:
|
||||||
bool commit_props(const Props& props) override;
|
bool commit_props(const Props& props) override;
|
||||||
}; // EaxEchoEffect
|
}; // EaxEchoEffect
|
||||||
|
|
||||||
EaxEchoEffect::EaxEchoEffect(const EaxCall& call)
|
EaxEchoEffect::EaxEchoEffect(int eax_version)
|
||||||
: EaxEffect4{AL_EFFECT_ECHO, call}
|
: EaxEffect4{AL_EFFECT_ECHO, eax_version}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void EaxEchoEffect::set_defaults(Props& props)
|
void EaxEchoEffect::set_defaults(Props& props)
|
||||||
|
@ -344,9 +344,9 @@ bool EaxEchoEffect::commit_props(const Props& props)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
EaxEffectUPtr eax_create_eax_echo_effect(const EaxCall& call)
|
EaxEffectUPtr eax_create_eax_echo_effect(int eax_version)
|
||||||
{
|
{
|
||||||
return eax_create_eax4_effect<EaxEchoEffect>(call);
|
return eax_create_eax4_effect<EaxEchoEffect>(eax_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ALSOFT_EAX
|
#endif // ALSOFT_EAX
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue