# Use the C-Language Implementation of the API

The C-language implementation of the API is divided into the following function suites:

- File Extraction API Functions—Open and extract subfiles in a container file. These functions also extract metadata and file format information, and control character set conversion on extraction.

- HTML Export API Functions— Extract format information (metadata, character set, and format), create an input/output stream from a file, and open, convert, and close the stream.

- HTML Export API Callback Functions—Controls the conversion while it is in progress.

## Input/Output Operations

In the Export API, the source input and target output can be either a physical file accessed through a file path, or a stream created from a data source. A stream is a C structure that contains pointers to I/O functions similar in nature to their standard ANSI C counterparts. This structure is passed to Export functions in place of the standard input source. See KVInputStream and KVOutputStream.

You can create an input stream either by using the `fpFileToInputStreamCreate()` function, or by using code similar to the example code in the `io_samp` sample program. You can create an output stream by using the `fpFileToOutputStreamCreate()` function. These functions assign C equivalent I/O functions to `fpOpen()`, `fpRead()`, `fpSeek()`, `fpTell()`, and `fpClose()`. See fpFileToInputStreamCreate() and fpFileToOutputStreamCreate().

## Convert Files

To use the C-language implementation of the API

1. Develop the HTML markup and tokens to be assigned to the required members of a declared instance of `KVHTMLTemplateEx`.

   If you use markup in the structure that is not compliant with HTML standards, HTML Export inserts the markup into the output file unchanged. This might result in a malformed HTML file.

2. Declare instances of the following types and assign values to the members as required:

       KVHTMLTemplateEx
       KVHTMLOptionsEx
       KVHTMLHeadingInfo
       KVHTMLTOCOptions

   See HTML Export API Structures for more information.

3. Load the `KVHTML` library and obtain the `KVHTMLInterfaceEx` entry point by calling `KVHTMLInterfaceEx`. See KVHTMLGetInterfaceEx().

4. Initialize an Export session by calling `fpInit()` or `fpInitWithLicenseData()`. The function's return value, `pContext`, is passed as the first argument to all other Export functions. See fpInit() or fpInitWithLicenseData().

5. Pass the context pointer from fpInit() or fpInitWithLicenseData() and the address of a structure containing pointers to the File Extraction API functions in the call to `KVGetExtractInterface()`. See. KVGetExtractInterface().

6. If you are using streams for the input and output source, follow these steps; otherwise, proceed to Step 7:

   1. Create an input stream (`KVInputStream`) either by calling `fpFileToInputStreamCreate()`, or by using code similar to the example code in the `io_samp` sample program. fpFileToInputStreamCreate().

   2. Create an output stream (`KVOutputStream`) either by calling `fpFileToOutputStreamCreate()`, or by using code similar to the example code in the `io_samp` sample program. fpFileToOutputStreamCreate().

   3. Proceed to Step 7.

7. Declare the input stream or file name in the `KVOpenFileArg` structure. See KVOpenFileArg.

8. Open the source file by calling `fpOpenFile()` and passing the `KVOpenFileArg` structure. This call defines the parameters necessary to open a file for extraction. See fpOpenFile().

9. Determine whether the source file is a container file (contains subfiles) by calling `fpGetMainFileInfo()`. See fpGetMainFileInfo().

10. If the call to `fpGetMainFileInfo()` determined the source file is a container file, proceed to Step 11; otherwise, proceed to Step 14.

11. Determine whether the subfile is itself a container (contains subfiles) by calling `fpGetSubFileInfo()`. See fpGetSubFileInfo().

12. Extract the subfile by calling `fpExtractSubFile()`. See fpExtractSubFile().

13. If the call to `fpGetSubFileInfo()` determined the subfile is a container file, repeat Step 6 through Step 12 until all subfiles are extracted; otherwise, proceed to Step 14.

14. Setup an out-of-process session by calling `KVHTMLStartOOPSession()`. See KVHTMLStartOOPSession().

15. Convert the input and generate the output files by calling `KVHTMLConvertFile()` or `fpConvertStream()`. The structures `KVHTMLTemplate`, `KVHTMLOptions`, and `KVHTMLTOCOptions` are defined in the call to `KVHTMLStartOOPSession()`, and should be `NULL` in the conversion call. A conversion function can be called only once in a single out-of-process session. See KVHTMLConvertFile(), and fpConvertStream().

16. If you are using callbacks, they are called while the conversion process is underway. If required, you can specify alternate paths and file names for output files, including using the table of content entries for the file names. See HTML Export API Callback Functions.

17. If you are converting additional files, terminate the out-of-process session by calling `KVHTMLEndOOPSession()` and setting the Boolean to `TRUE`. The Servant ends the current conversion session, and releases the source data and session resources.

    If you are not converting additional files, terminate the out-of-process session and the Servant process by calling `KVHTMLEndOOPSession()` and setting the Boolean to `FALSE`. See KVHTMLEndOOPSession().

18. Close the file by calling `fpCloseFile()`. See fpCloseFile().

19. If you used streams, free the memory allocated for the input stream and output stream by calling the functions `fpFileToInputSreamFree()` and `fpFileToOutputStreamFree()`. See fpFileToInputStreamFree() and fpFileToOutputStreamFree().

20. Repeat Step 6 through Step 18 for additional source files.

21. Shutdown the Export session by calling `fpShutDown()`. See fpShutDown().

## Multithreaded Conversions

To ensure that multithreaded conversions are thread-safe, you must create a unique context pointer for every thread by initializing the Export session with fpInit() or fpInitWithLicenseData(). In addition, threads must not share context pointers, and the same context pointer must be used for all API calls in the same thread. Creating a context pointer for every thread does not affect performance because the context pointer uses minimal resources.

For example, your code should have the following logic for one thread:

    fpInit()
       KVGetExtractInterface()
       fpFileToInputStreamCreate()
       fpFileToOutputStreamCreate()
          fpOpenFile()
          fpGetMainFileInfo()         /* container file */
          fpGetSubFileInfo()
          fpExtractSubFile
          KVHTMLStartOOPSession()
          fpConvertStream()
          KVHTMLEndOOPSession(bKeepServantAlive TRUE)
          fpCloseFile()
       fpFileToInputSreamFree()
       fpFileToOutputStreamFree()
          set input/output file
          fpOpenFile()
          fpGetMainFileInfo()           /* not a container file */
          KVHTMLStartOOPSession()
          KVHTMLConvertFile()
          KVHTMLEndOOPSession(bKeepServantAlive TRUE)
          fpCloseFile()
       ...
    fpShutdown()

_FT_HTML5_bannerTitle.htm