g Library Functions
Book Contents | Book Index |
Search STEP Tools Web Support

Overview

Some features of the ROSE library are provided as members of C++ classes, but many are provided as ordinary functions. These functions are documented below.

rose_basename()

char * rose_basename(
	const char * fname
	);

The rose_basename() function replicates the UNIX basename shell command. This function will strip any leading directories from a path, returning just the filename, without any extensions.

The function returns a pointer to a static character buffer. This buffer may be overwritten on subsequent calls to the function.

rose_clear_select()

void rose_clear_select(
	RoseUnion * sel
	);

The rose_clear_select() function unsets the value of a SELECT type. In addition to setting the value and the attribute of the RoseUnion to NULL, this function also moves any intermediate RoseUnion objects to the trashcan design.

See Also

rose_create_select(); rose_get_nested_object()

rose_compute_backptrs()

void rose_compute_backptrs(
	RoseDesign * des
	);

The rose_compute_backptrs() function traverses a design and builds a table of all the backpointers. This must be done before any of the backpointer operations are performed, or if the instance data changes.

See Also

Backpointers; RoseBackptrs; RoseBackptrCursor; rose_get_backptrs(); rose_release_backptrs()

rose_compute_refcount()

void rose_compute_refcount(
	RoseDesign * des
	);

The rose_compute_refcount() function computes the reference counts for all instances in a design. This should be done before calling any of the reference count functions, or if the instance data changes.

See Also

Reference Counting; rose_release_refcount(); rose_refcount()

rose_create_select()

RoseUnion * rose_create_select(
	RoseDomain * sel_type,
	RoseObject * obj
	);

The rose_create_select() function creates an instance of a RoseUnion which contains the specified object as its value. The sel_type parameter identifies the type of the RoseUnion that is created and returned. This function will, if necessary, create a nested sequence of RoseUnion objects.

If the object of the indicated type cannot be placed in the indicated select type, this function returns NULL.

See Also

rose_put_nested_object()

rose_dir_exists()

int rose_dir_exists(
	char * dir_name
	);

The rose_dir_exists() function tests whether a directory with a given name exists on secondary storage. The "fname" string should be a UTF-8 directory path. On UNIX machines, this will call the POSIX stat() function. On Windows, the function will convert the UTF-8 path to wide characters and call _wstat().

rose_dirname()

char * rose_dirname(
	const char * fname
	);

The rose_dirname() function replicates the UNIX dirname shell command. This function strips the filename from a path, returning just the directory. If the path does not have a directory component, the function returns null.

The function returns a pointer to a static character buffer. The buffer may be overwritten on subsequent calls to the function.

rose_domain_name_cmp()

int rose_domain_name_cmp(
	const void * a, 
	const void * b
	);

The rose_domain_name_cmp() function is used with qsort() to sort an array of RoseDomain pointers into the ordering used by the list of types in the STEP Part 21 external mapping.

This orders using an uppercase version of the domain name, which results in the correct collating sequence when underscores appear in the names.

rose_empty_trash()

void rose_empty_trash();

The rose_empty_trash() function traverses every persistent object in memory, nulling out pointers to non-persistent objects or objects in the trashcan design. Then it will reclaim memory by deleting the contents of the trashcan design. Persistent objects can be moved it to the trashcan with the rose_move_to_trash() function.

Example

    Point * p_pnt = pnew Point;

    rose_move_to_trash (p_pnt);    /* moves from design to trash */
    rose_empty_trash();            /* clears bad pointers, deletes obj */

See Also

Deleting Objects; rose_move_to_trash(); rose_trash()

rose_expand_substitutes()

RoseObject * rose_expand_substitutes(
	RoseObject * obj
	);

The rose_expand_substitutes() function takes a pointer to an object and either returns the same pointer, or a pointer to a substitute object if one has been registered using either the rose_register_substitute() or rose_mutate() functions.

Example

    RoseObject * obj;

    obj = rose_expand_substitutes (obj);
    /* now we are sure to have the most up-to-date pointer if 
     * there was some substitution or mutation going on
     */

See Also

rose_register_substitute(); rose_mutate()

rose_extname()

char * rose_extname(
	const char * fname
	);

The rose_extname() function returns the filename extension, without the dot (".") separator. If the string does not contain an extension, the function returns null. The function returns a pointer to a static character buffer. The buffer may be overwritten on subsequent calls to the function.

rose_file_exists()

int rose_file_exists(
	const char * fname
	);

The rose_file_exists() function returns a boolean value indicating if a file with the given name exists on secondary storage. The "fname" string should be a UTF-8 file path. On UNIX machines, this will call the POSIX access() function. On Windows, the function will convert the UTF-8 filename to wide characters and call _waccess().

rose_file_readable()

int rose_file_readable(
	const char * fname
	);

The rose_file_readable() function tests the permissions of a given file, and returns a boolean value indicating whether the file can be read.

rose_file_remove()

void rose_file_remove(
	const char * fname
	);

The rose_file_remove() function removes a file from secondary storage. The "fname" string should be a UTF-8 file path. On UNIX machines, this will call the POSIX remove() function or unlink() as needed. On Windows, the function will convert the UTF-8 filename to wide characters and call _wremove().

rose_file_rename()

void rose_file_rename(
	const char * orig_fname,
	const char * new_fname
	);

The rose_file_rename() function renames a file on secondary storage. The old and new "fname" strings should be UTF-8 file paths. On UNIX machines, this will call the POSIX rename() function or link() as needed. On Windows, the function will convert the UTF-8 filename to wide characters and call _wrename().

rose_file_writable()

int rose_file_writable(
	const char * fname
	);

The rose_file_writable() function tests the permissions of a given file, and returns a boolean value indicating whether the file can be overwritten.

rose_get_backptrs()

RoseBackptrs * rose_get_backptrs(
	RoseObject * obj
	);

The rose_get_backptrs() function returns a handle to the computed backpointers for a given object. Call the rose_compute_backptrs() first to establish the lists of backpointers. If rose_get_backptrs() is called without previously computing the backpointers, the function will return an empty RoseBackptrs object.

See Also

Backpointers; RoseBackptrs; RoseBackptrCursor; rose_compute_backptrs(); rose_release_backptrs()

rose_get_nested_object()

RoseObject * rose_get_nested_object(
	RoseUnion * sel,
	RoseDomain * filter = NULL
	);

The rose_get_nested_object() function returns the entity instance that is the value of a select type. This function is a useful shortcut eliminates many "if-then" tests

This function searchs the (possibly nested) RoseUnion until it returns underlying entity instance. If the optional filter parameter is given, the value returned will be limited to the specified type (or a subtype). If the select contains a different type of object, the function will return null.

Example

The situation below is common in STEP application protocols, where a nested select models the types of objects that something can refer to. Using the get function makes looking for a specific kind of value very simple.

    // The definition of a property is a characterized_definition 
    // select, which could contain:
    //   characterized_object,
    //   characterized_product_definition (nested select)
    //       product_definition,
    //       product_definition_relationship
    //   product_definition_shape
    //   shape_aspect, 
    //   shape_aspect_relationship

    property_definition * prop

    // We only care about values that are product_definitions
    RoseObject * def = rose_get_nested_object (
         prop->definition(),
         ROSE_DOMAIN(product_definition)
         );

    product_definition * pd = ROSE_CAST (product_definition, def);

See Also

rose_put_nested_object()

rose_get_ref()

RoseReference * rose_get_ref(
	RoseObject *	obj,
	RoseAttribute * att,
	unsigned 	idx = 0
	);

RoseReference * rose_get_ref(
	RoseObject *	obj,
	const char * 	attname
	);

RoseReference * rose_get_ref(
	RoseAggregate *	obj,
	unsigned 	idx
	);

RoseReference * rose_get_ref(
	RoseUnion *	obj
	);

The rose_get_ref() function tests whether a field of an object contains an external reference. Several versions of the function are provided for use with entities, selects, and aggregates. Testing entities needs an attribute, aggregates needs an index, and selects do not need any additional information.

If the field contains an external reference, the function will return the RoseReference object that contains the URI of the reference. Typically an application might check for an unresolved reference if a field is null, but the function works regardless of whether the reference has been resolved.

Example

stp_product_definition_formation * pdf;
stp_product * p = pdf-> of_product();

if (!p) {
    RoseReference * ref = rose_get_ref (pdf,"of_product");
    printf ("product is reference to %s\n", ref->uri());
}

See Also

References Between Data Sets; RoseReference; rose_make_ref(); rose_put_ref();

rose_get/put_schema_property()

char * rose_get_schema_property(
	RoseDesign * d,
	const char * keyword
	);

void rose_put_schema_property (
	RoseDesign * d, 
	const char * keyword, 
	const char * value);

The get/put schema property functions are used to manage string properties stored by the compiled ROSE data-dictionary files. Application code is unlikely to use the put function since data dictionary files are part of ST-Runtime. The get function may be useful for getting Part 28 namespace information from a schema.

rose_getenv/setenv integrated_schema_path()

char * rose_getenv_integrated_schema_path();

void rose_setenv_integrated_schema_path(
	const char * dir
	);

The rose_getenv_integrated_schema_path() function returns the location of the configuration file and integrated schemas described in Integrated Schemas and AP Contexts.

The rose_setenv_integrated_schema_path() function can be used to set the location. The value should be a single directory containing the configuration file and integrated schemas. If the function is passed a null pointer, the default value will be used. This function must be called before rose_use_ap_interoperability() for the changes to take effect.

If the setenv function is not used, the path will be taken from the environment or registry. The getenv function will look for a path in the $ROSE_AP_PATH environment variable or "ROSE_AP_PATH" registry value.

On Windows, the registry will be searched before environment variables. The location in the registry for all ROSE library settings is controlled by rose_getenv/setenv registry_key().

See Also

Integrated Schemas and AP Contexts; rose_use_ap_interoperability()

rose_getenv/setenv registry_key()

char * rose_getenv_registry_key();

void rose_setenv_registry_key(
	const char * dir
	);

The rose_getenv_registry_key() function returns the location in the Windows registry where configuration information is kept. This function is present, but has no effect, on UNIX platforms. By default, this location is:

    SOFTWARE\STEP Tools, Inc.\ST-Developer\<version>

The rose_setenv_registry_key() function can be used to set the location. Which may be useful for Windows applications built using ST-Developer that wish to keep external configuration settings in a different place. For debug and test purposes, the location can also be set externally using the $ROSE_REGKEY environment variable.

rose_getenv/setenv search_path()

char * rose_getenv_search_path();

void rose_setenv_search_path(
	const char * dir
	);

The rose_getenv_search_path() function returns the initial value of the database search path. The database search path is a list of directories used by the RoseInterface::findDesign() operation. The directories in the path are separated by the character appropriate for the platform (colons on UNIX, semicolons on Windows, and commas on VMS). See Database Search Paths for a more information on the use of the search path.

The rose_setenv_search_path() function specifies the initial value of the database search path. When the library is initialized, this path is concatenated with the system schema path and copied into the RoseInterface object. These paths are used to find data files and compiled schema files during initialization.

After the library is initialized, the RoseInterface::usePath() function can be used to change the path. The setenv function is only used to specify the initial search path. The library is initialized by the creation of the first persistent object or the first call to the RoseInterface object.

If setenv function is not used, the path will be taken from the environment or registry. The getenv function will look for a path in the $ROSE_DB environment variable or "ROSE_DB" registry value.

On Windows, the registry will be searched before environment variables. The location in the registry for all ROSE library settings is controlled by rose_getenv/setenv registry_key().

If a value is not found in the environment or Windows registry, a default path consisting of the current directory and a "./schemas" subdirectory is used. If the function is called with a null pointer, the default value will be used. To force an empty path, set the value to a zero-length string.

Example

If an application wanted to take the search path from a variable called $NEW_PATH, it could do so by putting the following code at the beginning of main(), before any database operations are performed:

    main () {
        [ ... application init code ... ]
        rose_setenv_search_path (getenv ("NEW_PATH"));

        [ ... start reading files, creating objects, etc ... ]
    }

In the previous example, the application would still look for the system_db directory under the ST-Developer installation to find system support files, such as the schema for Part 21 header section instances. We can make the library look elsewhere for these support files.

    main () {
        [ ... application init code ... ]
        rose_setenv_search_path (getenv ("NEW_PATH"));
        rose_setenv_system_schema_path ("/usr/local/myapp/schemas");

        [ ... start reading files, creating objects, etc ... ]
    }

If these support files will always be in the normal database path, we could also disable the search for this extra directory.

    main () {
        [ ... application init code ... ]
        rose_setenv_search_path (getenv ("NEW_PATH"));
        rose_setenv_system_schema_path ("");   /* disabled */

        [ ... start reading files, creating objects, etc ... ]
    }

See Also

Packaging Applications for Distribution; Database Search Paths; rose_getenv/setenv system_schema_path()

rose_getenv/setenv_system_schema_path()

char * rose_getenv_system_schema_path();

void rose_setenv_system_schema_path(
	const char * dir
	);

The rose_getenv_system_schema_path() function returns the system schema path. This is an extra search path that is appended to the normal database search path at library initialization to make sure that the system support files are always found.

The rose_setenv_system_schema_path() function specifies the system schema path. The path can contain many directories separated by the character appropriate for the platform (colons on UNIX, semicolons on Windows, and commas on VMS). If the function is called with a null pointer, the default value will be used. To force an empty path, set the value to a zero-length string.

This path should refer to directories containing compiled schemas and auxillary files required by the ST-Developer applications. These files are normally found in the system_db/schemas directory under the ST-Developer installation.

If the setenv function is not used, the path will be taken from the environment or registry. On Windows, the registry will be searched before environment variables. The location in the registry for all ROSE library settings is controlled by rose_getenv/setenv registry_key().

First the getenv function will look for a path in the $ROSE_SYSTEM_DB environment variable or "ROSE_SYSTEM_DB" registry value. If a value is not found, the path will default to the system_db/schemas directory in the ST-Developer installation. The installation directory is found by looking for the $ROSE environment variable or "ROSE" registry value.

See Also

Packaging Applications for Distribution; Database Search Paths; rose_getenv/setenv search_path()

rose_hash_insensitive()

unsigned rose_hash_insensitive(
	const char * str
	);

The rose_hash_insensitive() function is used internally by the ROSE library. It generates a 32bit hash value from a string which treats the 7bit characters A-Z and a-z as the same values. The function ignores the locale setting and uses all other character values verbatim. This function must be given a valid pointer.

rose_is_marked()

int rose_is_marked(
	RoseObject * obj, 
	RoseMark m = ROSE_MARK_CURRENT
	);

The rose_is_marked() function tests whether an object has been given a mark by rose_mark_set(). To remove a mark from an object, use rose_mark_clear().

The function takes an optional mark handle previously returned by rose_mark_begin(). If one is not given, the function uses rose_mark_current(). The function returns zero if no handle is active.

See Also

Marking Objects During Traversal; rose_mark_begin(); rose_mark_clear(); rose_mark_current(); rose_mark_end(); rose_mark_set()

rose_is_system_schema()

int rose_is_system_schema(
	RoseDesign * d
	);

The rose_is_system_schema() function returns true if a RoseDesign object is a schemas that are used internally by the ROSE library. This allows an application to distinguish between system schemas that used by the ROSE library and schemas that represent an application protocol or other public schema. This is useful when deciding which schemas to write in the header of a STEP file.

rose_iso_timestamp()

char * rose_iso_timestamp();

The rose_iso_timestamp() function returns the current time as a character string in the ISO format required by the Part 21 header file_name.time_stamp field. For example, the string "1995-05-18T14:18:59-04:00" indicates May 18, 1995 at 2:18pm, 4 hours behind UTC. The function returns a pointer to a static character buffer which may be overwritten by subsequent calls to the function.

rose_logwin_init()

#include <rose_logwin.h>

int rose_logwin_init();

The rose_logwin_init() function registers the ST-Developer Message Window with the ROSE library so that all Part 21 syntax errors, warnings, or other status messages will be sent to a separate message window. This package is only available on Windows.

Include rose_logwin.h, call this function near the start of your application, and link against the rose_logwin.lib library. The roselog DLL must be in your path for the log window to appear. If the DLL is found, rose_logwin_init() will return non-zero. If it is not found, the function will return zero and the default error handling used.

Calling rose_logwin_wait() at the end of your program will block until the user dismisses the message box. This gives the user a chance to view the messages, particularly in short-lived programs.

Example

The following example shows how to initialize the message window

    #include <rose.h>
    #include <rose_logwin.h>

    int main (int argc, char ** argv) 
    {
        rose_logwin_init();
        /* your code */
        rose_logwin_wait();
    }

See Also

ST-Developer Message Window; rose_logwin_wait()

rose_logwin_wait()

void rose_logwin_wait();

The rose_logwin_wait() function does not return until the ST-Developer Message Window has been dismissed. Calling this function at the end of your program gives the user a chance to view the messages, particularly in short-lived programs.

See Also

ST-Developer Message Window; rose_logwin_init()

rose_make_ref()

RoseReference * rose_make_ref(
	RoseDesign *	design,
	const char *	uri
	);

The rose_make_ref() function creates a new RoseReference instance with the given URL. The object is greated in the RoseDesignSection reserved for references.

See Also

References Between Data Sets; RoseReference rose_put_ref();

rose_mark_begin()

typedef unsigned RoseMark;
#define ROSE_MARK_CURRENT ((RoseMark) 0)

RoseMark rose_mark_begin();

The rose_mark_begin() function initializes an object marker for use in traversals. The function returns a handle identifying a marker. You can use this handle to alternate between several marks, but most usage will be strictly nested, so you can omit the handle in the function calls and the most recent one will be used. The macro ROSE_MARK_CURRENT also refers to most recently opened mark.

When a new marker is started, no data objects will be marked. Call rose_mark_set() to add a mark, rose_is_marked() to test for a mark, and rose_mark_clear() to remove a previously placed mark.

When the marking algorithm is finished, call rose_mark_end() to release the mark. To help detect code that fails to release marks, the library will warn when more than a certain number of marks are concurrently opened. You can control when warnings occur using the rose_mark_warning_at() function.

Previous versions of the ROSE class library provided one non-nested mark managed with the RoseInterface::beginTraversal(), RoseInterface::endTraversal(), RoseObject::visit(), and RoseObject::wasVisited() functions. These are still present, but alias the more general rose_mark_xxx functions.

Example

The following example shows a simple traversal which takes a list that may contain duplicates. The code marks each object as it works to make sure that no object is processed twice.

ListOfRoseObject * objs;

rose_begin_mark();
for (unsigned i=0; i<objs->size(); i++)
{
    RoseObject * obj = objs->get(i);
    if (!rose_is_marked(obj))
    {
	rose_mark_set(obj);
	/* do other things */
    }
}
rose_mark_end();

The following example shows a traversal that uses multiple marks to categorize some objects.

unsigned i;
ListOfRoseObject * objs;

RoseMark red = rose_mark_begin();
RoseMark green = rose_mark_begin();
RoseMark blue = rose_mark_begin();

// Apply several different marks based on various conditions

for (i=0; i<objs->size(); i++)
{
    RoseObject * obj = objs->get(i);
    if (/* obj is red */)    rose_mark_set(obj, red);
    if (/* obj is green */)  rose_mark_set(obj, green);
    if (/* obj is blue */)   rose_mark_set(obj, blue);
}

// Do something based on what marks an object has
for (i=0; i<objs->size(); i++)
{
    RoseObject * obj = objs->get(i);
    if (rose_is_marked(obj, red) &&
        rose_is_marked(obj, green) &&
        rose_is_marked(obj, blue))
    {
	// object is marked by all three
    }
}

rose_mark_end(red);
rose_mark_end(green);
rose_mark_end(blue);

See Also

Marking Objects During Traversal; rose_is_marked(); rose_mark_current(); rose_mark_end(); rose_mark_set()

rose_mark_clear()

void rose_mark_clear(
	RoseObject * obj, 
	RoseMark m = ROSE_MARK_CURRENT
	);

The rose_mark_clear() function removes a mark from an object. The function takes an optional mark handle previously returned by rose_mark_begin(). If not given, the function uses rose_mark_current().

To bulk unmark all objects, just end the previous mark with rose_mark_end() and begin a new one with rose_mark_begin(). Closing the old mark and opening a new one is a constant time operation.

See Also

Marking Objects During Traversal; rose_is_marked(); rose_mark_set()

rose_mark_clear_all()

void rose_mark_clear_all(	
	RoseDesign * design, 
	RoseMark m = ROSE_MARK_CURRENT
	);

void rose_mark_clear_all(
	RoseMark m = ROSE_MARK_CURRENT
	);

These "clear all" functions are used for internal cleanup and examine every object in a design or in memory.

If you just want to make sure all objects are not marked, just end the previous mark with rose_mark_end() and begin a new one with rose_mark_begin(). Closing the old mark and opening a new one is a constant time operation.

rose_mark_current()

RoseMark rose_mark_current();

The rose_mark_current() function returns the handle of the mark returned by the most recent rose_mark_begin(). The library maintains a stack of marks, so nested traversals work as expected. When a mark is released by rose_mark_end(), the current mark reverts to the next most recently begun one. The function returns zero if no traversal mark is active.

See Also

Marking Objects During Traversal; rose_mark_begin(); rose_mark_set()

rose_mark_end()

void rose_mark_end(
	RoseMark m = ROSE_MARK_CURRENT
	);

The rose_mark_end() function releases a mark handle when a traversal algorithm is finished. The function takes an optional mark handle previously returned by rose_mark_begin(). If not given, the function uses rose_mark_current().

Releasing the rose_mark_current() handle will set the current to the next most recent active handle.

See Also

Marking Objects During Traversal; rose_mark_begin()

rose_mark_set()

void rose_mark_set(
	RoseObject * obj, 
	RoseMark m = ROSE_MARK_CURRENT
	);

The rose_mark_set() function adds a mark to an object. The function takes an optional mark handle previously returned by rose_mark_begin(). If not given, the function uses rose_mark_current().

See Also

Marking Objects During Traversal; rose_is_marked(); rose_mark_clear()

rose_mark_warning_at()

void rose_mark_warning_at(
	unsigned max_concurrent
	);

The rose_mark_warning_at() function sets the point at which the library will warn about nested calls to rose_mark_begin(), which is done to help detect code that fails to release marks. By default, the library will warn when marks are nested more then ten deep.

rose_move_to_design()

void rose_move_to_design(
	RoseObject * obj, 
	RoseDesign * design,
	);

The rose_move_to_design() function moves an object to another RoseDesign. The object is moved to the default section in the new design. This function is called by RoseObject::move() to move individual objects, but does not perform a recursive move.

The function also has an unused third argument, a RoseDomain pointer that defaults to zero. This third argument is for internal use only.

Example

    Point * pt;
    RoseObject * design_1;
    RoseObject * design_2;

    pt = pnewIn (design_1) Point;         /* create in design 1 */
    rose_move_to_design (pt, design_2);   /* move to design 2 */

    pt = new Point;                       /* create non persistent obj */
    rose_move_to_design (pt, design_2);   /* move into a design */

See Also

Moving and Copying Objects; rose_move_to_section(); RoseObject::move()

rose_move_to_section()

void rose_move_to_section(
	RoseObject * obj, 
	RoseDesignSection * section,
	);

The rose_move_to_section() function moves an object to a RoseDesignSection in another design. The function actually has a third argument, a RoseDomain pointer that defaults to zero. This third argument is for internal use only.

Example

    Point * pt;
    RoseObject * design_1;
    RoseObject * design_2;

    pt = pnewIn (design_1) Point;       /* create in design 1 */

    /* both to move to the default section in design 2 */
    rose_move_to_design (pt, design_2);
    rose_move_to_section (pt, design_2->dflt_section());

See Also

Moving and Copying Objects; Design Sections;

rose_move_to_trash()

void rose_move_to_trash(
	RoseObject * obj
	);

void rose_move_to_trash(
	RoseDesign * design
	);

The rose_move_to_trash() function moves a persistent object to the trashcan design. The trashcan design contains objects scheduled for deletion. When the trash is emptied, all persistent objects in memory are examined and any pointers to objects in the trash are reset to null. Once all pointers have been corrected, the objects are deleted.

When called on a RoseDesign, this function schedules the entire design for deletion. When emptying the trash, any pointers to objects in the trashed design will be set to null. The RoseDesign::isTrashed() function can be used to determine whether a design has been scheduled for deletion.

Example

    Point * pt = pnew Point;
    RoseDesign * design;

    rose_move_to_trash (pt);      /* mark object for deletion */
    rose_move_to_trash (design);  /* mark entire design for deletion */
    rose_empty_trash();

See Also

Creating and Deleting Design Objects; Deleting Objects; rose_empty_trash(); rose_trash()

rose_mutate()

RoseObject * rose_mutate(
	RoseObject * orig, 
	RoseDomain * new_domain
	);

The rose_mutate() function creates a new object with the same attribute values of the old. Attributes are matched by name. The original object is moved to the trash and a substitution is registered from the old to the new object. The entity_id() and entity_comment(), oid(), and wasVisited() state of the object are preserved, but any user-defined RoseManagers that an application may have added are not.

References to the old object will only be updated when the trash is emptied or rose_update_object_references() is called on the design. An application can convert a particular pointer with the rose_expand_substitutes() functions.

Example

    /* creates copy of orig, moves to trash */
    rose_mutate (orig, new_dom);

    /* these updates references to orig */
    RoseObject * oldref;
    RoseObject * newref;

    newref = rose_expand_substitutes(oldref);  /* one pointer */
    rose_update_object_references (design);    /* one design */
    rose_empty_trash();                        /* all designs */

See Also

rose_register_substitute(); rose_expand_substitutes(); rose_update_object_references(); RoseObject::copy()

rose_p21_dflt_add_schema()

RoseStatus rose_p21_dflt_add_schema(
	RoseDesign * design, 
	const char * name
	);

The rose_p21_dflt_add_schema() function is a predefined hook function used with RoseP21Parser::add_schema_fn to process each schema name in the header of a Part 21 file. This function reads the compiled data dictionary file for a schema using rose_p21_find_schema() and adds it to the design using addSchema().

Example

Use this function to handle schemas by putting the following somewhere in your main, before you start reading files.

    // This function is the default if no hook specified
    RoseP21Parser::set_schemas_fn = 0;  
    RoseP21Parser::add_schema_fn = 0;  

See Also

Customized Schema Handling; rose_p21_find_schema(); RoseDesign::addSchema()

rose_p21_dflt_read_comment()

void rose_p21_dflt_read_comment(
	RoseP21Lex * lex
	);

The rose_p21_dflt_read_comment() function an alias for rose_p21_read_and_discard_comment().

rose_p21_dflt_renumber()

RoseStatus rose_p21_dflt_renumber(
	RoseDesign * design
	);

The rose_p21_dflt_renumber() function is a predefined hook function used with RoseP21Writer::renumber_fnto renumber the entity instances in a Part 21 file before it is written.

This function provides all of the default renumbering behavior controlled by the RoseP21Writer::preserve_eids, RoseP21Writer::sort_eids, and RoseP21Writer::renumber_density variables. If you replace this with your own hook function, these variables will no longer have any effect.

Example

Use this function to renumber by putting the following somewhere in your main, before you start reading files.

    RoseP21Writer::renumber_fn = rose_p21_dflt_renumber;

    // This function is also the default if no hook specified
    RoseP21Writer::renumber_fn = 0;  

See Also

Entity ID Numbering; RoseObject::entity_id()

rose_p21_dflt_schema_name()

char * rose_p21_dflt_schema_name(
	RoseDesign * design,
	RoseDesign * schema 
	);

The rose_p21_dflt_schema_name() function is a predefined hook function used with RoseP21Writer::schema_name_fn to provide the schema name that should appear in the header of a Part 21 file.

The function is passed two arguments, a pointer to the design being written, and a pointer to the schema (which is also a design). This function reads the name of the schema design.

Example

Use this function to handle schemas by putting the following somewhere in your main, before you start reading files.

    RoseP21Writer::schema_name_fn = rose_p21_dflt_schema_name;

    // This function is also the default if no hook specified
    RoseP21Writer::schema_name_fn = 0;  

See Also

Customized Schema Handling; RoseDesign::name()

rose_p21_find_schema()

RoseDesign * rose_p21_find_schema(
	const char * schema_name
	);

The rose_p21_find_schema() function searches for a rose compiled schema given a schema identifier from the header of a Part 21 file. The schema name in the header is usually uppercase and may have additional ASN/1 identifiers (the numbers in braces "{1 10303 203 1 2 3}"), so the function may have to do some processing name remapping before calling ROSE.findDesign() to read the design.

This function is primarily used within functions, such as rose_p21_add_schema(), that are provided to the RoseP21Parser::add_schema_fn hook.

See Also

Customized Schema Handling; rose_p21_dflt_add_schema(); RoseInterface::findDesign()

rose_p21_read_and_discard_comment()

void rose_p21_read_and_discard_comment(
	RoseP21Lex * lex
	);

The rose_p21_read_and_discard_comment() function is a predefined hook functions that can be assigned to RoseP21Lex::comment_fn to scan comments in a Part 21 file.

As described in Reading and Writing Comments a hook function is called when the Part 21 lexer encounters a comment. This function processes the comment and discards the contents.

Example

Use this function to handle comments by putting the following somewhere in your main, before you start reading files.

    RoseP21Lex::comment_fn = rose_p21_read_and_discard_comment;

    // This function is also the default if no hook specified
    RoseP21Lex::comment_fn = 0;  

See Also

Reading and Writing Comments; rose_p21_read_and_preserve_comment();

rose_p21_read_and_preserve_comment()

void rose_p21_read_and_preserve_comment(
	RoseP21Lex * lex
	);

The rose_p21_read_and_preserve_comment() function is a predefined hook functions that can be assigned to RoseP21Lex::comment_fn to scan comments in a Part 21 file.

As described in Reading and Writing Comments a hook function is called when the Part 21 lexer encounters a comment. This function captures the comment and associates it with the nearest object so that it is available via the RoseObject::entity_comment() function.

Example

Use this function to handle comments by putting the following somewhere in your main, before you start reading files.

    RoseP21Lex::comment_fn = rose_p21_read_and_preserve_comment;

See Also

Reading and Writing Comments; rose_p21_read_and_discard_comment(); RoseObject::entity_comment().

rose_p28_init()

#include <rose_p28.h>

void rose_p28_init();

The rose_p28_init() function registers the XML file handler so that applications can read and write STEP Part 28 Edition 2 XML exchange files (ISO 10303-28:2007). You must include the rose_p28.h file and link against the p28e2 library as well.

Once rose_p28_init() is called, your application will recognize STEP Part 28 XML files when reading. By default, new files are written as Part 21 but you can switch to Part 28 XML by calling RoseDesign::format() with "p28" or p28-raw" strings.

See Also

STEP Part 28 XML Files; RoseDesign::format()

rose_put_nested_object()

RoseBoolean rose_put_nested_object(
	RoseUnion * sel,
	RoseObject * obj
	);

The rose_put_nested_object() function places an entity instance into a select type. If necessary, intermediate RoseUnion objects are created and populated. If the RoseUnion specified by sel parameter already contains a value, this function will resuse as many of the intermediate selects as possiblle, and move any others to the trash for future deletion.

If the top-level select instance does not yet exist, the rose_create_select() function can create and set it in one step or you can create it by other means.

The function returns ROSE_TRUE if it was able to place the value in the select. Otherwise, it returns ROSE_FALSE, and the select is unchanged.

Example

Given the nested characterized_definition example below, we could use the following code to set a value.

    // The definition of a property is a characterized_definition 
    // select, which could contain:
    //   characterized_object,
    //   characterized_product_definition (nested select)
    //       product_definition,
    //       product_definition_relationship
    //   product_definition_shape
    //   shape_aspect, 
    //   shape_aspect_relationship

    RoseDesign * d
    property_definition * prop;
    product_definition * new_pd;

    if (prop-> definition()) {
        // the top-level select exists already
        rose_put_nested_object (prop-> definition(), new_pd);
    }
    else {
        // create the top level object
        prop-> definition(
             ROSE_CAST(characterized_definition, 
                 rose_create_select (
                   ROSE_DOMAIN (characterized_definition), new_pd))
             ));

        // OR create it yourself and then put
        prop-> definition (pnewIn(d) characterized_definition);
        rose_put_nested_object (prop-> definition(), new_pd);
    }

See Also

rose_clear_select(); rose_create_select(); rose_get_nested_object()

rose_put_ref()

RoseRefUsage * rose_put_ref(
	RoseReference * ref,
	RoseObject *	obj,
	RoseAttribute * att,
	unsigned 	idx = 0
	);

RoseRefUsage * rose_put_ref(
	RoseReference * ref,
	RoseObject *	obj,
	const char * 	attname
	);

RoseRefUsage * rose_put_ref(
	RoseReference * ref,
	RoseAggregate *	obj,
	unsigned 	idx
	);

RoseRefUsage * rose_put_ref(
	RoseReference * ref,
	RoseUnion *	obj
	);

The rose_put_ref() function associates an external reference with a field of an object. Several versions of the function are provided for use with entities, selects, and aggregates. Assigning a reference to entities needs an attribute, aggregates needs an index, and selects do not need any additional information.

To construct and use an external reference, first use rose_make_ref() to create the reference object with the URI, and then assign it to a field using rose_put_ref(). This will also give the field the resolved value of the reference (if not null).

The function returns a RoseRefUsage structure which holds internal usage information.

Example

stp_product_definition_formation * pdf;

RoseReference * ref = rose_make_ref(
    pdf->design(), "file://foobar.stp#anchor1"
    );

rose_put_ref (ref, pdf, "of_product");

See Also

References Between Data Sets; rose_get_ref(); rose_make_ref()

rose_refcount()

unsigned long rose_refcount(
	RoseObject* obj
	);

The rose_refcount() function returns the reference count of the given object. The rose_compute_refcount() function must have been previously called to compute the reference counts for each object. This function will return zero if the counts have not been computed.

You can test if reference counts have been computed by calling rose_refcount() on a RoseDesign. The function will return a non-zero value if reference counts have previously been computed by a call to rose_compute_refcount().

See Also

Reference Counting; rose_compute_refcount(); rose_release_refcount()

rose_refcount_dec()

unsigned long rose_refcount_dec(
	RoseObject* obj
	);

The rose_refcount_dec() function decrements the reference count of the given object and returns the new value. If the reference count is already zero, or if reference counts have never been computed, the function just returns zero.

See Also

Reference Counting; rose_refcount(); rose_refcount_inc(); rose_refcount_put(); rose_refcount_dec_atts(); rose_refcount_recursive_dec_atts()

rose_refcount_dec_atts()

void rose_refcount_dec_atts(
	RoseObject* obj
	);

The rose_refcount_dec_atts() function decrements the reference count of the attributes of a given object. This does not decrement the count of the initial object, only of the objects that it points to through its attributes.

This function only follows one level of reference. A recursive version is also available as rose_refcount_recursive_dec_atts().

See Also

Reference Counting; rose_refcount(); rose_refcount_dec(); rose_refcount_recursive_dec_atts()

rose_refcount_inc()

unsigned long rose_refcount_inc(
	RoseObject* obj
	);

The rose_refcount_inc() function increments the reference count of the given object and returns the new value. There is no need to call rose_compute_refcount() before calling this function. An application can compute and manage reference counts on selected objects using this function if desired.

See Also

Reference Counting; rose_refcount(); rose_refcount_dec(); rose_refcount_put()

rose_refcount_put()

unsigned long rose_refcount_put(
	RoseObject* obj,
	unsigned long count
	);

The rose_refcount_put() function sets the reference count of the given object and returns the same count value. There is no need to call rose_compute_refcount() before calling this function. An application can compute and manage reference counts on selected objects using this function if desired.

See Also

Reference Counting; rose_refcount(); rose_refcount_inc(); rose_refcount_dec()

rose_refcount_recursive_dec_atts()

void rose_refcount_recursive_dec_atts(
	RoseObject * obj, 
	ListOfRoseObject * return_now_unrefed = 0
	);

The rose_refcount_dec_atts() function decrements the reference count of the attributes of a given object. This continues to recursively decrement attributes of a sub-object if it becomes unreferenced. If the second parameter is used, the function will populate a list with pointers to all of the objects that becomes unreferenced as a result of the call.

This does not decrement the count of the initial object, only of the objects that it points to through its attributes.

Example

Using this function, you could write a function to cleanly delete a tree of objects as shown below. Objects would only be deleted if they were not referenced elsewhere The counts must have been initialized by an earlier call to rose_compute_refcount().

    ListOfRoseObject objs;
    unsigned i, sz;

    rose_refcount_recursive_dec_atts(obj, &objs);
    for (i=0, sz=objs.size(); i<sz; i++) {
        rose_move_to_trash (objs[i]);
    }
    rose_move_to_trash (obj);

See Also

Reference Counting; rose_refcount(); rose_refcount_dec(); rose_refcount_dec_atts()

rose_register_substitute()

void rose_register_substitute(
	RoseObject * orig, 
	RoseObject * substitute
	);

The rose_register_substitute() function is part of the reference substitution API. This function is used to substitute one object for another and make sure that all references to the original object are updated.

First, an application calls rose_register_substitute() to specify the replacement object. Next, the original object is usually moved to the trash. When the trashcan is emptied, or rose_update_object_references() is called, pointers to the original object will be replaced by pointers to new one.

If you are using C++ classes, the new pointer must meet all C++ type compatibility constraints met by the original. The update also nulls out references to trashed or non-persistent objects. The rose_update_object_references() function will only update references in one design. Emptying the trash calls the update function on all designs and deletes all objects in the trash design.

It is not necessary to move the original object to the trash, but if it isn't, the substitution remains in effect. Any references to the object will continue to be changed whenever the trash is emptied or the update function is called.

See Also

rose_update_object_references(); rose_expand_substitutes()

rose_release_backptrs()

void rose_release_backptrs(
	RoseDesign * des
	);

The rose_release_backptrs() function frees the backpointers that were computed by a previous call to rose_compute_backptrs().

See Also

Backpointers; RoseBackptrs; RoseBackptrCursor; rose_compute_backptrs()

rose_release_refcount()

void rose_release_refcount(
	RoseDesign * des
	);

The rose_release_refcount() function clears the reference count data that was computed by a previous call to rose_compute_refcount(). This releases the memory that was used to store the reference counts. It is safe, although inefficient, to call this function multiple times, or without previously calling the compute function.

See Also

Reference Counting; rose_compute_refcount()

rose_set_cxx_schema()

void rose_set_cxx_schema(
	RoseDesign * schema
	);

void rose_set_cxx_schema_from_design(
	RoseDesign * design
	);

The rose_set_cxx_schema() functions change the RoseDomain data-dictionary entries associated with the RoseType C++ class information. The C++ class information is used by the pnew and ROSE_DOMAIN() operations.

If an application is working with schemas that have overlapping entity definitions, like many of the STEP APs, the C++ class information may be associated with data-dictionary entries from the wrong schema. This could cause incorrect behavior in traversals, the isa() function, and other areas.

The rose_set_cxx_schema() function changes all built-in C++ types to use data-dictionary entries from the given schema. The rose_set_cxx_schema_from_design() function sets the C++ class information using the schema (or schemas) of the given design.

Example

Consider software that reads both AP203 and AP214 files. When working on either type of file, we force the C++ classes to use the appropriate domains. This is done using the "set from design" function.

    RoseDesign * design;
    design = ROSE.findDesign ("AP214_datafile.stp");
    rose_set_cxx_schema_from_design (design);

If we are creating a new design, we can set the schema manually using the rose_set_cxx_schema() function or we can set it from the design as before.

    RoseDesign * design;
    RoseDesign * schema;

    /* The AP203 schema */
    schema = ROSE.findDesign ("config_control_design");

    /* create AP203 data set */
    design = new RoseDesign ("AP203_datafile.stp", schema);
    rose_set_cxx_schema (schema);

    /* alternate approach */
    design = new RoseDesign ("AP203_datafile.stp", "config_control_design");
    rose_set_cxx_schema_from_design (design);

See Also

Switching Between with Several Long Form APs

rose_strcasecmp() / rose_strncasecmp()

int rose_strcasecmp(
	const char * str_a, 
	const char * str_b
	);

int rose_strncasecmp(
	const char * str_a, 
	const char * str_b,
	int num
	);

The rose_strcasecmp() and rose_strncasecmp() functions are used internally by the ROSE library. They perform string comparison in the manner of strcmp() but as if the input strings were converted to all lowercase. The rose_strncasecmp() function compares a fixed number of characters in the style of strncmp().

These functions ignore the current locale settings and only convert case for the 7bit characters A-Z and a-z. Any high-bit UTF8 or ANSI characters are compared verbatim. The functions also treat null pointers as an empty string ("") for comparison.

Note that the rose_strcmp_as_lower() function is just an alias for rose_strcasecmp().

rose_strcenter()

char * rose_strcenter(
	char * buf,
	const char * str,
	size_t bufsz
	);

The rose_strcenter() functions is a simple string utility that centers a string in a buffer of a given size. The first argument is the buffer to be filled, the second is the string to fill it with and the last is the size of the buffer. The function returns a pointer to the buffer. The input buffer and source strings must not be in overlapping memory.

rose_strcmp_as_lower() / rose_strcmp_as_upper()

int rose_strcmp_as_lower(
	const char * str_a, 
	const char * str_b
	);

int rose_strcmp_as_upper(
	const char * str_a, 
	const char * str_b
	);

The rose_strcmp_as_lower() and rose_strcmp_as_upper() functions are used internally by the ROSE library. They perform string comparison in the manner of strcmp() but as if the input strings were converted to all lowercase or all uppercase characters, respectively.

These functions ignore the current locale settings and only convert case for the 7bit characters A-Z and a-z. Any high-bit UTF8 or ANSI characters are compared verbatim. The functions also treat null pointers as an empty string ("") for comparison.

rose_strtolower() / rose_strtoupper()

char * rose_strtolower(
	char * str
	);

char * rose_strtoupper(
	char * str
	);

The rose_strtolower() and rose_strtoupper() functions are used internally by the ROSE library. These simple string utility functions convert the contents of a string to all lowercase or all uppercase characters, respectively.

These functions ignore the current locale settings and only convert case for the 7bit characters A-Z and a-z. Any high-bit UTF8 or ANSI characters are left unchanged.

The functions return the string pointer that was passed in. They will also tolerate a null pointer as input.

rose_trash()

RoseDesign * rose_trash();

The rose_trash() function returns a pointer to the trash design. The trash design contains objects scheduled for deletion. Persistent objects can be moved to the trash using the rose_move_to_trash() function, or by using RoseObject::move() with the trash design pointer.

Example

    Point * pt = pnew Point;

    rose_move_to_trash (pt);
    pt-> move (rose_trash());    /* equivalent */

See Also

Deleting Objects; rose_empty_trash(); rose_move_to_trash()

rose_update_object_references()

void rose_update_object_references(
	RoseDesign * design
	);

The rose_update_object_references() function examines every attribute of every object in one specific design. The function expands all reference substitutions that have been put in place by either rose_register_substitute() or rose_mutate(), and nulls out references to trashed or non-persistent objects.

The rose_empty_trash() function performs the same operation on all designs in memory.

See Also

rose_register_substitute(); rose_expand_substitutes(); rose_empty_trash()

rose_use_ap_interoperability()

int rose_use_ap_interoperability();

[This function is deprecated. It has been replaced with the techniques used by the merged CAD schema library.]

This function enables the use of integrated schemas, RoseAPContext objects and multiple AP features described in Integrated Databases Using Multiple AP Part 21 Files.

To initialize these features, the function must find and read the integrated schema configuration file. The integrated schema directory should contain the integrated schema files as well as iso_ap_list.rose. The function will return a non-zero error code if it is unable to find the schema configuration file.

The directory can be specified using either the $ROSE_AP_PATH environment variable or the rose_setenv_integrated_schema_path() directory.

See Also

Integrated Schemas and AP Contexts; rose_getenv/setenv integrated_schema_path()

| Book Contents | Book Index | ST-Developer Home |