Microsoft Information Protection SDK - File SDK observers

The File SDK contains two observer classes. You can override virtual observer members to handle event callbacks.

When an asynchronous operation completes, the SDK calls the OnXxx() member function that corresponds to the result. Examples are OnLoadSuccess(), OnLoadFailure(), and OnAddEngineSuccess() for mip::FileProfile::Observer.

These examples demonstrate the promise/future pattern. The SDK samples also use this pattern, and you can extend it to implement the desired callback behavior.

File Profile observer implementation

The following example creates a class, ProfileObserver, that derives from mip::FileProfile::Observer. The member functions override the base class to use the future/promise pattern used throughout the samples.

Note

The samples implement only part of the observer class and don't include overrides for the mip::FileEngine related observers.

profile_observer.h

The header defines ProfileObserver, derives it from mip::FileProfile::Observer, then overrides each of the member functions.

class ProfileObserver final : public mip::FileProfile::Observer {
public:
ProfileObserver() { }
  void OnLoadSuccess(const std::shared_ptr<mip::FileProfile>& profile, const std::shared_ptr<void>& context) override;
  void OnLoadFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) override;
  //TODO: Implement mip::FileEngine related observers.
};

profile_observer.cpp

The implementation defines an action to take for each observer member function.

Each member accepts two parameters. The first is a shared pointer to the class that the function handles. ProfileObserver::OnLoadSuccess expects to receive a mip::FileProfile. ProfileObserver::OnAddEngineSuccess expects mip::FileEngine.

The second is a shared pointer to the context. In this implementation, the context is a reference to a std::promise, passed by reference as std::shared_ptr<void>. The first line of the function casts this value to std::promise, then stores it in an object called promise.

Finally, the code makes the future ready by setting promise->set_value() and passing in the mip::FileProfile object.

#include "profile_observer.h"
#include <future>

//Called when FileProfile is successfully loaded
void ProfileObserver::OnLoadSuccess(const std::shared_ptr<mip::FileProfile>& profile, const std::shared_ptr<void>& context) {
  //cast context to promise
  auto promise = 
  std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileProfile>>>(context);
  //set promise value to profile
  promise->set_value(profile);
}

//Called when FileProfile fails to load
void ProfileObserver::OnLoadFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) {
  auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileProfile>>>(context);
  promise->set_exception(error);
}

//TODO: Implement mip::FileEngine related observers.

When you instantiate any SDK class or use a function that performs asynchronous operations, pass the observer implementation to the settings constructor or async function itself. When you instantiate the mip::FileProfile::Settings object, the constructor accepts mip::FileProfile::Observer as one of the parameters. This example shows the custom ProfileObserver, used in a mip::FileProfile::Settings constructor.

FileHandler observer implementation

Similar to the profile observer, mip::FileHandler implements a mip::FileHandler::Observer class for handling asynchronous event notifications during file operations. The implementation is similar to the preceding implementation. The following example partially defines FileHandlerObserver.

file_handler_observer.h

#include "mip/file/file_handler.h"

class FileHandlerObserver final : public mip::FileHandler::Observer {
public:
  void OnCreateFileHandlerSuccess(
      const std::shared_ptr<mip::FileHandler>& fileHandler,
      const std::shared_ptr<void>& context) override;

  void OnCreateFileHandlerFailure(
      const std::exception_ptr& error,
      const std::shared_ptr<void>& context) override;

  //TODO: override remaining member functions inherited from mip::FileHandler::Observer
};

file_handler_observer.cpp

This sample includes only the first two functions, but the remaining functions use a similar pattern to these functions and to ProfileObserver.

#include "file_handler_observer.h"

void FileHandlerObserver::OnCreateFileHandlerSuccess(const std::shared_ptr<mip::FileHandler>& fileHandler, const std::shared_ptr<void>& context) {
    auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileHandler>>>(context);
    promise->set_value(fileHandler);
}

void FileHandlerObserver::OnCreateFileHandlerFailure(const std::exception_ptr& error, const std::shared_ptr<void>& context) {
    auto promise = std::static_pointer_cast<std::promise<std::shared_ptr<mip::FileHandler>>>(context);
    promise->set_exception(error);
}

//TODO: override remaining member functions inherited from mip::FileHandler::Observer

Next steps