How to Load a Package for Reading

This topic shows how to use Packaging APIs to load a package to be read.

This topic contains the following sections.

Before your application can access the components of a package, it must load the package for reading by using the Packaging API to create a read-only stream over the package.

You can use a stream either to read a package or to write a package, but you cannot use the same stream for both reading and writing. This topic describes how to use a read-only stream to load a package for reading. For an example of reading and writing a package, see the Set Author Sample topic.

[!Important]
The stream that you use to load a package for reading remains active for the lifetime of the package object with which it is associated. Do not you use the same stream for both read and write operations because this can cause undefined behavior.

 

Steps to Load a Package

The following steps describe how to access the Packaging API from your application and how to use those APIs to load a package for reading.

  1. Define a function that loads a package:

    HRESULT
    LoadPackage(
        IOpcFactory *factory,
        LPCWSTR packageName,
        IOpcPackage **outPackage
        )
    {
    

    This example function requires a reference to a Packaging API factory object instance as an input parameter because your application can retain a reference to that instance and use it to call Packaging APIs repeatedly.

  2. Declare a stream:

        IStream * sourceFileStream = NULL;
    

    This example uses a default implementation of IStream; if you use a custom stream implementation that does not support the IStream::Clone method, the package is buffered and read sequentially, incurring overhead when an application accesses package components.

  3. Create a read-only stream over the package to be read:

        // Create a read-only stream over the package to prevent errors caused by
        // simultaneously writing and reading from a package.
        HRESULT hr = factory->CreateStreamOnFile(
                        packageName, 
                        OPC_STREAM_IO_READ, 
                        NULL, 
                        0, 
                        &sourceFileStream
                        );
    
  4. Load the package to be read:

        if (SUCCEEDED(hr))
        {
            // Note: If a part is modified, it is accessed at least twice for
            // reading and writing. Use the OPC_CACHE_ON_ACCESS flag to reduce
            // overhead incurred by accessing a package component (in this case, a
            // part) multiple times.
    
            // Read the package into a package object.
            // Note: A stream used to read a package is active for the lifetime of
            // the package object into which it is read. 
            hr = factory->ReadPackageFromStream(
                    sourceFileStream, 
                    OPC_CACHE_ON_ACCESS, 
                    outPackage
                    );
        }
    

    The package object keeps a pointer to the stream for the lifetime of the object so that you can access the data from the stream at any time.

  5. Release references and return:

        if (sourceFileStream)
        {
            sourceFileStream->Release();
            sourceFileStream = NULL;
        }
    
        return hr;
    }
    

Calling Your Function

The following example shows how to call your load function:

    IOpcPackage * package = NULL;

C++
    IOpcFactory * factory = NULL;
// Create a new factory.
HRESULT hr = CoCreateInstance(
                __uuidof(OpcFactory),
                NULL,
                CLSCTX_INPROC_SERVER,
                __uuidof(IOpcFactory),
                (LPVOID*)&factory
                );

if (SUCCEEDED(hr))
{
    // Load the package file.
    hr = opclib::LoadPackage(factory, filename, &package);
}</code></pre></td>

Now that you have loaded a package file, you can use the package interface pointer to read from it.

Code Details

Here are the details of the example function in one convenient block:

HRESULT
LoadPackage(
    IOpcFactory *factory,
    LPCWSTR packageName,
    IOpcPackage **outPackage
    )
{
    IStream * sourceFileStream = NULL;

    // Note: Do not use a writable stream to overwrite the data of a package
    // that is read.

    // Create a read-only stream over the package to prevent errors caused by
    // simultaneously writing and reading from a package.
    HRESULT hr = factory->CreateStreamOnFile(
                    packageName, 
                    OPC_STREAM_IO_READ, 
                    NULL, 
                    0, 
                    &amp;sourceFileStream
                    );

    if (SUCCEEDED(hr))
    {
        // Note: If a part is modified, it is accessed at least twice for
        // reading and writing. Use the OPC_CACHE_ON_ACCESS flag to reduce
        // overhead incurred by accessing a package component (in this case, a
        // part) multiple times.

        // Read the package into a package object.
        // Note: A stream used to read a package is active for the lifetime of
        // the package object into which it is read. 
        hr = factory->ReadPackageFromStream(
                sourceFileStream, 
                OPC_CACHE_ON_ACCESS, 
                outPackage
                );
    }

    // Release resources
    if (sourceFileStream)
    {
        sourceFileStream->Release();
        sourceFileStream = NULL;
    }

    return hr;
}

You can find this function in the opclib.cpp file of the Set Author Sample.

Disclaimer

Some code has been omitted. For the complete code, see the Set Author Sample.

Code examples are not intended to be complete and working programs. The code examples that are referenced on this page, for example, do not perform parameter checking, error checking, or error handling. Use these examples as a starting point, and then add the code necessary to create a robust application. For more information about error handling in COM, see the Error Handling (COM) topic.

Packages How-To Topics

Overviews

Getting Started with the Packaging API

Packages Overview

Reference

IOpcFactory

IOpcFactory::CreateStreamOnFile

IOpcFactory::ReadPackageFromStream

IStream

IStream::Clone

Packaging API Reference

Samples

Packaging API Samples

Set Author Sample

Set Author opclib.h

Set Author opclib.cpp