• Places
    • Home
    • Graphs
    • Prefixes
  • Admin
    • Users
    • Settings
    • Plugins
    • Statistics
  • CPACK
    • Home
    • List packs
    • Submit pack
  • Repository
    • Load local file
    • Load from HTTP
    • Load from library
    • Remove triples
    • Clear repository
  • Query
    • YASGUI SPARQL Editor
    • Simple Form
    • SWISH Prolog shell
  • Help
    • Documentation
    • Tutorial
    • Roadmap
    • HTTP Services
  • Login

12.9 Foreign access to Prolog IO streams
All Application Manual Name SummaryHelp

  • Documentation
    • Reference manual
      • Foreign Language Interface
        • Foreign access to Prolog IO streams
          • Get IO stream handles
            • PL_get_stream()
            • PL_get_stream_from_blob()
            • PL_acquire_stream()
            • PL_release_stream()
          • Creating an IO stream
          • Interacting with foreign streams
          • Foreign stream error handling
          • Foreign stream encoding
          • Foreign stream line endings
          • Foreign stream position information
          • Support functions for blob save/load
    • Packages

12.9.1 Get IO stream handles

There are several ways to get access to an IO Stream handle, basically get them from Prolog, get access to the standard streams and create a new stream. The standard streams are available as Sinput, Soutput and Serror. Note that these are thread specific. Creating a new stream is discussed with Snew(). Below are the functions to obtain a stream handle from a Prolog term, obtain and release ownership.

int PL_get_stream(term_t t, IOSTREAM **s, int flags)
Get a stream handle from the Prolog term t. Returns TRUE on success and FALSE on failure, by default generating an exception. The flags argument is a bitwise disjunction of these flags:
SIO_INPUT
Get an input stream. If t is a stream pair (see stream_pair/3), return the input channel. If t is an output stream the function fails.
SIO_OUTPUT
Get an output stream. See SIO_INPUT for details. If neither SIO_OUTPUT nor SIO_INPUT is given t may not be a pair.
SIO_TRYLOCK
Return FALSE if the stream cannot be locked immediately. No error is generated.
SIO_NOERROR
If the function fails no exception is produced.

The returned stream is owned by the calling thread using PL_acquire_stream().

int PL_get_stream_from_blob(atom_t b, IOSTREAM **s, int flags)
Same as PL_get_stream(), but operates directly on the blob b. This allows for foreign code that wishes long term access to a stream to maintain a handle to the stream as a (registered) atom_t object rather than a IOSTREAM*.
IOSTREAM * PL_acquire_stream(IOSTREAM *s)
Obtain ownership of s and return s. The application must call PL_release_stream() when done. Only one thread can own a stream and this call blocks if some other thread owns the stream. This function may be called multiple times by the same thread (recursive lock). Note that PL_get_stream() also acquires ownership.
int PL_release_stream(IOSTREAM *s)
Give up ownership acquired using PL_acquire_stream() or PL_get_stream(). If the stream is an an error state, return FALSE with an exception. Otherwise return TRUE.

In general, stream functions do not set any Prolog error state; that is done by PL_release_stream(). Once a stream is in an error state, all subsequent functions act as no-ops (returning -1) unless Sclearerr() is called. Sferror() may be used to check whether a stream is in an error condition. This error may be turned into a Prolog exception by calling PL_acquire_stream() followed by PL_release_stream(). In this case, PL_release_stream() will set the Prolog exception and return FALSE.

Below is an example that writes “Hello World” to a stream provided by Prolog. Note that PL_release_stream() raises an exception if the Sfprintf() failed and (thus) left the stream in an error state.

static foreign_t
hello_world(term_t to)
{ IOSTREAM *s;

  if ( PL_get_stream(to, &s, SIO_OUTPUT) )
  { Sfprintf(s, "Hello World!\n");
    return PL_release_stream(s);
  }

  return FALSE;
}

  ... // fragment from install function
  PL_register_foreign("hello world", 1, hello_world, 0);

ClioPatria (version V3.1.1-51-ga0b30a5)