Nice-agent-recv()

We just got a new issue:

From the API docs

https://libnice.freedesktop.org/libnice/NiceAgent.html#nice-agent-recv

gsize buf_len seems to be not an out parameter. And indeed the user expects not an out parameter for that.

From gir we have

~/gintrotest/tests $ grep -A64 "<method name=\"recv\"" /opt/gtk/share/gir-1.0/Nice-0.1.gir 
      <method name="recv"
              c:identifier="nice_agent_recv"
              version="0.1.5"
              throws="1">
        <doc xml:space="preserve"
             filename="../agent/agent.h"
             line="995">A single-message version of nice_agent_recv_messages().</doc>
        <source-position filename="../agent/agent.h" line="1016"/>
        <return-value transfer-ownership="none">
          <doc xml:space="preserve"
               filename="../agent/agent.h"
               line="1009">the number of bytes written to @buf on success (guaranteed to be
greater than 0 unless @buf_len is 0), 0 if in reliable mode and the remote
peer closed the stream, or -1 on error</doc>
          <type name="gssize" c:type="gssize"/>
        </return-value>
        <parameters>
          <instance-parameter name="agent" transfer-ownership="none">
            <doc xml:space="preserve"
                 filename="../agent/agent.h"
                 line="997">a #NiceAgent</doc>
            <type name="Agent" c:type="NiceAgent*"/>
          </instance-parameter>
          <parameter name="stream_id" transfer-ownership="none">
            <doc xml:space="preserve"
                 filename="../agent/agent.h"
                 line="998">the ID of the stream to receive on</doc>
            <type name="guint" c:type="guint"/>
          </parameter>
          <parameter name="component_id" transfer-ownership="none">
            <doc xml:space="preserve"
                 filename="../agent/agent.h"
                 line="999">the ID of the component to receive on</doc>
            <type name="guint" c:type="guint"/>
          </parameter>
          <parameter name="buf"
                     direction="out"
                     caller-allocates="1"
                     transfer-ownership="none">
            <doc xml:space="preserve"
                 filename="../agent/agent.h"
                 line="1000">caller-allocated buffer
to write the received data into, of length at least @buf_len</doc>
            <array length="3" zero-terminated="0" c:type="guint8*">
              <type name="guint8" c:type="guint8"/>
            </array>
          </parameter>
          <parameter name="buf_len"
                     direction="out"
                     caller-allocates="0"
                     transfer-ownership="full">
            <doc xml:space="preserve"
                 filename="../agent/agent.h"
                 line="1002">length of @buf</doc>
            <type name="gsize" c:type="gsize"/>
          </parameter>

with <parameter name=“buf_len” direction=“out”

The Nim wrapper generator generates

$ grep -A14 nice_agent_recv nim_gi/nice.nim 
proc nice_agent_recv(self: ptr Agent00; streamId: uint32; componentId: uint32;
    buf: ptr uint8; bufLen: var uint64; cancellable: ptr gio.Cancellable00;
    error: ptr ptr glib.Error = nil): int64 {.
    importc, libprag.}

proc recv*(self: Agent; streamId: int; componentId: int; buf: var (seq[uint8] | string);
    bufLen: var uint64; cancellable: gio.Cancellable = nil): int64 =
  var gerror: ptr glib.Error
  let resul0 = nice_agent_recv(cast[ptr Agent00](self.impl), uint32(streamId), uint32(componentId), cast[ptr uint8](unsafeaddr(buf[0])), bufLen, if cancellable.isNil: nil else: cast[ptr gio.Cancellable00](cancellable.impl), addr gerror)
  if gerror != nil:
    let msg = $gerror.message
    g_error_free(gerror[])
    raise newException(GException, msg)
  result = resul0

So bufLen: var uint64; is generated on a 64 bit system. Var annotation is used in Wirthian languages to annotate out or inout parameters.

My assumption would be that the out annotation in the gir file is wrong?

The issue is that the buf argument is an (out, caller allocates) argument for an array of length buf_len, and this throws the generator in for a loop; out arguments for arrays usually have out arguments for the length of the array.

It should be the case of explicitly annotating buf_len as (in), in order to restore the semantics of the function: you pass the length of the buffer alongside the buffer, and the callee will fill the buffer out. The parser could also not apply the same direction of the array argument to the length argument.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.