# Coding conventions

Use the conventions described in this topic when writing the service interface for a Natural Access service. Natural Access includes conventions for:

- Function names

- Function arguments

- Return values

- Error, reason, event, command, and trace tag codes

- Manifest constants and enumerations

- Structures

- Parameter structures

## Function names

All API functions for the service begin with the service's three letter acronym (for example, adiStartCallProgress).

For each API function, the corresponding SPI function and implementation function must use the following naming convention:

API and SPI function names

The naming convention for the managed resource event handler is xxxFetchAndProcess. All other functions should follow the convention xxxFunctionDescription.

## Function arguments

Arguments to functions can be one of the following types:

Argument type | Description
--- | ---
in | Argument provides an input value for the function.
out | Argument is a buffer to place output from the function.

A single argument cannot be used for both input and output (inout). This is not merely a convention, but is mandated by internal Natural Access processing of dispSendCommand.

In arguments should precede out arguments whenever possible.

Argument names should be lower case without underscores. Underscores can be used if the argument name is long and would be unreadable or misread without them. Arguments should be weakly typed (for example: int or unsigned) instead of strongly typed (for example: INT32 or DWORD).

Certain data types cannot be used as arguments to API or SPI functions. These are:

- Function addresses (such as callback function addresses)

- Any local (to the application process) handles such as a file handle

- Pointers to local memory, except in the case of an asynchronous buffer

### Buffer arguments in API calls

Service API functions can use both synchronous and asynchronous buffers. All buffers must be allocated on the client side. Buffers cannot be allocated on the server side and directly returned to the client side.

Note: Buffers for events are handled differently. For details, refer to the Buffer management summary section.

Special flags are used within the command structure when data buffers are associated with an API command. These flags are discussed in DISP_COMMAND structure and DISP_EVENT structure. The following illustration provides an overview of buffer management:

Buffer management overview: API calls

## Return values

All Natural Access functions return a status code that can be either SUCCESS, CTAERR_something, or XXXERR_something. Any other information returned from a function should be handled using out arguments.

A return value of SUCCESS for an asynchronous function means that the function request was initiated. The function subsequently may fail and return an error in an event. For a synchronous (short term blocking) function, no events are returned and SUCCESS means that the command completed with no errors.

When defining return codes, reuse existing Natural Access return and error codes as much as possible (for example, CTAERR_something).

## Event and reason names

Events for a service must be named XXXEVN_something.

The event structure contains a value field which can further classify an event by providing additional information (for example, an error code).

To further classify a DONE event, the value field may contain a reason code. Reasons for a service must be named XXX_REASON_something. Reasons are typically used to indicate an application error (for example, the network is down). Error codes typically indicate a programming problem.

When defining the service events and reasons, one should attempt to reuse existing Natural Access event and reason codes as much as possible.

## Error, reason, event, command, and trace tag codes

Error, reason, event, command, and trace tag codes are constructed using the service ID, a type code (to distinguish between errors, events, commands, or reasons), and a sequence number.

The following table lists the valid range of types as defined in ctadef.h:

Description | Sequence range | Type code
--- | --- | ---
Error codes | 0x0000 - 0x0FFF | CTA_CODE_ERROR (0x0000)
Reason codes | 0x1000 - 0x1FFF | CTA_CODE_REASON (0x1000)
Event codes | 0x2000 - 0x2FFF | CTA_CODE_EVENT (0x2000)
Command codes | 0x3000 - 0x3FFF | CTA_CODE_COMMAND (0x3000)
Trace tag codes | 0x4000 - 0x4FFF | CTA_CODE_TRACETAG (0x4000)

Note: DONE event codes must have the 0x100 bit set. All other event codes must not have this bit set.

Natural Access macros are used to assign an error/reason/event/command/tracetag code. A code is constructed by using the service ID, the type code, and a sequence number as shown:

(( service_id << 16 ) | type_code | sequence )

For example, assigning an ADI service error code:

#define ADIERR_PLAYREC_ACCESS (( ADI_SVCID << 16 ) | CTA_CODE_ERROR | 1 )

To facilitate browsing, the defines should be assigned to the resultant hexadecimal number rather than constructed. That is, the adidef.h header actually contains the following definition:

#define ADIERR_PLAYREC_ACCESS 0x10001

where the ADI_SVCID value is 1.

Note: DONE events must have the 0x100 bit set. All other events must not have this bit set. For example, an event with code 0x10002103 is a DONE event. An event with code 0x10002004 is not a DONE event.

## Manifest constants and enumerations

The naming convention for enumerations is the same as for manifest constants. Names are in all capital letters. The service acronym is separated from the manifest by an underscore. Underscores should be used freely to separate words to make the manifests and enumeration names more readable. For example:

#define CTA_UNITS_INTERNAL 0
#define CTA_UNITS_INTEGER 1
typedef enum {CTA_TRACE_SEVERITY_INFO=0,
CTA_TRACE_SEVERITY_WARNING,
CTA_TRACE_SEVERITY_ERROR} CTA_TRACE_SEVERITY;
#define VCE_FILETYPE_AUTO 0
#define VCE_FILETYPE_VOX 1
#define VCE_FILETYPE_WAVE 2
#define VCE_FILETYPE_FLAT 3

## Structures

Structures should include a size field as the first field. The size of the structure should be passed as an extra argument if the structure is an out argument and the size field of the structure will be filled with the output size. Structure fields must be strongly typed (for example, INT32, DWORD) for compatibility between libraries and applications.

For backward compatibility, structure fields should never be removed, only added.

Each field within a structure must use 4 byte packing (each must begin on a four byte boundary). The total size of the structure must be a multiple of 4 bytes, in case an application uses 1 or 2 byte packing.

Structure names (typedefs) should be all upper case with underscores to improve readability.

Structure field names should be all lower case with no underscores unless needed for readability.

Parameter structures must have fields that can be classified into one of the valid parameter field types (see ctaGetParmInfo for a list of valid field descriptors).

## Parameter structures

Parameter structures that are arguments to a service API function call must follow the xxx_PARMS naming convention. For example, the ADI function to start playing requires the ADI_PLAY_PARMS data structure.

If the value of the parameter passed with the API function call is NULL, the service implementation uses the context default values.