Skip Headers
Oracle® Outside In Transformation Server Developer's Guide
Release 8.3.7

Part Number E12868-02
Go to Documentation Home
Home
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

7 IO Provider Specification

In order to support the reading, writing, and creation of documents that are not stored on the operating system's file system, Transformation Server has defined a generic input/output interface called the IO Provider Interface. An IO Provider is a module that implements this interface. On the other side of this interface, the code that loads and uses an IO Provider is called an IO Consumer. All document access in Transformation Server is accomplished through the IO Provider interface; it is also available for use by any third-party developer of a custom transformation engine.

This version of the IO Provider interface is available only for developers coding in C or C++. Users writing code in Java who wish to perform redirected IO should refer to Section 5.3, "Redirected IO."

The IO Provider Interface allows bi-directional random access to a stream of data, and is modeled after file-based input and output. (We also refer to this functionality as "redirected IO" because the transformation process is operating on a source other than a file.) This interface allows an IO Consumer to treat any target data stream as if it were a file, while leaving the IO Provider itself responsible for the specific details of accessing and modifying that data stream.

The IO Provider Interface includes operations for creation, opening, closing, reading, writing, and seeking; as well as a method for querying the IO Provider for various data about the particular IO target.

An IO Provider acts as a "plug-in" component to Transformation Server. An IO Provider does not implement SOAP or any other type of interprocess communication (except possibly for private reasons). Integration with the Transformation Server infrastructure and the engine that accomplishes a transformation is handled by Transformation Server itself.

7.1 IO Provider Interface

The IO Provider interface is a generic means of opening, creating, reading or writing documents, modeled on file-based input/output functions. This interface may be implemented by a developer to provide Transformation Server with access to documents that don't reside on a file system.

7.1.1 Why Use IO Providers?

A developer writing an application that uses Transformation Server may wish to transform or create documents that reside in a database, document management system, some other repository, or a file system to which Transformation Server does not have access. If Transformation Server supported only file-based IO, these applications would be required to copy and manage temporary files as part of their interaction with Transformation Server.

The IO Provider interface supplies a more flexible solution to the problem. Once an IO provider is written for a particular repository, it can be used by any transformation technology installed on Transformation Server.

7.1.2 IO Specifications

The specification of an input or output document is simply the identifier by which it is known in its native repository; for example, a file's specification is its path. Transformation Server requires that input and output documents be identified by both a specification and a specification type, which is a text label that identifies how the specification should be interpreted. The two specification types that are natively supported by Transformation Server are file-system paths and URLs, but any IO Provider can extend this set. The Transformation Agent configuration file maintains a mapping of each specification type to the IO Provider module that supports it.

An IO Provider may support any number of specification types, but only one IO Provider may handle any given specification type.

7.1.3 Server-Side Versus Client-Side IO Providers

A "client-side" IO Provider executes its code in the same process as the client application, while a "server-side" IO Provider is supplied as a module that is loaded by a Transformation Agent when needed. Transformation Server defines two versions of the IO Provider interface: one for Java that is only available on the client-side, and a C-language version that can be deployed on either the client or server sides of Transformation Server.

Server-side IO is straightforward: the appropriate IO Provider module is loaded by the Transformation Agent and provides functions through which the Transformation Engine reads and writes its input and output.

Client-side IO is a little more complicated. For one thing, it is only supported when the application is using either the C/C++ or Java client modules to communicate with Transformation Server.

Figure 7-1 Client Side IO Provider

Flowchart of the client-side IO provider

In order for the Transformation Engine on the server to read data from a client-side IO provider, the engine interacts with a proxy IO Provider (a component supplied with Transformation Server). The proxy communicates to the C/C++ or Java interface module, relaying the IO operations via a private protocol. The client module in turn uses the client-side IO Provider to perform the operation, the results of which are sent back up to the server-side proxy.

The IO communication flows through a different socket than the SOAP communication that controls the Transformation Manager, and won't interfere with the general operation of Transformation Server.

7.1.4 The C Version

Most of the IO Provider functionality is encapsulated in the BASEIO data structure, which contains pointers to the IO functions implemented by the IO Provider. Transformation Engines interact directly with the BASEIO structure to open, create, read, and write input and output documents.

The Transformation Agent obtains a pointer to a BASEIO object from an IO provider by calling OpenIO, which is an entry point function that must be implemented by the IO Provider. This function receives the specification of the document to be opened/created, flags that tell how the document is to be opened, and a pointer to a structure that provides access to functions within the Transformation Agent.

The BASEIO structure contains pointers to functions that provide the following operations: read, write, seek, tell, close, and GetInfo. The first five functions are directly analogous to common file operations. The GetInfo function provides information for various queries that aren't directly related to reading, writing, or positioning within the IO stream. The Transformation Engine may use the GetInfo function to determine things such as the size of the stream, a URL that should be used to link to the stream, or an IO specification for an additional output stream.

If a developer has written both a Transformation Engine and an IO Provider, the GetInfo function may also be used to exchange private data between them.

7.1.5 The Java Version

The functionality of the Java version is identical to the C client version, except that the data structures and functions referred to in the previous section are replaced with similarly-named Java classes (BaseIO and OpenIO).

The basic architecture of the Outside In technology is the same across all supported platforms.

7.2 Configuration

This section contains basic configuration information.

7.2.1 Server-Side Versus Client-Side Operation

As a client-server application, Transformation Server runs its transformation operations in a separate process from the "client" application that uses it. For maximum flexibility, Transformation Server allows IO Providers to supply redirected IO on either the server side or the client side. In other words, the code that provides the IO may execute in the process of the client application or in the process where the transformation occurs. From an implementation point of view, there is little to no difference between the two approaches; it is entirely possible to use the same binary code to provide redirected IO on both the client and server.

In server-side redirected IO, the IO Provider must be built as a dynamically loadable library that is loaded by the transformation process as needed. Communication with the IO Provider then proceeds in-process as the transformation is being performed. This provides more efficient performance than client-side redirected IO, and should be considered the preferred configuration.

An application that wishes to use client-side redirected IO must also use the C Client interface (SCCTS module). The C client API will communicate privately with the server-side Transformation Agent to marshal all IO operations between the two processes.

7.2.1.1 Installing an IO Provider on the Server

Build your IO Provider code into a loadable module/DLL, with OpenIO specified as an exported function. Copy this module to a location accessible to Transformation Server, such as the root level of the install directory.

Modify the Transformation Server configuration file agent_iospec_types.xml to indicate the location of your IO Provider. In this step, you must also define the name of an IO spec type that will be mapped to your IO Provider (the specType field in the TS_IOSpec structure). Note that the specType value redirect is reserved for client-side redirected IO, and is not allowed for a server-side IO provider.

Example:

<?xml version="1.0" encoding="UTF-8"?>
<IoSpecTypeToModuleMap xsi:type="..." attributes deleted for 
   readability>
      <SpecType xsi:type="tss:SpecType">
      <!-- For local file system and shared file system paths-->
      <Name xsi:type="xsd:string">myspectype</Name>
      <Module xsi:type="xsd:string">my_io_module.dll</Module>
   </SpecType>
   ...Other SpecType elements ...
</IoSpecTypeToModuleMap>

7.2.1.2 Using an IO Provider on the Client

To use an IO Provider on the client, you supply the address of your OpenIO function as a parameter to the TSInit function in the SCCTS module. Then, when you need to supply a specification of a data stream that should be opened with your IO Provider, you use the reserved specType value redirect.

7.3 IO Provider Entry Point

This section describes the OpenIO function, which is the entry point through which an IO Consumer opens a new data stream for reading or writing, and the BASEIO data structure.

7.3.1 OpenIO

IOERR OpenIO( const * ioSpec,
   VTDWORD dwFlags,
   IOConsumerInterface * pConsumer,
   BASEIO ** ppBaseIO);

The OpenIO function is the entry point through which an IO Consumer opens a new data stream for reading or writing.

Parameters

  • ioSpec: This is the specification of the data stream to be opened, or created and opened.

  • dwFlags: The flags indicate whether the file is opened for read, write and create operations. These flags may be combined together to as desired. The valid flags are:

    • IOOPEN_READ: The secondary file should be opened for read.

    • IOOPEN_WRITE: The secondary file should be opened for write. Please note that if the specified file already exists, it's contents will be erased when this flag is set.

    • IOOPEN_CREATE: The secondary file should be created and opened for write.

  • pConsumer: This is a pointer to the IO Consumer interface of the caller.

  • ppBaseIo: This is a pointer to a pointer to a BASEIO structure. The IO Provider must allocate and initialize this data structure, and set ppBaseIO to point to it. A new BASEIO structure must be separately allocated for each data stream opened via this call.

Return Values

This function returns an IOERR value:

  • IOERR_OK: The IO Provider was able to initialize and open the data stream

  • IOERR_NOFILE: The data stream could not be opened.

  • IOERR_NOCREATE: The data stream could not be created.

  • IOERR_BADPARAM: An invalid parameter was given to OpenIO.

  • IOERR_INVALIDSPEC: The IOSpec not valid for this IO Provider.

  • IOERR_FALSE: The reported version of the IOConsumerInterface is not supported.

7.3.2 The BASEIO Structure

The BASEIO structure is the means through which an IO Provider allows an IO Consumer access to its interface functions. It is a data structure that contains pointers to each of the interface functions implemented by the IO Provider. A pointer to this data structure is also included as a parameter in each of the functions it provides.

The BASEIO data structure is defined as follows:

typedef struct BASEIOtag
{
    IOCLOSEPROC pClose;
    IOREADPROC pRead;
    IOWRITEPROC pWrite;
    IOSEEKPROC pSeek;
    IOTELLPROC pTell;
    IOGETINFOPROC pGetInfo;
    IOOPENPROC pOpen; /* pOpen *MUST* be set to NULL. */
#ifndef NLM
    IOSEEK64PROC pSeek64;
    IOTELL64PROC pTell64;
#endif
    VTVOID *aDummy[3];
} BASEIO, * PBASEIO;

The fields of the BASEIO data structure should be set as follows:

  • pClose: Set this to point to your IOClose function

  • pRead: Set this to point to your IORead function

  • pWrite: Set this to point to your IOWrite function

  • pSeek: Set this to point to your IOSeek function

  • pTell: Set this to point to your IOTell function

  • pGetInfo: Set this to point to your IOGetInfo function

  • pOpen: Reserved. Must be set to null.

  • pSeek64: Set this to point to your 64-bit IOSeek function

  • pTell64: Set this to point to your 64-bit IOTell function

  • aDummy: Reserved

Remarks

In practice, when implementing an IO Provider you will probably need to associate your own private data with the BASEIO structure in order to maintain state information during IO operations. (You will be handed back your BASEIO pointer in every IO operation.)

You may do this in C by defining your own data structure that includes a BASEIO structure as its first element.

For example:

typedef struct MyIOStruct
{
   BASEIO               baseIO;
   MYDATA               myDataStream;
   IOConsumerInterface  * pConsumer;
   ...etc...
} MyIOStruct;

Then, from your OpenIO function, you would return a pointer to this data structure, cast as a BASEIO pointer:

MyIOStruct * pMyData;
pData = (MyIOStruct *) malloc(sizeof(MyIOStruct));

/* open the data stream and initialize the struct, then... */

*ppBaseIO = (BASEIO *) pMyData;

7.4 IO Provider Functions

For compatibility with older versions of Outside In SDKs, the type of the first parameter in the IO Provider functions (BASEIO *) may also be referred to by the typedef HIOFILE in header files and/or documentation. These two types should be considered interchangeable, as both are required to be the address of a BASEIO structure.

7.4.1 IOClose

This function tells the IO Provider that the IO Consumer has finished using a pointer to a BASEIO structure. Any allocated resources associated with the BASEIO may now be released. The IO Consumer will not make any use of this BASEIO structure after calling IOClose.

IOERR IOClose(BASEIO* pBaseIO);

Parameters

  • pBaseIO: The BASEIO structure.

Return Values

  • IOERR_OK: The data stream was closed.

  • IOERR_UNKNOWN: The data stream could not be closed.

7.4.2 IORead

Reads the next size bytes from the current position in the data stream; the current position should then be set to the byte after the last byte read.

IOERR IORead(BASEIO* pBaseIO, VTLPBYTE pData, VTDWORD size,
   VTLPDWORD pCount);

Parameters

  • pBaseIO: A pointer to the BASEIO structure for this data stream.

  • pData: Pointer to the buffer to read the data into.

  • size: The number of bytes to be read.

  • pCount: IORead sets *pCount to the number of bytes actually read.

Return Values

  • IOERR_OK: Read was successful. pCount contains the number of bytes read and pData contains the bytes themselves. A request for 0 bytes should return an unknown error.

  • IOERR_EOF: The data stream was already at the end of the file when this call was received.

  • IOERR_UNKNOWN: The data stream could not be read.

7.4.3 IOWrite

Writes size bytes at the current position in the data stream; the current position should then be set to the position after the last byte written.

IOERR IOWrite(BASEIO* pBaseIO, VTLPBYTE pData, VTDWORD size,
   VTLPDWORD pCount);

Parameters

  • pBaseIO: A pointer to the BASEIO structure for this data stream.

  • pData: Points to the data to be written to the data stream.

  • size: The number of bytes to be written.

  • pCount: IOWrite sets this to the number of bytes actually written.

Return Values

  • IOERR_OK: The data stream was successfully written.

  • IOERR_UNKNOWN: The data stream could not be written.

7.4.4 IOSeek

Moves the current data stream position.

IOERR IOSeek(BASEIO* pBaseIO, VTWORD wFrom, VTLONG lOffset);

Parameters

  • pBaseIO: A pointer to the BASEIO structure for this data stream.

  • wFrom: One of the following values:

    • IOSEEK_TOP: Move the data stream position to lOffset from the beginning of the data stream.

    • IOSEEK_BOTTOM : Move the data stream position to lOffset from the end of the data stream.

    • IOSEEK_CURRENT: Move the data stream position to lOffset from the current position in the data stream.

  • lOffset: The number of bytes to move the data stream position. May be positive or negative.

Return Values

  • IOERR_OK: The current stream position was successfully changed.

  • IOERR_UNKNOWN: The current stream position was not changed.

7.4.5 IOTell

Reports the current data stream position.

IOERR IOTell(BASEIO* pBaseIO, VTLPDWORD pOffset);

Parameters

  • pBaseIO: A pointer to the BASEIO structure for this data stream.

  • pOffset: Pointer to a DWORD that should be set to the current data stream position.

Return Value

  • IOERR_OK: Current position was reported.

  • IOERR_UNKNOWN: Failure to find or report the current position.

7.4.6 IOGetInfo

This is a multi-purpose function that is used for querying the IO Provider for information about the data stream and how it should be referenced in transformation output. Some of the queries may be ignored, while others are required to be handled.

The IOGetInfo function has the following prototype:

IOERR IOGetInfo(BASEIO* pBaseIO, VTDWORD dwInfoId, VTLPVOID
   pInfo);

Parameters

  • pBaseIO: A pointer to the BASEIO structure for this data stream.

  • dwInfoId: The Info ID of the info request being made.

  • pInfo: Pointer to auxiliary data that some info requests pass, or require to be returned.

Return Value

  • IOERR_OK: The requested information was supplied.

  • IOERR_BADINFOID: The specified query is not supported.

  • IOERR_UNKNOWN: The requested information is not available.

  • IOERR_FALSE: Returned in response to specific queries documented below.

7.4.6.1 IOGetInfo Info IDs

The following ID values are defined for dwInfoId. Pay particular attention to notes indicating that a value is required in order for transformations to succeed.

7.4.6.1.1 IOGETINFO_FILENAME_IOP

This message retrieves the name of the data stream. If the data stream represents a file in some non-file-system based repository, the file name is what should be returned from this message.

pInfo points to a TS_stringData structure. The IO Provider must allocate the str field within this structure using the Alloc function supplied in the IO Consumer interface. The name is to be copied into this allocated structure. The IO Consumer will be responsible for freeing the allocated memory.

This query must always be handled.

Example:

TS_IOSpec * pFilename = (TS_IOSpec *) pInfo;
MyIOStruct * pMyData = (MyIOStruct *) pBaseIO;
pInfo->str = pMyData->pConsumer->Alloc( strlen(pMyData->name)+1 );
strcpy( pInfo->str, pMyData->name );
7.4.6.1.2 IOGETINFO_PATHNAME_IOP

This message retrieves the full path to the data stream. If the data stream represents a file in some non-file-system based repository, and has path information associated with it, the path to the file is what should be returned from this message. If there is no appropriate response to this message, IOGetInfo should return IOERR_UNKNOWN.

pInfo points to a TS_stringData structure. The IO Provider must allocate the str field within this structure using the Alloc function supplied in the IO Consumer interface. The path is to be copied into this allocated structure. The IO Consumer will be responsible for freeing the allocated memory.

This query must always be handled.

Example:

TS_stringData * pFilename = (TS_stringData *) pInfo;
MyIOStruct * pMyData = (MyIOStruct *) pBaseIO;
pInfo->str = pMyData->pConsumer->Alloc( strlen(pMyData->path)+1 );
strcpy( pInfo->str, pMyData->path );
7.4.6.1.3 IOGETINFO_HYPERLINK - HTML Export Only

This message retrieves the URL of the data stream, and is used to generate links between transformation output documents.

pInfo points to a TS_stringData structure. The IO Provider must allocate the str field within this structure using the Alloc function supplied in the IO Consumer interface. The URL is to be copied into this allocated structure. The IO Consumer will be responsible for freeing the allocated memory.

This query must be handled when the output of the transformation is handled via the IO provider. If the IO provider is supporting only the input side of the transformation, this query will not be received.

This query must be handled when the output of the transformation is handled via the IO provider. If the IO provider is supporting only the input side of the transformation, this query will not be received.

Example:

TS_stringData * pFilename = (TS_stringData *) pInfo;
MyIOStruct * pMyData = (MyIOStruct *) pBaseIO;
pInfo->str = pMyData->pConsumer->Alloc( strlen(pMyData->url)+1 );
strcpy( pInfo->str, pMyData->url );
7.4.6.1.4 IOGETINFO_GENSECONDARY_IOP

This message is sent by an IO Consumer that needs to open an additional data stream for reading, which may occur with certain types of input documents that refer to other documents, or when transformation templates refer to secondary templates.

This query should be handled to support the complete set of input formats supported by Outside In, and the full range of template functionality. If not this query is not handled, transformations that use templates that refer to other templates will fail, as will transformations of some types of input documents.

pInfo points to an IOGENSECONDARY_IOP structure:

typedef struct IOGENSECONDARY_IOP
{
   TS_stringData   filename;
   TS_IOSpec       ioSpec;
   VTDWORD         dwOpenFlags
} IOGENSECONDARY_IOP, * PIOGENSECONDARY_IOP;
  • filename: Set by the caller. This is the name of the secondary data stream to be opened. In most cases there will be no "path" information. To use the analogy of files in a file system, the location of the current data stream would be the "current directory", and the data stream indicated by the filename parameter would be assumed to exist in the same "directory."

  • ioSpec: To be filled in by the IO provider in response to this message. An IO specification for the new document that may be used in a subsequent call to OpenIO to open the data stream. The IO Provider must allocate the spec.str and "specType" fields within this structure using the Alloc function supplied in the IO Consumer interface. The caller will be responsible for freeing these strings.

  • dwOpenFlags: A set of flags indicating how the secondary file should be opened. Multiple flags may be use by bitwise OR-ing them together. One of the following values:

    • IOOPEN_READ: The secondary file should be opened for read.

    • IOOPEN_WRITE: The secondary file should be opened for write.

    • IOOPEN_CREATE: The secondary file should be created and then opened.

7.4.6.1.5 IOGETINFO_CREATENEWIOSPEC

This message is sent by an IO Consumer when it needs to create an additional output data stream. During a transformation, the BASEIO associated with the primary output sink will receive this message for all additional output streams that need to be created. This message provides hints for the name and format of the output data stream, and requires that the IO Provider return an IO specification that can be used in a subsequent call to OpenIO.

This query must be handled for an IO Provider to support creation of output documents. It is not used for input documents.

pInfo points to an IOCREATENEWIOSPEC structure:

struct IOCREATENEWIOSPEC
{
   IOSpec   ioSpec;
   VTCHAR   *suggestedName; 
   VTCHAR   *outputType;    
} IOCREATENEWIOSPEC, * PIOCREATENEWIOSPEC;
  • ioSpec: To be filled in by the IO provider in response to this message. A specification for a new document that is going to be created by the transformation process. The IO Provider must allocate the spec.str and specType fields within this structure using the Alloc function supplied in the IO Consumer interface. The caller will be responsible for freeing these strings.

  • suggestedName: Set by the caller. A string, in UTF-8 encoding, that provides a suggested name for this output document. This string may be interpreted as the "base name" for the output document. (In a file system, this would be the portion of the file name prior to the extension.) This string pointer may also be null, indicating that there is no suggestion for the document name.

  • outputType: Set by the caller. A string, in UTF-8 encoding, that identifies the type of document for which the new specification will apply. This string may be interpreted as the default "file extension" for the new output document. The values for this string may include html, xml, gif, jpg, png, or another extension that may have been defined for other supported output formats. This string pointer may also be null, indicating that the file type is unknown.

7.4.6.1.6 IOGETINFO_PROVIDERDATA

This method is provided for the private use of the implementer. It is provided so that a developer who implements both a Transformation Engine and an IO Provider would have a convenient way to establish a private communication between the two.

This method is not supported when the IO Provider is executing on the client side.

This query is optional.

7.5 IO Consumer Interface

The IO Consumer interface is a set of functions provided and implemented by Transformation Server to be used by an IO Provider for various activities related to opening, reading and writing sources of input and output.

Like the BASEIO interface, the IO Consumer interface consists of a data structure (IOConsumerInterface) containing pointers to functions. The pointer to this data structure must be handed back to each of the IO Consumer functions.

7.5.1 Alloc

Certain operations in the BASEIO interface require the IO Provider to allocate memory, to be freed by the IO Consumer. The IO Consumer's Alloc function must be used for these allocations.

Prototype

typedef VTLPVOID (IO_CALLTYPE* IOCAllocProc)(const struct 
   IOConsumerInterface* pConsumer, VTDWORD dwSize);

Parameter

  • dwSize: The size, in bytes, of the memory to be allocated.

Return Values

Returns either a valid, non-null pointer to memory, or if the allocation fails, a null pointer.

7.5.2 Free

This function frees memory allocated via the IO Consumer's Alloc function. Note that this function should never be called to free memory that was returned to the IO Consumer via IOGetInfo operations.

This function is provided to allow the IO Provider to use the Alloc function for private memory allocations. Use of this function is strictly optional; when an IO source is closed, all of the memory allocated via the IO Consumer's Alloc function will be automatically cleaned up.

Prototype

typedef VTVOID (IO_CALLTYPE* IOCFreeProc)(const struct
   IOConsumerInterface* pConsumer, VTLPVOID pMem);


void Free(VTLPVOID pMem)

Parameters

  • pMem: A pointer to memory to be deallocated. The memory being deallocated must have been allocated using Alloc( ).

Return Values

none

7.5.3 UTF8toUCS2

Converts a UTF-8 string to UCS2 (wide character) using an algorithm from the Unicode Standard 2.0.

Prototype

typedef TSERR (IO_CALLTYPE* UTF8toUCS2Proc) (const struct 
   IOConsumerInterface* pConsumer, unsigned char*  sourceStart,
   wchar_t* targetStart, VTDWORD* pTargetSize); 

Parameters

  • sourceStart: The input UTF-8 character string. Must be null-terminated.

  • targetStart: The wide character array which will contain the Unicode string.

  • pTargetSize: Pointer to the variable that contains the size of the buffer for the UCS-2 string. Upon return, this will be set to the size in wide characters (not bytes) of the decoded string, including the terminating null. If this function returns TSERR_BOUNDSEXCEEDED, the pTargetSize will still be set to the full size of the correctly decoded string and can be used to determine an appropriate buffer size for a second attempt to decode the string.

Return Values

  • TSERR_OK: The conversion succeeded.

  • TSERR_BADPARAM: The sourceStart or pTargetSize is null.

  • TSERR_BOUNDSEXCEEDED: The UTF-8 string buffer wasn't large enough.

7.5.4 UCS2toUTF8

Converts a UCS2 string to UTF-8 string using an algorithm from the Unicode Standard 2.0.

Prototype

typedef TSERR (IO_CALLTYPE* UCS2toUTF8Proc) (const struct
   IOConsumerInterface* pConsumer, wchar_t* sourceStart,
   unsigned char* targetStart, VTDWORD* pTargetSize);

Parameters

  • sourceStart: The input UCS2 character string. Must be null-terminated.

  • targetStart: The byte array which will contain the UTF-8 string.

  • pTargetSize: Pointer to the variable that contains the size of the buffer for the UTF-8 string. Upon return, this will be set to the size (in bytes) of the decoded string, including the terminating null. If this function returns TSERR_BOUNDSEXCEEDED, the pTargetSize will still be set to the full size of the correctly decoded string and can be used to determine an appropriate buffer size for a second attempt to decode the string.

Return Values

  • TSERR_OK: The conversion succeeded.

  • TSERR_BADPARAM: The sourceStart or pTargetSize is null.

  • TSERR_BOUNDSEXCEEDED: The UTF-8 string buffers wasn't large enough.

7.5.5 IOConsumerInterface Data Structure

The IOConsumerInterface structure has the following definition:

typedef VTLPVOID (ENTRYMOD* IOCAllocProc)( const struct 
   IOConsumerInterface* pConsumer, VTDWORD size);
typedef VTVOID (ENTRYMOD* IOCFreeProc)( const struct 
   IOConsumerInterface* pConsumer, VTLPVOID pMem);
typedef IO_ENTRYPOINT TSERR (IO_CALLTYPE* UTF8toUCS2Proc) 
   (const struct IOConsumerInterface* pConsumer,
   unsigned char*   sourceStart,
   wchar_t*         targetStart,
   VTDWORD*         targetSize);
typedef IO_ENTRYPOINT  TSERR (IO_CALLTYPE* UCS2toUTF8Proc)
   (const struct IOConsumerInterface* pConsumer,
   wchar_t*         sourceStart,
   unsigned char*   targetStart,
   VTDWORD*         pTargetSize);

typedef struct IOConsumerInterface
{
   VTDWORD          version;
   IOCAllocProc     Alloc;
   IOCFreeProc      Free;
   UTF8toUCS2Proc   UTF8toUCS2;
   UCS2toUTF8Proc   UCS2toUTF8;
} IOConsumerInterface,  * PIOConsumerInterface;
  • version: This specifies the version number of the transformation agent API specification to which this agent was written. The format of this number is not currently documented, but later versions are guaranteed to have a higher version number than earlier versions. Developers should compare this value to kIOConsumerInterfaceVersion, which is the current version of the IO Consumer interface. If the IO Provider does not support the specified version, it should set the version field to a version number that it does support and return IOERR_FALSE from the OpenIO function.

  • Alloc: Points to the agent's IO Consumer's Alloc function.

  • Free: Points to the agent's IO Consumer's Free function.

  • UTF8toUCS2: Provides a function to transform characters from 8-bit UTF-8 encoding to 16-bit Unicode UCS-2 encoding.

  • UCS2toUTF8: Provides a function to transform characters from 16-bit Unicode UCS-2 encoding to Unicode 8-bit UTF-8 encoding.