Search code examples
networkingforthgforth

How do I read raw code from a website in Gforth?


I would like a word like

read-site ( add n buff max -- n flag )

where 'add n' is the site name buffer, 'buff max' is the buffer to which the ASCII text should be read to, 'n' is the number of bytes that was read and flag is true if operation succeeded.

Is this possible in Gforth in Linux, Android or Windows?


Solution

  • Just a list of approaches

    The most easy proper way should be to use an HTTP-client library (or binding) in Forth (if any). It seems that some kind of such library exists in the Gforth repository — see netlib/httpclient.fs. Obviously it doesn't work with HTTPS.

    The next way is to use an appropriate external shared library, for example libcurl. It is well-known tool that supports a lot of protocols (the binding and some usage examples can be also found in SP-Forth).

    The next way is to use a system call and spawn a child process (not so efficient approach in terms of resources usage). Gforth has system word for that. Usage example:

    S" curl http://example.com/" system
    

    The web-page HTML code will be printed to stdout. Unfortunately, redirection with outfile-execute doesn't work in this case (it looks like incomplete or weak implementation of the system word).

    So, a temporary file should be used:

    S" curl --silent http://example.com/ > tmp" system
    

    After that the file content can be read into a given buffer.

    A conceptual implementation is the following:

    : read-url ( d-buffer d-txt-url -- d-txt-webpage )
      s" curl --silent {} > tmp" interpolate system
      over >r \ keep buf addr
      s" tmp" open-file throw dup >r read-file throw
      r> close-file throw
      r> swap
    ;
    

    where interpolate ( i*x d-txt1 -- d-txt2 ) expands the given template.