Indexed text to GLK function using IF6

I have an Inform 7 extension that I want to have pass indexed text to a GLK function as a c-string. I know that I could do this with regular text by including an IF6 call to the GLK function with the text passed through the ChangeAnyToCString() function first:

To do something with the text (foo - a text): (- glk_some_function(Glulx_ChangeAnyToCString({foo})); -)

I want to do the same type of thing, but with “foo” being an indexed text instead. However, the ChangeAnyToCString() function doesn’t accept an indexed text. Does anyone know how I could pass indexed text from Inform 7 to a GLK function as a c-string?

Thanks in advance!

Two ways:

Array streamCloseResults --> 0 0; [ indexedTextToCStyle buffer bufferSize indexedText oldStream stream; oldStream = glk_stream_get_current(); buffer-->0 = $E2000000; stream = glk_stream_open_memory_uni(buffer+4, bufferSize-2, filemode_Write, 0); glk_stream_set_current(stream); print (INDEXED_TEXT_TY_Say) indexedText; glk_stream_close(stream, streamCloseResults); buffer-->((streamCloseResults-->1) + 1) = 0; glk_stream_set_current(oldStream); return buffer; ];or[ indexedTextToCStyle buffer bufferSize indexedText length index character; length = BlkValueExtent(indexedText); if (length > bufferSize - 2) length = bufferSize - 2; buffer-->0 = $E2000000; for (index = 0: index < length: ++index) { character = BlkValueRead(indexedText, index); buffer-->(index+1) = character; if (~~character) break; } if (index == length) { buffer-->(index+1) = 0; } return buffer; ];which you would use something like this: Include (- Constant exampleBufferSize = 256; Array exampleBuffer --> exampleBufferSize; -) after "Definitions.i6t". To print (I - some indexed text): (- glk_put_string_uni(indexedTextToCStyle(exampleBuffer, exampleBufferSize, {I})); -).
The former is a more robust, as it leaves the details up to INDEXED_TEXT_TY_Say. But the latter may be better if you plan on doing this a lot (read: hundreds of times per turn) because there are Glk implementations where memory streams are very slow. Of course, if you can at all avoid the conversion and just use INDEXED_TEXT_TY_Say, that would be best.

Are there implementations where memory streams are slow? This is not something in my private repository of things to worry about being slow.

I was speaking from my experience getting Interactive Debugger to start up decently fast under CocoaGlk; switching from memory streams to filter I/O cut the time by something like a minute and a half. But that’s definitely outlier code, so I went back to check with simpler source text. Now I wonder if the slowness is really due to the number of streams cycled through, and not their kind. For instance, the test-me in this source:There is a room. Include (- [ spin counter; for (counter = 0: counter < 1000: ++counter) { glk_stream_close(glk_stream_open_memory(1, 0, filemode_Write, 0), 0); } ]; -). To spin: (- spin(); -). Every turn: spin. Test me with "z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z".is already slower under CocoaGlk by the second wait, but the effect becomes more pronounced as the turns accumulate. Maybe this accounts for some of the perceived slowness of indexed text, sinceThere is a room. Every turn: repeat with a counter running from one to 1000: let foo be some indexed text; now foo is "". Test me with "z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z/z". is essentially a less transparent rendition of the same.

Hm. So I see.

This is worth poking at, because the same spin function has no noticeable delay under CheapGlk, Quixe, or my IosGlk library (all running on the same CPU) (iOS Simulator for the last test). And it’s only a little bit slow under Zoom.

I’ll file an I7 bug, I guess.

Looks like a memory leak in the CocoaGlk library, to me.

Fantastic, that code did the trick. Thanks EmacsUser and zarf!!

Thank you again, EmacsUser and zarf for your earlier replies.

I am trying to edit this function (by EmacsUser) so that the buffer will resize according to the number of characters in indexedText:

I’d like to be able to resize the Array “buffer” provided as a parameter, if needed, to accommodate the number of characters in the “indexedText” parameter. I’ve looked through the Inform 6 documentation, but can’t find any information regarding how an array could be resized. Any ideas?

Thanks in advance.

I6 has no built-in way to resize an array, but Glulx assembly does have malloc and free. So you can malloc an array in the conversion function:[ indexedTextToNewCStyle indexedText length bufferByteCount buffer index character; length = BlkValueExtent(indexedText); bufferByteCount = 4 * (length + 2); @malloc bufferByteCount buffer; buffer-->0 = $E2000000; for (index = 0: index < length: ++index) { character = BlkValueRead(indexedText, index); buffer-->(index+1) = character; if (~~character) break; } if (index == length) { buffer-->(index+1) = 0; } return buffer; ];so long as you remember to free it when it’s no longer needed:[ example indexedText cStyle; cStyle = indexedTextToNewCStyle(indexedText); glk_put_string_uni(cStyle); @mfree cStyle; ];