sdaiGetADBValue

valueType argument to specify what type of data caller wants to get and value argument where the caller should provide a buffer, and the function will write the result to. Table 1 shows type of buffer the caller should provide depending on the valueType for sdaiGetADBValue, and it works similarly for all get-functions. Note: with SDAI API it is impossible to check buffer type at compilation or execution time and this is responsibility of a caller to ensure that requested valueType is matching with the value argument, a mismatch will lead to unpredictable results. The Table 2 shows what valueType can be fulfilled depending on actual model data. If a get-function cannot get a value it will return 0, it may happen when model item is unset ($) or incompatible with requested valueType. To separate these cases you can use engiGetInstanceAttrType(BN), sdaiGetADBType and engiGetAggrType. On success get-function will return non-zero. More precisely, according to ISO 10303-24-2001 on success they return content of value argument (*value) for sdaiADB, sdaiAGGR, or sdaiINSTANCE or value argument itself for other types (it has no useful meaning for C#).

Table 1 – Required value buffer depending on valueType (on the example of sdaiGetADBValue but valid for all get-functions)

valueType               C/C++                                               C#

sdaiINTEGER             int_t val;                                          int_t val;
                        sdaiGetADBValue (ADB, sdaiINTEGER, &val);           ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiINTEGER, out val);

sdaiREAL or sdaiNUMBER  double val;                                         double val;
                        sdaiGetADBValue (ADB, sdaiREAL, &val);              ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiREAL, out val);

sdaiBOOLEAN             bool val;                                           bool val;
                        sdaiGetADBValue (ADB, sdaiBOOLEAN, &val);           ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiBOOLEAN, out val);

sdaiLOGICAL             const TCHAR* val;                                   string val;
                        sdaiGetADBValue (ADB, sdaiLOGICAL, &val);           ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiLOGICAL, out val);

sdaiENUM                const TCHAR* val;                                   string val;
                        sdaiGetADBValue (ADB, sdaiENUM, &val);              ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiENUM, out val);

sdaiBINARY              const TCHAR* val;                                   string val;
                        sdaiGetADBValue (ADB, sdaiBINARY, &val);            ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiBINARY, out val);

sdaiSTRING              const char* val;                                    string val;
                        sdaiGetADBValue (ADB, sdaiSTRING, &val);            ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiSTRING, out val);

sdaiUNICODE             const wchar_t* val;                                 string val;
                        sdaiGetADBValue (ADB, sdaiUNICODE, &val);           ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiSTRING, out val);

sdaiEXPRESSSTRING       const char* val;                                    string val;
                        sdaiGetADBValue (ADB, sdaiEXPRESSSTRING, &val);     ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiEXPRESSSTRING, out val);

sdaiINSTANCE            SdaiInstance val;                                   int_t val;
                        sdaiGetADBValue (ADB, sdaiINSTANCE, &val);          ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiINSTANCE, out val);

sdaiAGGR                SdaiAggr aggr;                                      int_t aggr;
                        sdaiGetADBValue (ADB, sdaiAGGR, &aggr);             ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiINSTANCE, out aggr);

sdaiADB                 SdaiADB adb = sdaiCreateEmptyADB();                 int_t adb = 0;  //  it is important to initialize
                        sdaiGetADBValue (ADB, sdaiADB, adb);                ifcengine.sdaiGetADBValue (ADB, ifcengine.sdaiADB, out adb);        
                        sdaiDeleteADB (adb);

                        SdaiADB adb = nullptr;  //  it is important to initialize
                        sdaiGetADBValue (ADB, sdaiADB, &adb);
TCHAR is “char” or “wchar_t” depending on setStringUnicode. (Non-standard behavior) sdaiLOGICAL behaves differently from ISO 10303-24-2001: it expects char* while standard declares int_t (Non-standard extension) sdiADB in C++ has an option to work without sdaiCreateEmptyADB and sdaiDeleteADB as shown in the table
Table 2 - valueType can be requested depending on actual model data.

valueType       Works for following values in the model
                  integer      real     .T. or .F.     .U.      other enum    binary      string     instance      list      $ (empty)
sdaiINTEGER         Yes         Yes *        .           .           .           .           .           .           .           .
sdaiREAL            Yes         Yes          .           .           .           .           .           .           .           .
sdaiNUMBER          Yes         Yes          .           .           .           .           .           .           .           .
sdaiBOOLEAN          .           .          Yes          .           .           .           .           .           .           .
sdaiLOGICAL          .           .          Yes         Yes          .           .           .           .           .           .
sdaiENUM             .           .          Yes         Yes         Yes          .           .           .           .           .
sdaiBINARY           .           .           .           .           .          Yes          .           .           .           .
sdaiSTRING          Yes         Yes         Yes         Yes         Yes         Yes         Yes          .           .           .
sdaiUNICODE         Yes         Yes         Yes         Yes         Yes         Yes         Yes          .           .           .
sdaiEXPRESSSTRING   Yes         Yes         Yes         Yes         Yes         Yes         Yes          .           .           .
sdaiINSTANCE         .           .           .           .           .           .           .          Yes          .           .
sdaiAGGR             .           .           .           .           .           .           .           .          Yes          .
sdaiADB             Yes         Yes         Yes         Yes         Yes         Yes         Yes         Yes         Yes          .
Note: sdaiGetAttr, stdaiGetAttrBN, engiGetElement will success with any model data, except non-set($) (Non-standard extensions) sdaiGetADBValue: sdaiADB is allowed and will success when sdaiGetADBTypePath is not NULL, returning ABD value has type path element removed.

Syntax

//
//   Strong typing definition
//
void            * sdaiGetADBValue(
                        const SdaiADB           ADB,
                        SdaiPrimitiveType       valueType,
                        void                    * value
                    );


//
//   Weak typing definition
//
void    __declspec(dllexport) * __stdcall sdaiGetADBValue(
                                                                        const void              * ADB,
                                                                        int_t                   valueType,
                                                                        void                    * value
                                                                    );
    

Property ADB

Size: 64 bit / 8 byte (reference)
...

Property valueType

Size: 64 bit / 8 byte (value)
...

Property value

Size: 64 bit / 8 byte (reference)
...

Example (based on pure API calls)

Here you can find code snippits that show how the API call sdaiGetADBValue can be used.

#include    "./include/ifcengine.h"
#include    <iostream>

//
//  The following code allows output as found in SPFF (STEP Physical File Format)
//

using namespace std;

void    CreateLineAggregation__cout(
                SdaiAggr        aggregation
            );

char    BUFF__cout[512];

char    * UpperCase__cout(
                char    * in
            )
{
    assert(strlen(in) < 256);
    size_t  len = strlen(in);
    for (size_t i = 0; i <= len; i++) {
        if (in[i] >= 'a' && in[i] <= 'z')
            BUFF__cout[i] = in[i] - 'a' + 'A';
        else
            BUFF__cout[i] = in[i];
    }
    return  BUFF__cout;
}

void    CreateInstance__cout(
                SdaiInstance    instance
            )
{
    assert(instance);

    cout << "#" << internalGetP21Line(instance);
}

void    CreateBoolean__cout(
                bool            value
            )
{
    if (value)
        cout << ".T.";
    else
        cout << ".F.";
}

void    CreateLogical__cout(
                char            * value
            )
{
    cout << "." << value << ".";
}

void    CreateEnumeration__cout(
                char            * value
            )
{
    cout << "." << value << ".";
}

void    CreateReal__cout(
                double          value
            )
{
    cout << value;
}

void    CreateInteger__cout(
                int_t           value
            )
{
    cout << value;
}

void    CreateString__cout(
                char            * value
            )
{
    if (value)
        cout << "'" << value << "'";
    else
        cout << "''";
}

void    CreateLineADB__cout(
                SdaiADB         ADB
            )
{
    cout << sdaiGetADBTypePath(ADB, sdaiSTRING);

    switch (sdaiGetADBType(ADB)) {
        case  sdaiADB:
            {
                SdaiADB    attributeDataBlock = 0;
                if (sdaiGetADBValue(ADB, sdaiADB, &attributeDataBlock)) {
                    CreateLineADB__cout(attributeDataBlock);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiAGGR:
            {
                SdaiAggr        valueAggr = nullptr;
                SdaiInstance    valueInstance = 0;
                if (sdaiGetADBValue(ADB, sdaiAGGR, &valueAggr)) {
                    cout << "(";
                    CreateLineAggregation__cout(valueAggr);
                    cout << ")";
                }
                else if (sdaiGetADBValue(ADB, sdaiINSTANCE, &valueInstance)) {
                    CreateInstance__cout(valueInstance);
                }
                else {
                    assert(false);
                }
            }
            break;
        case  sdaiINSTANCE:
            {
                SdaiInstance    value = 0;
                if (sdaiGetADBValue(ADB, sdaiINSTANCE, &value)) {
                    CreateInstance__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiBOOLEAN:
            {
                bool    value = false;
                if (sdaiGetADBValue(ADB, sdaiBOOLEAN, &value)) {
                    CreateBoolean__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiLOGICAL:
            {
                char    * value = nullptr;
                if (sdaiGetADBValue(ADB, sdaiLOGICAL, &value)) {
                    CreateLogical__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiENUM:
            {
                char    * value = nullptr;
                if (sdaiGetADBValue(ADB, sdaiENUM, &value)) {
                    CreateEnumeration__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiREAL:
            {
                double  value = 0.;
                if (sdaiGetADBValue(ADB, sdaiREAL, &value)) {
                    CreateReal__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiINTEGER:
            {
                int_t   value = 0;
                if (sdaiGetADBValue(ADB, sdaiINTEGER, &value)) {
                    CreateInteger__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiSTRING:
            {
                char    * value = nullptr;
                if (sdaiGetADBValue(ADB, sdaiEXPRESSSTRING, &value)) {
                    CreateString__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        default:
            assert(false);
            cout << "??";
            break;
    }

    cout << ")";
}

void    CreateLineAggregationElement__cout(
                SdaiAggr        aggregation,
                int_t           aggrType,
                SdaiInteger     index
            )
{
    switch (aggrType) {
        case  sdaiADB:
            {
                SdaiADB    attributeDataBlock = 0;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiADB, &attributeDataBlock)) {
                    CreateLineADB__cout(attributeDataBlock);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiAGGR:
            {
                SdaiAggr        valueAggr = nullptr;
                SdaiInstance    valueInstance = 0;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiAGGR, &valueAggr)) {
                    cout << "(";
                    CreateLineAggregation__cout(valueAggr);
                    cout << ")";
                }
                else if (sdaiGetAggrByIndex(aggregation, index, sdaiINSTANCE, &valueInstance)) {
                    CreateInstance__cout(valueInstance);
                }
                else {
                    assert(false);
                }
            }
            break;
        case  sdaiINSTANCE:
            {
                SdaiInstance    value = 0;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiINSTANCE, &value)) {
                    CreateInstance__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiBOOLEAN:
            {
                bool    value = false;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiBOOLEAN, &value)) {
                    CreateBoolean__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiLOGICAL:
            {
                char    * value = nullptr;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiLOGICAL, &value)) {
                    CreateLogical__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiENUM:
            {
                char    * value = nullptr;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiENUM, &value)) {
                    CreateEnumeration__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiREAL:
            {
                double  value = 0.;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiREAL, &value)) {
                    CreateReal__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiINTEGER:
            {
                int_t   value = 0;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiINTEGER, &value)) {
                    CreateInteger__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiSTRING:
            {
                char    * value = nullptr;
                if (sdaiGetAggrByIndex(aggregation, index, sdaiEXPRESSSTRING, &value)) {
                    CreateString__cout(value);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        default:
            assert(false);
            cout << "??";
            break;
    }
}

void    CreateLineAggregation__cout(
                SdaiAggr        aggregation
            )
{
    SdaiInteger memberCount = sdaiGetMemberCount(aggregation);
    if (memberCount == 0)
        return;

    int_t   aggrType = 0;
    engiGetAggrType(aggregation, &aggrType);

    SdaiInteger index = 0;
    CreateLineAggregationElement__cout(aggregation, aggrType, index++);
    while (index < memberCount) {
        cout << ", ";
        CreateLineAggregationElement__cout(aggregation, aggrType, index++);
    }
}

void    CreateLineAttribute__cout(
                SdaiInstance    instance,
                SdaiAttr        attribute
            )
{
    int_t   attrType = engiGetAttrType(attribute);
    if (attrType & engiTypeFlagAggr ||
        attrType & engiTypeFlagAggrOption)
        attrType = sdaiAGGR;

    switch (attrType) {
        case  sdaiADB:
            {
                SdaiADB    attributeDataBlock = 0;
                if (sdaiGetAttr(instance, attribute, sdaiADB, &attributeDataBlock)) {
                    assert(attributeDataBlock);
                    CreateLineADB__cout(attributeDataBlock);
                }
                else {
                    assert(false);
                    cout << "$";
                }
            }
            break;
        case  sdaiAGGR:
            {
                SdaiAggr        valueAggr = nullptr;
                SdaiInstance    valueInstance = 0;
                if (sdaiGetAttr(instance, attribute, sdaiAGGR, &valueAggr)) {
                    cout << "(";
                    CreateLineAggregation__cout(valueAggr);
                    cout << ")";
                }
                else if (sdaiGetAttr(instance, attribute, sdaiINSTANCE, &valueInstance)) {
                    CreateInstance__cout(valueInstance);
                }
                else {
                    cout << "$";
                }
            }
            break;
        case  sdaiINSTANCE:
            {
                SdaiInstance    value = 0;
                if (sdaiGetAttr(instance, attribute, sdaiINSTANCE, &value)) {
                    CreateInstance__cout(value);
                }
                else {
                    if (engiGetAttrDerived(sdaiGetInstanceType(instance), attribute)) {
                        cout << "*";
                    }
                    else {
                        cout << "$";
                    }
                }
            }
            break;
        case  sdaiBOOLEAN:
            {
                bool    value = false;
                if (sdaiGetAttr(instance, attribute, sdaiBOOLEAN, &value)) {
                    CreateBoolean__cout(value);
                }
                else {
                    cout << "$";
                }
            }
            break;
        case  sdaiLOGICAL:
            {
                char    * value = nullptr;
                if (sdaiGetAttr(instance, attribute, sdaiLOGICAL, &value)) {
                    CreateLogical__cout(value);
                }
                else {
                    cout << "$";
                }
            }
            break;
        case  sdaiENUM:
            {
                char    * value = nullptr;
                if (sdaiGetAttr(instance, attribute, sdaiENUM, &value)) {
                    CreateEnumeration__cout(value);
                }
                else {
                    cout << "$";
                }
            }
            break;
        case  sdaiREAL:
            {
                double  value = 0.;
                if (sdaiGetAttr(instance, attribute, sdaiREAL, &value)) {
                    CreateReal__cout(value);
                }
                else {
                    cout << "$";
                }
            }
            break;
        case  sdaiINTEGER:
            {
                int_t   value = 0;
                if (sdaiGetAttr(instance, attribute, sdaiINTEGER, &value)) {
                    CreateInteger__cout(value);
                }
                else {
                    cout << "$";
                }
            }
            break;
        case  sdaiSTRING:
            {
                char    * value = nullptr;
                if (sdaiGetAttr(instance, attribute, sdaiEXPRESSSTRING, &value)) {
                    CreateString__cout(value);
                }
                else {
                    cout << "$";
                }
            }
            break;
        default:
            assert(false);
            cout << "??";
            break;
    }
}

void    CreateLineInstance__cout(
                SdaiInstance    instance
            )
{
    //
    //  Create a generic line, similar to an IFC file in SPFF (STEP Phyical File Format)
    //
    char    * entityName = nullptr;
    engiGetEntityName(sdaiGetInstanceType(instance), sdaiSTRING, (const char**) &entityName);
    cout << "#" << internalGetP21Line(instance) << " = " << UpperCase__cout(entityName) << "(";

    bool    countedWithParents = true,
            countedWithInverse = false;

    SdaiEntity  entity = sdaiGetInstanceType(instance);
    SdaiInteger index = 0;
    SdaiAttr    attribute = engiGetEntityAttributeByIndex(
                                    entity,
                                    index++,
                                    countedWithParents,
                                    countedWithInverse
                                );
    CreateLineAttribute__cout(instance, attribute);
    while (attribute) {
        attribute = engiGetEntityAttributeByIndex(
                        entity,
                        index++,
                        countedWithParents,
                        countedWithInverse
                    );
        if (attribute) {
            cout << ", ";
            CreateLineAttribute__cout(instance, attribute);
        }
    }

    cout << ");\n";
}