Chromium Embedded Framework (CEF) Translator Tool -- translator.py
-------------------------------------------------------------------------------

Document Last Updated: February 14, 2012


OVERVIEW
--------

The CEF translator tool automatically generates CEF source code based on the
contents of the CEF header file (cef.h). The generated source code includes the
main C API header file (cef_capi.h) and all files in the libcef_dll/cpptoc and
libcef_dll/ctocpp directories.

If any differences are detected between the new translator-generated output and
the file that currently exists on disk a backup of the existing file will be
created before the new file is written (this behavior can be controlled using
a command-line switch -- see 'translator.py -h' for more information). Header
files (*.h) are completely generated by the translator and should never be
edited by hand. Implementation files (*.cc) may contain user-created content
within method and function body blocks. The user-created content is extracted
from the existing file and inserted into the new translator-generated file. Any
differences between existing method/function prototypes and new method/function
prototypes in manually edited implementations will be noted as a warning in new
output file.

   // WARNING - CHANGED ATTRIBUTES
   //   REMOVED: const wchar_t* key
   //   ADDED:   int index
   // WARNING - CHANGED RETURN VALUE
   //   WAS: void
   //   NOW: int
   #pragma message("Warning: "__FILE__": MyFunction prototype has changed")

Auto-generated implementations will be added in the new output file for any
methods/functions that exist in the CEF header file but did not exist in the
current on-disk implementation file. Each time the translator re-generates the
implementation file it will warn if an implementation could not be auto-
generated. Delete the indicated portion of the generated code after adding the
implementation manually.

   size_t CEF_CALLBACK frame_new_func(struct _cef_frame_t* self)
   {
     // BEGIN DELETE BEFORE MODIFYING
     // AUTO-GENERATED CONTENT
     #pragma message("Warning: "__FILE__": frame_new_func is not implemented")
     // END DELETE BEFORE MODIFYING
   }

If the complete function or method implementation has been auto-generated the
body of the function or method will contain the following comment.

   // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

If you edit the implementation manually you should remove this comment so that
CEF will not discard your changes on the next run of the translator tool.

The 'translator.[bat|sh]' file can be used to run the translator tool with
command- line arguments that match the default CEF directory structure and
output options. Run 'translator.py -h' for a complete list of available command-
line arguments.


HEADER ATTRIBUTES
-----------------

Comment-based attribute tags are added before each function, class and method
definition in the CEF header file to provide the translator with additional
information about how the output should be generated. The attribute tags must
be in the form of a comma-delimited list of name=value pairs. Attribute names
and values must contain only alpha-numeric characters, numbers and underscores,
and must all exist on a single line.

   /*--cef(name1=value1,name2=value2,name3=value3)--*/

Supported method/function attributes:

   capi_name=[string]      (Optional) Force a specific output name for the
                           resulting C API function.
   optional_param=[param]  (Optional) Parameter name that will be optional
                           instead of required.
   index_param=[param]     (Optional) Parameter name representing an index
                           value that will be verified as >= 0.
   default_retval=[string] (Required for enumeration types, Optional for other
                           types) Specify the default return value.
   count_func=[param:func] (Required for non-const non-string std::vector
                           types) Specify the C++ function that returns the
                           count of elements for a vector parameter.
   api_hash_check          (Optional) If set an API hash check will be added
                           to the CToCpp version of the method/function.
   
Supported class attributes:

   source=[library|client] (Required) Indicates whether the class
                           implementation is provided by the library or the
                           client. This effects the generation of guard
                           blocks in the cpptoc and ctocpp header files.
   no_debugct_check       (Optional) If set the debug reference count
                           of the object will not be checked on shutdown.


TRANSLATION RULES
-----------------

All C++ names in the CEF header file are written in CamelCaps format and all
C API translations are generated in lowercase_underscore format.


Translating Classes and Methods
-------------------------------

Class names and global function names must be prefixed with the 'Cef' string.

   Global function translation
      C++:   void CefShutdown()
      C API: void cef_shutdown()

The translation of a C++ class name to a C API structure name is prefixed with
'_' and postfixed with '_t'.  A typedef of the C API structure to a value
without the prefixed '_' is also provided and may be used interchangeably.

   Class name translation
      C++:   class CefPostData
      C API: typedef struct _cef_post_data_t { ... } cef_post_data_t

The translation of a C++ virtual class method to a C API member function adds a
'self' structure pointer as the first parameter. This will always be a pointer
to the structure that contains the member function.

   Virtual method translation
      C++:   virtual void SetFocus(bool enable)
      C API: void set_focus(struct _cef_browser_t* self, int enable)

The translation of a C++ static class method to a C API global function
is prefixed with 'cef_classname_' where 'classname' is the
lowercase_underscore name of the class that contains the static method.  Any
repeat of 'classname' in the function name is removed.

   Static method translation
      C++:   static CefRefPtr<CefRequest> CreateRequest()
      C API: struct _cef_request_t* cef_request_create()

Implementation of the wrapper method/function body is generally formatted as
follows.

   Static/Global CppToC (without Return):

      CEF_EXPORT void cef_function(capi_params)
      {
        // Parameter Verification (Optional)
        // Verify the C parameter values.
        // ...

        // Parameter Translation (Optional)
        // Convert C parameter values to C++ parameter values.
        // ...

        // Execution
        CefFunction(cpp_arams);
        
        // Parameter Restoration (Optional)
        // Retore the C parameter values if changed.
        // ...
      }
   
   Static/Global CppToC (with Return):

      CEF_EXPORT capi_retval cef_function(capi_params)
      {
        // Parameter Verification (Optional)
        // Verify the C parameter values.
        // ...

        // Parameter Translation (Optional)
        // Convert C parameter values to C++ parameter values.
        // ...

        // Execution
        cpp_retval _rv = CefFunction(cpp_params);
        
        // Parameter Restoration (Optional)
        // Restore the C parameter values if changed.
        // ...
        
        // Return Translation
        // Convert the C++ return value to a C return value.
        return ...;
      }
   
   Static/Global CToCpp (without Return):
   
      void CefFunction(cpp_params)
      {
        // Parameter Verification (Optional)
        // Verify the C++ parameter values.
        // ...

        // Parameter Translation (Optional)
        // Convert C++ parameter values to C parameter values.
        // ...
        
        // Execution
        cef_function(capi_params);
        
        // Parameter Restoration (Optional)
        // Restore the C++ parameter values if changed.
        // ...
      }
   
   Static/Global CToCpp (with Return):
   
      cpp_retval CefFunction(cpp_params)
      {
        // Parameter Verification (Optional)
        // Verify the C++ parameter values.
        // ...

        // Parameter Translation (Optional)
        // Convert C++ parameter values to C parameter values.
        // ...
        
        // Execution
        capi_retval _rv = cef_function(capi_params);
        
        // Parameter Restoration (Optional)
        // Restore the C++ parameter values if changed.
        // ...
        
        // Return Translation
        // Convert the C return value to a C++ return value.
        return ...;
      }
   
   Member CppToC (without Return):
   
      CEF_CALLBACK void class_function(cef_class_t* self, capi_params)
      {
        // Parameter Verification.
        // Verify the C parameter values.
        DCHECK(self);
        DCHECK(...);
        if (!self || ...)
          return;
          
        // Parameter Translation (Optional)
        // Convert the C parameter values to C++ parameter values.
        // ...

        // Execution
        CefClassCppToC::Get(self)->CefFunction(cpp_params);
        
        // Parameter Restoration (Optional)
        // Restore the C parameter values if changed.
        // ...
      }

   Member CppToC (with Return):
   
      CEF_CALLBACK capi_retval class_function(cef_class_t* self, capi_params)
      {
        // Parameter Verification.
        // Verify the C parameter values.
        DCHECK(self);
        DCHECK(...);
        if (!self || ...)
          return default_retval; // Configured or defaulted automatically.
          
        // Parameter Translation (Optional)
        // Convert the C parameter values to C++ parameter values.
        // ...

        // Execution
        cpp_retval _rv = CefClassCppToC::Get(self)->CefFunction(cpp_params);
        
        // Parameter Restoration (Optional)
        // Restore the C parameter values if changed.
        // ...
        
        // Return Translation
        // Convert the C++ return value to a C return value.
        return ...;
      }

   Member CToCpp (without Return):

      void CefClassCToCpp::Function(cpp_params)
      {
        // Structure Verification
        if (CEF_MEMBER_MISSING(struct_, function))
          return;

        // Parameter Verification (Optional)
        // Verify the C++ parameter values.
        // ...

        // Parameter Translation (Optional)
        // Convert C++ parameter values to C parameter values.
        // ...
        
        // Execution
        struct_->class_function(struct_, capi_params);
        
        // Parameter Restoration (Optional)
        // Restore the C++ parameter values if changed.
        // ...
      }

   Member CToCpp (with Return):

      cpp_retval CefClassCToCpp::Function(cpp_params)
      {
        // Structure Verification
        if (CEF_MEMBER_MISSING(struct_, function))
          return default_retval; // Configured or defaulted automatically.

        // Parameter Verification (Optional)
        // Verify the C++ parameter values.
        // ...

        // Parameter Translation (Optional)
        // Convert C++ parameter values to C parameter values.
        // ...
        
        // Execution
        capi_retval _rv = struct_->class_function(struct_, capi_params);
        
        // Parameter Restoration (Optional)
        // Restore the C++ parameter values if changed.
        // ...
        
        // Return Translation
        // Convert the C return value to a C++ return value.
        return ...;
      }
   

Translating Data Types
----------------------

Data types that are available in both C++ and C are left unchanged. This
includes the 'double', 'int', 'long', 'size_t' and 'void' basic types. Other
data types have differing levels of support as indicated below. The translation
tool will terminate with an exception if it encounters a data type that it
cannot translate.

Parameters:

   Simple/enumeration type by value (simple_byval):
      C++:   int value
      C API: int value

      // CppToC Example
      CEF_EXPORT void cef_function(int value)
      {
        // Execution
        CefFunction(value);
      }

      // CToCpp Example
      void CefFunction(int value)
      {
        // Execution
        cef_function(value);
      }

   Simple/enumeration type by reference (simple_byref):
      C++:   int& value
      C API: int* value

      // CppToC Example
      CEF_EXPORT void cef_function(int* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Parameter Translation
        int valueVal = value?*value:0;
          
        // Execution
        CefFunction(valueVal);
        
        // Parameter Restoration
        if (value)
          *value = valueVal;
      }

      // CToCpp Example
      void CefFunction(int& value)
      {
        // Execution
        cef_function(&value);
      }

   Simple/enumeration const type by reference (simple_byref_const):
      C++:   const int& value
      C API: const int* value

      // CppToC Example
      CEF_EXPORT void cef_function(const int* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Parameter Translation
        int valueVal = value?*value:0;
          
        // Execution
        CefFunction(valueVal);
      }

      // CToCpp Example
      void CefFunction(const int& value)
      {
        // Execution
        cef_function(&value);
      }

   Simple/enumeration type by address (simple_byaddr):
      C++:   int* value
      C API: int* value

      // CppToC Example
      CEF_EXPORT void cef_function(int* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Execution
        CefFunction(value);
      }

      // CToCpp Example
      void CefFunction(int* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Execution
        cef_function(value);
      }

   Boolean type by value (bool_byval):
      C++:   bool value
      C API: int value

      // CppToC Example
      CEF_EXPORT void cef_function(int value)
      {
        // Execution
        CefFunction(value?true:false);
      }

      // CToCpp Example
      void CefFunction(bool value)
      {
        // Execution
        cef_function(value);
      }

   Boolean type by reference (bool_byref):
      C++:   bool& value
      C API: int* value

      // CppToC Example
      CEF_EXPORT void cef_function(int* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Parameter Translation
        bool valueBool = (value && *value)?true:false;
          
        // Execution
        CefFunction(valueBool);
        
        // Parameter Restoration
        if (value)
          *value = valueBool?true:false;
      }

      // CToCpp Example
      void CefFunction(bool& value)
      {
        // Parameter Translation
        int valueInt = value;

        // Execution
        cef_function(&valueInt);
        
        // Parameter Restoration
        value = valueInt?true:false;
      }

   Boolean type by address (bool_byaddr):
      C++:   bool* value
      C API: int* value

      // CppToC Example
      CEF_EXPORT void cef_function(int* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Parameter Translation
        bool valueBool = (value && *value)?true:false;
          
        // Execution
        CefFunction(&valueBool);
        
        // Parameter Restoration
        if (value)
          *value = valueBool?true:false;
      }

      // CToCpp Example
      void CefFunction(bool* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Parameter Translation
        int valueInt = value?*value:0;

        // Execution
        cef_function(&valueInt);
        
        // Parameter Restoration
        if (value)
          *value = valueInt?true:false;
      }

   Structure const type by reference (struct_byref_const):
      C++:   const CefPopupFeatures& value
      C API: const cef_popup_features_t* value

      // CppToC Example
      CEF_EXPORT void cef_function(const cef_popup_features_t* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;
          
        // Parameter Translation
        CefPopupFeatures valueObj;
        // Reference the existing values instead of copying.
        if (value)
          valueObj.Set(*value, false);
          
        // Execution
        CefFunction(valueObj);
      }

      // CToCpp Example
      void CefFunction(const CefPopupFeatures& value)
      {
        // Execution
        cef_function(&value);
      }

   Structure non-const type by reference (struct_byref):
      C++:   CefWindowInfo& value
      C API: cef_window_info_t* value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_window_info_t* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        CefWindowInfo valueObj;
        // Take ownership of the values.
        if (value)
          valueObj.AttachTo(*value);

        // Execution
        CefFunction(valueObj);

        // Parameter Restoration
        // Return the values to the structure.
        if (value)
          valueObj.DetachTo(*value);
      }

      // CToCpp Example
      void CefFunction(CefWindowInfo& value)
      {
        // Execution
        cef_function(&value);
      }
      
   String const type by reference (string_byref_const):
      C++:   const CefString& value
      C API: const cef_string_t* value

      // CppToC Example
      CEF_EXPORT void cef_function(const cef_string_t* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Execution
        CefFunction(CefString(value));
      }

      // CToCpp Example
      void CefFunction(const CefString& value)
      {
        // Execution
        cef_function(value.GetStruct());
      }

   String non-const type by reference (string_byref):
      C++:   CefString& value
      C API: cef_string_t* value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_string_t* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        CefString valueStr(value);

        // Execution
        CefFunction(valueStr);
      }

      // CToCpp Example
      void CefFunction(CefString& value)
      {
        // Execution
        cef_function(value.GetWritableStruct());
      }

   Smart pointer type same boundary side (refptr_same):
      C++:   CefRefPtr<CefBrowser> value
      C API: cef_browser_t* value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_browser_t* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Execution
        CefFunction(CefBrowserCppToC::Unwrap(value));
      }

      // CToCpp Example
      void CefFunction(CefRefPtr<CefBrowser> value)
      {
        // Execution
        cef_function(CefBrowserCToCpp::Unwrap(value));
      }

   Smart pointer type same boundary side by reference (refptr_same_byref):
      C++:   CefRefPtr<CefClient>& value
      C API: cef_client_t** value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_client_t** value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        CefRefPtr<CefClient> valuePtr;
        if (value && *value)
          valuePtr = CefClientCppToC::Unwrap(*value);
        CefClient* valueOrig = valuePtr.get();

        // Execution
        CefFunction(valuePtr);

        // Parameter Restoration
        if (value) {
          if (valuePtr.get()) {
            if (valuePtr.get() != valueOrig) {
              // The value has been changed.
              *value = CefClientCppToC::Wrap(valuePtr);
            }
          } else {
            *value = NULL;
          }
        }
      }

      // CToCpp Example
      void CefFunction(CefRefPtr<CefClient>& value)
      {
        // Parameter Translation
        cef_client_t* valueStruct = NULL;
        if(value.get())
          valueStruct = CefClientCToCpp::Unwrap(value);
        cef_client_t* valueOrig = valueStruct;

        // Execution
        cef_function(valueStuct);
        
        // Parameter Restoration
        if (valueStruct) {
          if (valueStruct != valueOrig) {
            // The value was changed.
            value = CefClientCToCpp::Wrap(valueStruct);
          }
        } else {
          value = NULL;
        }
      }

   Smart pointer type different boundary side (refptr_diff):
      C++:   CefRefPtr<CefBrowser> value
      C API: cef_browser_t* value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_browser_t* value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Execution
        CefFunction(CefBrowserCToCpp::Wrap(value));
      }

      // CToCpp Example
      void CefFunction(CefRefPtr<CefBrowser> value)
      {
        // Execution
        cef_function(CefBrowserCppToC::Wrap(value));
      }

   Smart pointer type different boundary side by reference (refptr_diff_byref):
      C++:   CefRefPtr<CefClient>& value
      C API: cef_client_t** value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_client_t** value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        CefRefPtr<CefClient> valuePtr;
        if (value && *value)
          valuePtr = CefClientCToCpp::Wrap(*value);
        CefClient* valueOrig = valuePtr.get();

        // Execution
        CefFunction(valuePtr);

        // Parameter Restoration
        if (value) {
          if (valuePtr.get()) {
            if (valuePtr.get() != valueOrig) {
              // The value has been changed.
              *value = CefClientCToCpp::Unwrap(valuePtr);
            }
          } else {
            *value = NULL;
          }
        }
      }

      // CToCpp Example
      void CefFunction(CefRefPtr<CefClient>& value)
      {
        // Parameter Translation
        cef_client_t* valueStruct = NULL;
        if(value.get())
          valueStruct = CefClientCppToC::Wrap(value);
        cef_client_t* valueOrig = valueStruct;

        // Execution
        cef_function(valueStuct);
        
        // Parameter Restoration
        if (valueStruct) {
          if (valueStruct != valueOrig) {
            // The value was changed.
            value = CefClientCppToC::Unwrap(valueStruct);
          }
        } else {
          value = NULL;
        }
      }

   String vector type by reference (string_vec_byref):
      C++:   std::vector<CefString>& value
      C API: cef_string_list_t value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_string_list_t value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        std::vector<CefString> valueList;
        transfer_string_list_contents(value, valueList);

        // Execution
        CefFunction(valueList);
        
        // Parameter Restoration
        cef_string_list_clear(value);
        transfer_string_list_contents(valueList, value);
      }

      // CToCpp Example
      void CefFunction(std::vector<CefString>& value)
      {
        // Parameter Translation
        cef_string_list_t valueList = cef_string_list_alloc();
        DCHECK(valueList);
        if (valueList)
          transfer_string_list_contents(value, valueList);

        // Execution
        cef_function(valueList);
        
        // Parameter Restoration
        if (valueList) {
          value.clear();
          transfer_string_list_contents(valueList, value);
          cef_string_list_free(valueList);
        }
      }

   String vector const type by reference (string_vec_byref_const):
      C++:   const std::vector<CefString>& value
      C API: cef_string_list_t value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_string_list_t value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        std::vector<CefString> valueList;
        transfer_string_list_contents(value, valueList);

        // Execution
        CefFunction(valueList);
      }

      // CToCpp Example
      void CefFunction(const std::vector<CefString>& value)
      {
        // Parameter Translation
        cef_string_list_t valueList = cef_string_list_alloc();
        DCHECK(valueList);
        if (valueList)
          transfer_string_list_contents(value, valueList);

        // Execution
        cef_function(valueList);
        
        // Parameter Restoration
        if (valueList)
          cef_string_list_free(valueList);
      }

   String-to-string single map type by reference (string_map_single_byref):
      C++:   std::map<CefString,CefString>& value
      C API: cef_string_map_t value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_string_map_t value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        std::map<CefString,CefString> valueMap;
        transfer_string_map_contents(value, valueMap);

        // Execution
        CefFunction(valueMap);
        
        // Parameter Restoration
        cef_string_map_clear(value);
        transfer_string_map_contents(valueMap, value);
      }

      // CToCpp Example
      void CefFunction(std::map<CefString,CefString>& value)
      {
        // Parameter Translation
        cef_string_map_t valueMap = cef_string_map_alloc();
        DCHECK(valueMap);
        if (valueMap)
          transfer_string_map_contents(value, valueMap);

        // Execution
        cef_function(valueMap);
        
        // Parameter Restoration
        if (valueMap) {
          value.clear();
          transfer_string_map_contents(valueMap, value);
          cef_string_map_free(valueMap);
        }
      }

   String-to-string single map const type by reference
     (string_map_single_byref_const):
      C++:   const std::map<CefString,CefString>& value
      C API: cef_string_map_t value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_string_map_t value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        std::map<CefString,CefString> valueMap;
        transfer_string_map_contents(value, valueMap);

        // Execution
        CefFunction(valueMap);
      }

      // CToCpp Example
      void CefFunction(const std::map<CefString,CefString>& value)
      {
        // Parameter Translation
        cef_string_map_t valueMap = cef_string_map_alloc();
        DCHECK(valueMap);
        if (valueMap)
          transfer_string_map_contents(value, valueMap);

        // Execution
        cef_function(valueMap);
        
        // Parameter Restoration
        if (valueMap)
          cef_string_map_free(valueMap);
      }

   String-to-string multi map type by reference (string_map_multi_byref):
      C++:   std::multimap<CefString,CefString>& value
      C API: cef_string_multimap_t value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_string_multimap_t value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        std::multimap<CefString,CefString> valueMultimap;
        transfer_string_multimap_contents(value, valueMultimap);

        // Execution
        CefFunction(valueMultimap);
        
        // Parameter Restoration
        cef_string_multimap_clear(value);
        transfer_string_multimap_contents(valueMultimap, value);
      }

      // CToCpp Example
      void CefFunction(std::multimap<CefString,CefString>& value)
      {
        // Parameter Translation
        cef_string_multimap_t valueMultimap = cef_string_multimap_alloc();
        DCHECK(valueMultimap);
        if (valueMultimap)
          transfer_string_multimap_contents(value, valueMultimap);

        // Execution
        cef_function(valueMultimap);
        
        // Parameter Restoration
        if (valueMultimap) {
          value.clear();
          transfer_string_multimap_contents(valueMultimap, value);
          cef_string_multimap_free(valueMultimap);
        }
      }
   
   String-to-string multi map const type by reference
   (string_map_multi_byref_const):
      C++:   const std::multimap<CefString,CefString>& value
      C API: cef_string_multimap_t value

      // CppToC Example
      CEF_EXPORT void cef_function(cef_string_multimap_t value)
      {
        // Parameter Verification
        DHECK(value);
        if (!value)
          return;

        // Parameter Translation
        std::multimap<CefString,CefString> valueMultimap;
        transfer_string_multimap_contents(value, valueMultimap);

        // Execution
        CefFunction(valueMultimap);
      }

      // CToCpp Example
      void CefFunction(const std::multimap<CefString,CefString>& value)
      {
        // Parameter Translation
        cef_string_multimap_t valueMultimap = cef_string_multimap_alloc();
        DCHECK(valueMultimap);
        if (valueMultimap)
          transfer_string_multimap_contents(value, valueMultimap);

        // Execution
        cef_function(valueMultimap);
        
        // Parameter Restoration
        if (valueMultimap)
          cef_string_multimap_free(valueMultimap);
      }
   
   Simple/Enumeration vector non-const type by reference (simple_vec_byref):
      C++:   std::vector<int>& value
      C API: size_t* valueCount, int* value

      // CppToC Example
      CEF_EXPORT void cef_function(size_t* valueCount, int* value)
      {
        // Parameter Verification
        DCHECK(valueCount && (*valueCount == 0 || value));
        if (!valueCount || (*valueCount > 0 && !value))
          return;
        
        // Parameter Translation
        std::vector<int> valueList;
        if (valueCount && *valueCount > 0 && value) {
          for (size_t i = 0; i < *valueCount; ++i)
            valueList.push_back(value[i]);
        }
        
        // Execution
        CefFunction(valueList);
        
        // Parameter Restoration
        if (valueCount && value) {
          *valueCount = std::min(valueList.size(), *valueCount);
          if (*valueCount > 0) {
            for (size_t i = 0; i < *valueCount; ++i)
              value[i] = valueList[i];
          }
        }
      }

      // CToCpp Example
      void CefFunction(std::vector<int>& value)
      {
        // Parameter Translation
        // Function identified by the "count_func" method attribute.
        size_t valueSize = value.size();
        size_t valueCount = std::max(GetFunctionCount(), valueSize);
        int* valueList = NULL;
        if (valueCount > 0) {
          valueList = new int[valueCount];
          DCHECK(valueList);
          if (valueList)
            memset(valueList, 0, sizeof(int)*valueCount);
          if (valueList && valueSize > 0) {
            for (size_t i = 0; i < valueSize; ++i) {
              valueList[i] = value[i];
            }
          }
        }

        // Execution
        cef_function(&valueCount, valueList);
        
        // Parameter Restoration
        value.clear();
        if (valueCount > 0 && valueList) {
          for (size_t i = 0; i < valueCount; ++i)
            value.push_back(valueList[i]);
          delete [] valueList;
        }
      }

   Simple/Enumeration vector const type by reference (simple_vec_byref_const):
      C++:   const std::vector<int>& value
      C API: size_t valueCount, int const* value

      // CppToC Example
      CEF_EXPORT void cef_function(size_t valueCount, int const* value)
      {
        // Parameter Verification
        DCHECK(valueCount == 0 || value);
        if (valueCount > 0 && !value)
          return;
        
        // Parameter Translation
        std::vector<int> valueList;
        if (valueCount > 0) {
          for (size_t i = 0; i < valueCount; ++i)
            valueList.push_back(value[i]);
        }

        // Execution
        CefFunction(valueList);
      }

      // CToCpp Example
      void CefFunction(const std::vector<int>& value)
      {
        // Parameter Translation
        const size_t valueCount = value.size();
        int* valueList = NULL;
        if (valueCount > 0) {
          valueList = new int[valueCount];
          DCHECK(valueList);
          if (valueList) {
            for (size_t i = 0; i < valueCount; ++i)
              valueList[i] = value[i];
          }
        }
        
        // Execution
        cef_function(valueCount, valueList);

        // Parameter Restoration
        if (valueList)
          delete [] valueList;
      }

   Boolean vector non-const type by reference (bool_vec_byref):
      C++:   std::vector<bool>& value
      C API: size_t* valueCount, int* value
      
      // CppToC Example
      CEF_EXPORT void cef_function(size_t* valueCount, int* value)
      {
        // Parameter Verification
        DCHECK(valueCount && (*valueCount == 0 || value));
        if (!valueCount || (*valueCount > 0 && !value))
          return;
        
        // Parameter Translation
        std::vector<bool> valueList;
        if (valueCount && *valueCount > 0 && value) {
          for (size_t i = 0; i < *valueCount; ++i)
            valueList.push_back(value[i]?true:false);
        }
        
        // Execution
        CefFunction(valueList);
        
        // Parameter Restoration
        if (valueCount && value) {
          *valueCount = std::min(valueList.size(), *valueCount);
          if (*valueCount > 0) {
            for (size_t i = 0; i < *valueCount; ++i)
              value[i] = valueList[i];
          }
        }
      }

      // CToCpp Example
      void CefFunction(std::vector<bool>& value)
      {
        // Parameter Translation
        // Function identified by the "count_func" method attribute.
        size_t valueSize = value.size();
        size_t valueCount = std::max(GetFunctionCount(), valueSize);
        int* valueList = NULL;
        if (valueCount > 0) {
          valueList = new int[valueCount];
          DCHECK(valueList);
          if (valueList)
            memset(valueList, 0, sizeof(int)*valueCount);
          if (valueList && valueSize > 0) {
            for (size_t i = 0; i < valueSize; ++i) {
              valueList[i] = value[i];
            }
          }
        }

        // Execution
        cef_function(&valueCount, valueList);
        
        // Parameter Restoration
        value.clear();
        if (valueCount > 0 && valueList) {
          for (size_t i = 0; i < valueCount; ++i)
            value.push_back(valueList[i]?true:false);
          delete [] valueList;
        }
      }

   Boolean vector const type by reference (bool_vec_byref_const):
      C++:   const std::vector<bool>& value
      C API: size_t valueCount, int const* value
      
      // CppToC Example
      CEF_EXPORT void cef_function(size_t valueCount, int const* value)
      {
        // Parameter Verification
        DCHECK(valueCount == 0 || value);
        if (valueCount > 0 && !value)
          return;
        
        // Parameter Translation
        std::vector<bool> valueList;
        if (valueCount > 0) {
          for (size_t i = 0; i < valueCount; ++i)
            valueList.push_back(value[i]?true:false);
        }

        // Execution
        CefFunction(valueList);
      }

      // CToCpp Example
      void CefFunction(const std::vector<bool>& value)
      {
        // Parameter Translation
        const size_t valueCount = value.size();
        int* valueList = NULL;
        if (valueCount > 0) {
          valueList = new int[valueCount];
          DCHECK(valueList)
          if (valueList) {
            for (size_t i = 0; i < valueCount; ++i)
              valueList[i] = value[i];
          }
        }
        
        // Execution
        cef_function(valueCount, valueList);

        // Parameter Restoration
        if (valueList)
          delete [] valueList;
      }

   Smart pointer vector non-const type same boundary side by reference
      (refptr_vec_same_byref):
      C++:   std::vector<CefRefPtr<CefPostDataElement>>& value
      C API: size_t* valueCount, cef_post_data_element_t** value
      
      // CppToC Example
      CEF_EXPORT void cef_function(size_t* valueCount,
                                   cef_post_data_element_t** value)
      {
        // Parameter Verification
        DCHECK(valueCount && (*valueCount == 0 || value));
        if (!valueCount || (*valueCount > 0 && !value))
          return;
        
        // Parameter Translation
        std::vector<CefRefPtr<CefPostDataElement>> valueList;
        if (valueCount && *valueCount > 0 && value) {
          for (size_t i = 0; i < *valueCount; ++i)
            valueList.push_back(CefPostDataElementCppToC::Unwrap(value[i]));
        }
        
        // Execution
        CefFunction(valueList);
        
        // Parameter Restoration
        if (valueCount && value) {
          *valueCount = std::min(valueList.size(), *valueCount);
          if (*valueCount > 0) {
            for (size_t i = 0; i < *valueCount; ++i)
              value[i] = CefPostDataElementCppToC::Wrap(valueList[i]);
          }
        }
      }

      // CToCpp Example
      void CefFunction(std::vector<bool>& value)
      {
        // Parameter Translation
        // Function identified by the "count_func" method attribute.
        size_t valueSize = value.size();
        size_t valueCount = std::max(GetFunctionCount(), valueSize);
        cef_post_data_element_t** valueList = NULL;
        if (valueCount > 0) {
          valueList = new cef_post_data_element_t*[valueCount];
          DCHECK(valueList);
          if (valueList)
            memset(valueList, 0, sizeof(cef_post_data_element_t*)*valueCount);
          if (valueList && valueSize > 0) {
            for (size_t i = 0; i < valueSize; ++i) {
              valueList[i] = CefPostDataElementCToCpp::Unwrap(value[i]);
            }
          }
        }

        // Execution
        cef_function(&valueCount, valueList);
        
        // Parameter Restoration
        value.clear();
        if (valueCount > 0 && valueList) {
          for (size_t i = 0; i < valueCount; ++i)
            value.push_back(CefPostDataElementCToCpp::Wrap(valueList[i]));
          delete [] valueList;
        }
      }

   Smart pointer vector const type same boundary side by reference
      (refptr_vec_same_byref_const):
      C++:   const std::vector<CefRefPtr<CefV8Value>>& value
      C API: size_t valueCount, const cef_v8value_t** value
      
      // CppToC Example
      CEF_EXPORT void cef_function(size_t valueCount,
                                   const cef_v8value_t** value)
      {
        // Parameter Verification
        DCHECK(valueCount == 0 || value);
        if (valueCount > 0 && !value)
          return;
        
        // Parameter Translation
        std::vector<CefRefPtr<CefV8Value>> valueList;
        if (valueCount > 0) {
          for (size_t i = 0; i < valueCount; ++i)
            valueList.push_back(CefV8ValueCppToC::Unwrap(value[i]));
        }

        // Execution
        CefFunction(valueList);
      }

      // CToCpp Example
      void CefFunction(const std::vector<bool>& value)
      {
        // Parameter Translation
        const size_t valueCount = value.size();
        cef_v8value_t** valueList = NULL;
        if (valueCount > 0) {
          valueList = new int[valueCount];
          DCHECK(valueList);
          if (valueList) {
            for (size_t i = 0; i < valueCount; ++i)
              valueList[i] = CefV8ValueCToCpp::Unwrap(value[i]);
          }
        }
        
        // Execution
        cef_function(valueCount, valueList);

        // Parameter Restoration
        if (valueList)
          delete [] valueList;
      }

   Smart pointer vector non-const type different boundary side by reference
      (refptr_vec_diff_byref):
      C++:   std::vector<CefRefPtr<CefPostDataElement>>& value
      C API: size_t* valueCount, cef_post_data_element_t** value
      
      // CppToC Example
      CEF_EXPORT void cef_function(size_t* valueCount,
                                   cef_post_data_element_t** value)
      {
        // Parameter Verification
        DCHECK(valueCount && (*valueCount == 0 || value));
        if (!valueCount || (*valueCount > 0 && !value))
          return;
        
        // Parameter Translation
        std::vector<CefRefPtr<CefPostDataElement>> valueList;
        if (valueCount && *valueCount > 0 && value) {
          for (size_t i = 0; i < *valueCount; ++i)
            valueList.push_back(CefPostDataElementCToCpp::Wrap(value[i]));
        }
        
        // Execution
        CefFunction(valueList);
        
        // Parameter Restoration
        if (valueCount && value) {
          *valueCount = std::min(valueList.size(), *valueCount);
          if (*valueCount > 0) {
            for (size_t i = 0; i < *valueCount; ++i)
              value[i] = CefPostDataElementCToCpp::Unwrap(valueList[i]);
          }
        }
      }

      // CToCpp Example
      void CefFunction(std::vector<bool>& value)
      {
        // Parameter Translation
        // Function identified by the "count_func" method attribute.
        size_t valueSize = value.size();
        size_t valueCount = std::max(GetFunctionCount(), valueSize);
        cef_post_data_element_t** valueList = NULL;
        if (valueCount > 0) {
          valueList = new cef_post_data_element_t*[valueCount];
          DCHECK(valueList);
          if (valueList)
            memset(valueList, 0, sizeof(cef_post_data_element_t*)*valueCount);
          if (valueList && valueSize > 0) {
            for (size_t i = 0; i < valueSize; ++i) {
              valueList[i] = CefPostDataElementCppToC::Wrap(value[i]);
            }
          }
        }

        // Execution
        cef_function(&valueCount, valueList);
        
        // Parameter Restoration
        value.clear();
        if (valueCount > 0 && valueList) {
          for (size_t i = 0; i < valueCount; ++i)
            value.push_back(CefPostDataElementCppToC::Unwrap(valueList[i]));
          delete [] valueList;
        }
      }

   Smart pointer vector const type different boundary side by reference
      (refptr_vec_diff_byref_const):
      C++:   const std::vector<CefRefPtr<CefV8Value>>& value
      C API: size_t valueCount, const cef_v8value_t** value
      
      // CppToC Example
      CEF_EXPORT void cef_function(size_t valueCount,
                                   const cef_v8value_t** value)
      {
        // Parameter Verification
        DCHECK(valueCount == 0 || value);
        if (valueCount > 0 && !value)
          return;
        
        // Parameter Translation
        std::vector<CefRefPtr<CefV8Value>> valueList;
        if (valueCount > 0) {
          for (size_t i = 0; i < valueCount; ++i)
            valueList.push_back(CefV8ValueCToCpp::Wrap(value[i]));
        }

        // Execution
        CefFunction(valueList);
      }

      // CToCpp Example
      void CefFunction(const std::vector<bool>& value)
      {
        // Parameter Translation
        const size_t valueCount = value.size();
        cef_v8value_t** valueList = NULL;
        if (valueCount > 0) {
          valueList = new int[valueCount];
          DCHECK(valueList);
          if (valueList) {
            for (size_t i = 0; i < valueCount; ++i)
              valueList[i] = CefV8ValueCppToC::Wrap(value[i]);
          }
        }
        
        // Execution
        cef_function(valueCount, valueList);

        // Parameter Restoration
        if (valueList)
          delete [] valueList;
      }

Return Values:

   Simple/Enumeration type (simple):
      C++:   int
      C API: int

      // CppToC Example
      CEF_EXPORT int cef_function()
      {
        // Execution
        int _rv = CefFunction();
        
        // Return Translation
        return _rv;
      }

      // CToCpp Example
      int CefFunction()
      {
        // Execution
        int _rv = cef_function();
        
        // Return Translation
        return _rv;
      }

   Boolean type (bool):
      C++:   bool
      C API: int

      // CppToC Example
      CEF_EXPORT int cef_function()
      {
        // Execution
        bool _rv = CefFunction();
        
        // Return Translation
        return _rv;
      }

      // CToCpp Example
      bool CefFunction()
      {
        // Execution
        int _rv = cef_function();
        
        // Return Translation
        return _rv?true:false;
      }

   String non-const by reference type (string):
      C++:   CefString
      C API: cef_string_userfree_t

      // CppToC Example
      CEF_EXPORT cef_string_userfree_t cef_function()
      {
        // Execution
        CefString _rv = CefFunction();
        
        // Return Translation
        return _rv.DetachToUserFree();
      }

      // CToCpp Example
      CefString CefFunction()
      {
        // Execution
        cef_string_userfree_t _rv = cef_function();
        
        // Return Translation
        CefString _rvStr;
        _rvStr.AttachToUserFree(_rv);
        return _rvStr;
      }

   Smart pointer type same boundary side (refptr_same):
      C++:   CefRefPtr<CefBrowser>
      C API: cef_browser_t*

      // CppToC Example
      CEF_EXPORT cef_browser_t* cef_function()
      {
        // Execution
        CefRefPtr<CefBrowser> _rv = CefFunction();
        
        // Return Translation
        return CefBrowserCppToC::Wrap(_rv);
      }

      // CToCpp Example
      CefString CefFunction()
      {
        // Execution
        cef_browser_t* _rv = cef_function();
        
        // Return Translation
        return CefBrowserCToCpp::Wrap(_rv);
      }

   Smart pointer type different boundary side (refptr_diff):
      C++:   CefRefPtr<CefBrowser>
      C API: cef_browser_t*

      // CppToC Example
      CEF_EXPORT cef_browser_t* cef_function()
      {
        // Execution
        CefRefPtr<CefBrowser> _rv = CefFunction();
        
        // Return Translation
        return CefBrowserCToCpp::Unwrap(_rv);
      }

      // CToCpp Example
      CefString CefFunction()
      {
        // Execution
        cef_browser_t* _rv = cef_function();
        
        // Return Translation
        return CefBrowserCppToC::Unwrap(_rv);
      }


Translating Comments
--------------------

Comments from the CEF header file are reproduced in the C API header file with
any referenced C++ types and terminology changed to reflect C API types and
terminology.

C++:
// Create a new CefV8Value object of the specified type.  These methods
// should only be called from within the JavaScript context -- either in a
// CefV8Handler::Execute() callback or a CefHandler::HandleJSBinding()
// callback.

C API:
// Create a new cef_v8value_t object of the specified type.  These functions
// should only be called from within the JavaScript context -- either in a
// cef_v8handler_t::execute() callback or a cef_handler_t::handle_jsbinding()
// callback.

Situations where the user is responsible for freeing strings allocated and
returned by the library are also noted by comments in the C API header file.

C API:
   // The resulting string must be freed by calling cef_string_free().

A comment must occur immediately before the function, class or method that it
documents with no extra space in between.  Comments may span multiple lines
but each line must start with the '//' comment identifier.

C++:
   // Set focus for the browser window.  If |enable| is true focus will be set
   // to the window.  Otherwise, focus will be removed.
   /*--cef()--*/
   virtual void SetFocus(bool enable) =0;

If two comments are separated by an empty line it will be assumed that the
higher comment represents a section header and additional space will be added
before it in the translated output.

C++:
   // ARRAY METHODS - These methods are only available on arrays.
   
   // Returns the number of elements in the array.
   /*--cef()--*/
   virtual int GetArrayLength() =0;

Empty lines and lines with the comment identifier but no content are considered
paragraph breaks for the purposes of wrapping the translated text. Any content
indented more than one space is reproduced as-is without content translation
or wrapping.

C++:
// Register a new V8 extension with the specified JavaScript extension code and
// handler. Functions implemented by the handler are prototyped using the
// keyword 'native'. The calling of a native function is restricted to the scope
// in which the prototype of the native function is defined.
//
// Example JavaScript extension code:
//
//   // create the 'example' global object if it doesn't already exist.
//   if (!example)
//     example = {};
