Sends data in the special driver term
          format to the port owner process. This is a fast way to
          deliver term data from a driver. It needs no binary
          conversion, so the port owner process receives data as
          normal Erlang terms. The 
          erl_drv_send_term
          functions can be used for sending to any process
          on the local node.
        
Note
          
Parameter port is not
            an ordinary port handle, but a port handle converted using
            
            driver_mk_port.
         
        Parameter term points to an array of
          ErlDrvTermData with n elements. This array
          contains terms described in the driver term format. Every
          term consists of 1-4 elements in the array. The
          first term has a term type and then arguments.
          Parameter port specifies the sending port.
        Tuples, maps, and lists (except strings, see below)
          are built in reverse polish notation, so that to build a
          tuple, the elements are specified first, and then the tuple
          term, with a count. Likewise for lists and maps.
        
          - 
            A tuple must be specified with the number of elements. (The
              elements precede the ERL_DRV_TUPLE term.) 
- 
            A map must be specified with the number of key-value pairs
              N. The key-value pairs must precede the ERL_DRV_MAP
              in this order: key1,value1,key2,value2,...,keyN,valueN.
              Duplicate keys are not allowed. 
- 
            A list must be specified with the number of elements,
              including the tail, which is the last term preceding
              ERL_DRV_LIST. 
The special term ERL_DRV_STRING_CONS is used to
          "splice" in a string in a list, a string specified this way is
          not a list in itself, but the elements are elements of the
          surrounding list.
        
Term type            Arguments
---------            ---------
ERL_DRV_NIL
ERL_DRV_ATOM         ErlDrvTermData atom (from driver_mk_atom(char *string))
ERL_DRV_INT          ErlDrvSInt integer
ERL_DRV_UINT         ErlDrvUInt integer
ERL_DRV_INT64        ErlDrvSInt64 *integer_ptr
ERL_DRV_UINT64       ErlDrvUInt64 *integer_ptr
ERL_DRV_PORT         ErlDrvTermData port (from driver_mk_port(ErlDrvPort port))
ERL_DRV_BINARY       ErlDrvBinary *bin, ErlDrvUInt len, ErlDrvUInt offset
ERL_DRV_BUF2BINARY   char *buf, ErlDrvUInt len
ERL_DRV_STRING       char *str, int len
ERL_DRV_TUPLE        int sz
ERL_DRV_LIST         int sz
ERL_DRV_PID          ErlDrvTermData pid (from driver_connected(ErlDrvPort port)
                     or driver_caller(ErlDrvPort port))
ERL_DRV_STRING_CONS  char *str, int len
ERL_DRV_FLOAT        double *dbl
ERL_DRV_EXT2TERM     char *buf, ErlDrvUInt len
ERL_DRV_MAP          int szThe unsigned integer data type ErlDrvUInt and the
	  signed integer data type ErlDrvSInt are 64 bits wide
	  on a 64-bit runtime system and 32 bits wide on a 32-bit
	  runtime system. They were introduced in ERTS 5.6
	  and replaced some of the int arguments in the list above.
	The unsigned integer data type ErlDrvUInt64 and the
	  signed integer data type ErlDrvSInt64 are always 64 bits
	  wide. They were introduced in ERTS 5.7.4.
	To build the tuple {tcp, Port, [100 | Binary]}, the
	  following call can be made.
	ErlDrvBinary* bin = ...
ErlDrvPort port = ...
ErlDrvTermData spec[] = {
    ERL_DRV_ATOM, driver_mk_atom("tcp"),
    ERL_DRV_PORT, driver_mk_port(drvport),
        ERL_DRV_INT, 100,
        ERL_DRV_BINARY, bin, 50, 0,
        ERL_DRV_LIST, 2,
    ERL_DRV_TUPLE, 3,
};
erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));    Here bin is a driver binary of length at least 50 and
          drvport is a port handle. Notice that ERL_DRV_LIST
          comes after the elements of the list, likewise
          ERL_DRV_TUPLE.
        The ERL_DRV_STRING_CONS term is a way to construct
          strings. It works differently from how ERL_DRV_STRING
          works. ERL_DRV_STRING_CONS builds a string list in
          reverse order (as opposed to how ERL_DRV_LIST
          works), concatenating the strings added to a list. The tail
          must be specified before ERL_DRV_STRING_CONS.
        ERL_DRV_STRING constructs a string, and ends
          it. (So it is the same as ERL_DRV_NIL followed by
          ERL_DRV_STRING_CONS.)
        /* to send [x, "abc", y] to the port: */
ErlDrvTermData spec[] = {
    ERL_DRV_ATOM, driver_mk_atom("x"),
    ERL_DRV_STRING, (ErlDrvTermData)"abc", 3,
    ERL_DRV_ATOM, driver_mk_atom("y"),
    ERL_DRV_NIL,
    ERL_DRV_LIST, 4
};
erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));    /* to send "abc123" to the port: */
ErlDrvTermData spec[] = {
    ERL_DRV_NIL,        /* with STRING_CONS, the tail comes first */
    ERL_DRV_STRING_CONS, (ErlDrvTermData)"123", 3,
    ERL_DRV_STRING_CONS, (ErlDrvTermData)"abc", 3,
};
erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));    The ERL_DRV_EXT2TERM term type is used for passing a
	  term encoded with the
	  external format,
	  that is, a term that has been encoded by
	  
	  erlang:term_to_binary,
	  erl_interface:ei(3),
	  and so on.
	  For example, if binp is a pointer to an ErlDrvBinary
	  that contains term {17, 4711} encoded with the
	  external format,
	  and you want to wrap it in a two-tuple with the tag my_tag,
	  that is, {my_tag, {17, 4711}}, you can do as follows:
	ErlDrvTermData spec[] = {
        ERL_DRV_ATOM, driver_mk_atom("my_tag"),
        ERL_DRV_EXT2TERM, (ErlDrvTermData) binp->orig_bytes, binp->orig_size
    ERL_DRV_TUPLE, 2,
};
erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));    To build the map #{key1 => 100, key2 => {200, 300}}, the
          following call can be made.
        ErlDrvPort port = ...
ErlDrvTermData spec[] = {
    ERL_DRV_ATOM, driver_mk_atom("key1"),
        ERL_DRV_INT, 100,
    ERL_DRV_ATOM, driver_mk_atom("key2"),
        ERL_DRV_INT, 200,
        ERL_DRV_INT, 300,
    ERL_DRV_TUPLE, 2,
    ERL_DRV_MAP, 2
};
erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0]));    If you want to pass a binary and do not already have the content
          of the binary in an ErlDrvBinary, you can benefit from using
          ERL_DRV_BUF2BINARY instead of creating an ErlDrvBinary
          through 
          driver_alloc_binary and then pass the binary through
          ERL_DRV_BINARY. The runtime system often allocates
          binaries smarter if ERL_DRV_BUF2BINARY is used.
          However, if the content of the binary to pass already resides in
          an ErlDrvBinary, it is normally better to pass the binary using
          ERL_DRV_BINARY and the ErlDrvBinary in question.
        The ERL_DRV_UINT, ERL_DRV_BUF2BINARY, and
          ERL_DRV_EXT2TERM term types were introduced in
          ERTS 5.6.
        This function is thread-safe.