sdaiPutAttrBN

valueType argument to specify what type of data caller wants to put Table 1 shows type of buffer the caller should provide depending on the valueType for sdaiPutAttrBN, and it works similarly for all put-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.

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

valueType               C/C++                                                       C#

sdaiINTEGER             int_t val = 123;                                            int_t val = 123;
                        sdaiPutAttrBN (inst, "attrName", sdaiINTEGER, &val);        ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiINTEGER, ref val);

sdaiREAL or sdaiNUMBER  double val = 123.456;                                       double val = 123.456;
                        sdaiPutAttrBN (inst, "attrName", sdaiREAL, &val);           ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiREAL, ref val);

sdaiBOOLEAN             bool val = true;                                            bool val = true;
                        sdaiPutAttrBN (inst, "attrName", sdaiBOOLEAN, &val);        ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiBOOLEAN, ref val);

sdaiLOGICAL             const TCHAR* val = "U";                                     string val = "U";
                        sdaiPutAttrBN (inst, "attrName", sdaiLOGICAL, val);         ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiLOGICAL, val);

sdaiENUM                const TCHAR* val = "NOTDEFINED";                            string val = "NOTDEFINED";
                        sdaiPutAttrBN (inst, "attrName", sdaiENUM, val);            ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiENUM, val);

sdaiBINARY              const TCHAR* val = "0123456ABC";                            string val = "0123456ABC";
                        sdaiPutAttrBN (inst, "attrName", sdaiBINARY, val);          ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiBINARY, val);

sdaiSTRING              const char* val = "My Simple String";                       string val = "My Simple String";
                        sdaiPutAttrBN (inst, "attrName", sdaiSTRING, val);          ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiSTRING, val);

sdaiUNICODE             const wchar_t* val = L"Any Unicode String";                 string val = "Any Unicode String";
                        sdaiPutAttrBN (inst, "attrName", sdaiUNICODE, val);         ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiSTRING, val);

sdaiEXPRESSSTRING       const char* val = "EXPRESS format, i.e. \\X2\\00FC\\X0\\";  string val = "EXPRESS format, i.e. \\X2\\00FC\\X0\\";
                        sdaiPutAttrBN (inst, "attrName", sdaiEXPRESSSTRING, val);   ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiEXPRESSSTRING, val);

sdaiINSTANCE            SdaiInstance val = sdaiCreateInstanceBN (model, "IFCSITE"); int_t val = ifcengine.sdaiCreateInstanceBN (model, "IFCSITE");
                        sdaiPutAttrBN (inst, "attrName", sdaiINSTANCE, val);        ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiINSTANCE, val);

sdaiAGGR                SdaiAggr val = sdaiCreateAggr (inst, 0);                    int_t val = sdaiCreateAggr (inst, 0);
                        sdaiAppend (val, sdaiINSTANCE, inst);                       ifcengine.sdaiAppend (val, ifcengine.sdaiINSTANCE, inst);
                        sdaiPutAttrBN (inst, "attrName", sdaiAGGR, val);            ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiAGGR, val);

sdaiADB                 int_t integerValue = 123;                                   int_t integerValue = 123;   
                        SdaiADB val = sdaiCreateADB (sdaiINTEGER, &integerValue);   int_t val = ifcengine.sdaiCreateADB (ifcengine.sdaiINTEGER, ref integerValue);
                        sdaiPutADBTypePath (val, 1, "IFCINTEGER");                  ifcengine.sdaiPutADBTypePath (val, 1, "IFCINTEGER");
                        sdaiPutAttrBN (inst, "attrName", sdaiADB, val);             ifcengine.sdaiPutAttrBN (inst, "attrName", ifcengine.sdaiADB, val); 
                        sdaiDeleteADB (val);                                        ifcengine.sdaiDeleteADB (val);
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          .           .           .           .           .           .           .           .           .
sdaiREAL             .          Yes          .           .           .           .           .           .           .           .
sdaiNUMBER           .          Yes          .           .           .           .           .           .           .           .
sdaiBOOLEAN          .           .          Yes          .           .           .           .           .           .           .
sdaiLOGICAL          .           .          Yes         Yes          .           .           .           .           .           .
sdaiENUM             .           .          Yes         Yes         Yes          .           .           .           .           .
sdaiBINARY           .           .           .           .           .          Yes          .           .           .           .
sdaiSTRING           .           .           .           .           .           .          Yes          .           .           .
sdaiUNICODE          .           .           .           .           .           .          Yes          .           .           .
sdaiEXPRESSSTRING    .           .           .           .           .           .          Yes          .           .           .
sdaiINSTANCE         .           .           .           .           .           .           .          Yes          .           .
sdaiAGGR             .           .           .           .           .           .           .           .          Yes          .
sdaiADB             Yes         Yes         Yes         Yes         Yes         Yes         Yes         Yes         Yes          .
Technically sdaiPutAttrBN will transform into the following call
    sdaiPutAttr(
            instance,
            sdaiGetAttrDefinition(
                    sdaiGetInstanceType(
                            instance
                        ),
                    attributeName
                ),
            valueType,
            value
        );

Syntax

//
//   Strong typing definition
//
void            sdaiPutAttrBN(
                        SdaiInstance            instance,
                        const char              * attributeName,
                        SdaiPrimitiveType       valueType,
                        const void              * value
                    );

static  inline  void    sdaiPutAttrBN(
                                SdaiInstance            instance,
                                char                    * attributeName,
                                SdaiPrimitiveType       valueType,
                                const void              * value
                            )
{
    return  sdaiPutAttrBN(
                    instance,
                    (const char*) attributeName,
                    valueType,
                    value
                );
}

static  inline  void    sdaiPutAttrBN(
                                SdaiInstance            instance,
                                const char              * attributeName,
                                SdaiPrimitiveType       valueType,
                                SdaiInstance            value
                            )
{
    return  sdaiPutAttrBN(
                    instance,
                    attributeName,
                    valueType,
                    (const void*) value
                );
}


//
//   Weak typing definition
//
void    __declspec(dllexport) __stdcall sdaiPutAttrBN(
                                                int_t                   instance,
                                                const char              * attributeName,
                                                int_t                   valueType,
                                                const void              * value
                                            );

static  inline  void    sdaiPutAttrBN(
                                int_t                   instance,
                                char                    * attributeName,
                                int_t                   valueType,
                                const void              * value
                            )
{
    return  sdaiPutAttrBN(
                    instance,
                    (const char*) attributeName,
                    valueType,
                    value
                );
}

static  inline  void    sdaiPutAttrBN(
                                int_t                   instance,
                                const char              * attributeName,
                                int_t                   valueType,
                                int_t                   value
                            )
{
    return  sdaiPutAttrBN(
                    instance,
                    attributeName,
                    valueType,
                    (const void*) value
                );
}
    

Property instance

Size: 32 bit / 4 byte (value)
...

Property attributeName

Size: 32 bit / 4 byte (reference)
...

Property valueType

Size: 32 bit / 4 byte (value)
...

Property value

Size: 32 bit / 4 byte (reference)
...

Example (based on pure API calls)

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

#include    "./include/ifcengine.h"
//
//  Created result when stored as IFC:
//  #31313 = IFCPOSTALADDRESS($, $, $, $, ('RDF Ltd.', 'Main Office'), '32', 'Bankya', 'Sofia', '1320', 'Bulgaria');
//
int_t   ifcPostalAddressInstance = sdaiCreateInstanceBN(model, "IFCPOSTALADDRESS");

int_t   * addressLines = sdaiCreateAggrBN(ifcPostalAddressInstance, "AddressLines");
sdaiAppend((int64_t) addressLines, sdaiSTRING, "RDF Ltd.");
sdaiAppend((int64_t) addressLines, sdaiSTRING, "Main Office");

sdaiPutAttrBN(ifcPostalAddressInstance, "PostalBox", sdaiSTRING, "32");
sdaiPutAttrBN(ifcPostalAddressInstance, "Town", sdaiSTRING, "Bankya");
sdaiPutAttrBN(ifcPostalAddressInstance, "Region", sdaiSTRING, "Sofia");         //  It is allowed to mix sdaiUNICODE and sdaiSTRING
sdaiPutAttrBN(ifcPostalAddressInstance, "PostalCode", sdaiUNICODE, L"1320");    //  as long as each call is consitent in itself.
sdaiPutAttrBN(ifcPostalAddressInstance, "Country", sdaiSTRING, "Bulgaria");