On 06/18/2017 08:10 PM, Steve Prior wrote:
> I've been playing more with the MQTT library for SWI-Prolog at
which does not appear
> to be actively maintained and have been able to publish and subscribe to
> MQTT messages. It looks like this repository bundles an old version of
> the mosquitto library which caused some problems with subscribe, but
> once I used an up to date library that problem went away - so far so good.
> One requirement I've got for my use of Prolog in my Smarthome system is
> to be able to pass binary blobs (actually images) around and I found
> this MQTT library doesn't work for that. Digging into the C code I've
> found that the author used PL_get_chars(topic, &mqtt_topic, CVT_WRITE |
> BUF_MALLOC) to copy from the term_t into the message buffer used for
> mosquitto - since PL_get_chars returns a null terminated string that's
> certainly not going to work for me. Since MQTT messages are binary
> blobs there should be another way.
Just replace that by PL_get_nchars() and you can represent blobs in
atoms, strings and lists of character codes. Just make sure all
`characters' are in the range 0..255. If one is higher it internally
switches to wide character arrays and it won't work any longer.
> To support the work I'm about to do I've forked the SWI MQTT pack on
> Github, my fork is at https://github.com/sprior/swi-mqtt-pack
> code of interest is c/mqtt.c around lines 716-729. I know that binary
> blobs aren't explicitly supported by SWI-Prolog, but 10 years ago when I
> did this for CORBA Jan mentioned that Strings are internally stored as
> an array of unsigned chars, so binary data should actually work there,
> and it has - that's been working for 10 years! When I did it I wrote my
> code in C++, not C so it was a lot easier. The one problem I had at the
> time was how to determine the length of the char buffer, so I ended up
> doing it ont the Prolog side with string_length/2:
> filestore_storeFile(ServerMachine, Description, Mimetype, Contents):-
> filestore_storeFile(ServerMachine, Description, Mimetype, Contents,
So, see above. Might not have existed by then, but I doubt it. Just,
there is no C++ support for it. You can simply call the C API from
> filestore_storeFile was implemented in C++.
> So now with the MQTT code I'm looking at the code:
> where term_t payload;
> char* mqtt_payload;
> PL_get_chars(payload, &mqtt_payload, CVT_WRITE | BUF_MALLOC)
> mosq_rc = mosquitto_publish(m->mosq, &mid, mqtt_topic,
> strlen(mqtt_payload), mqtt_payload, qos, retain);
> Is it more correct to use
> int *PL_get_pointer*(term_t +t, void **ptr)
No no. PL_get_pointer() is only the inverse of PL_put_pointer(), which
allows storing a pointer as a Prolog integer. There is some logic in
there that changes the pointer representation such that it typically
becomes a small integer which is stored more efficiently in Prolog.
Its use is generally not encouraged these days.
> instead of PL_get_chars
> and is there any way to ask a term_t for its length to avoid the call to
> string_length in the Prolog wrapper?
Cheers --- Jan
> You received this message because you are subscribed to the Google
> Groups "SWI-Prolog" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to swi-prolog+...@googlegroups.com
> Visit this group at https://groups.google.com/group/swi-prolog
> For more options, visit https://groups.google.com/d/optout