Converting UC_STRING to/from C pointer to UTF8 octet sequences
Paul Cohen <[email protected]> Mon, 18 May 2009 12:51:31 +0200
| Newsgroups | gmane.comp.lang.eiffel.gobo.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi all,
I need some advice/feedback on how to convert/create a UC_STRING from
a C pointer to a UTF8 byte sequence (and vice versa). I can't find any
routines or examples in the Gobo unicode library for doing it. The
need for this arises when writing Eiffel shared libraries (with
C-style API:s).
This is my current appach:
uc_string_from_utf8_pointer (p: POINTER): UC_STRING is
-- New UC_STRING object from UTF8 octet sequence pointed to by `p'.
require
p_not_default_pointer: p /= default_pointer
local
utf8: STRING_8
do
create utf8.make_from_c (p)
create Result.make_from_utf8 (utf8)
ensure
result_not_void: Result /= Void
end
It is unfortunate that I have to create two "string objects" to
perform the "conversion".
Returning a pointer to a UTF8 octet sequence is trickier. An initial
approach could be:
utf8_pointer_from_uc_string (s: UC_STRING): POINTER is
-- A pointer to the UTF8 octet sequence of `s'.
require
s_not_void: s /= Void
local
utf8: STRING_8
a: ANY
do
utf8 := s.to_utf8
a := utf8.to_c
Result := $a
ensure
result_not_default_pointer: Result /= default_pointer
end
This is not a good solution since 'utf8' and its memory area may not
be available any longer when the client tries to access the octet
sequence (they are on the stack). Many C API:s are written so that the
caller must supply a memory buffer that the API implementation uses
for returning the result, leaving the caller responsable for memory
management. So a better approach would maybe be something like:
fill_utf8_buffer_from_uc_string (s: UC_STRING; buffer: STRING_8) is
-- Fill the buffer with the UTF8 octet sequence of `s'.
require
s_not_void: s /= Void
buffer_not_void: buffer /= Void
buffer_large_enough: s.to_utf8.count <= buffer.count
local
utf8: STRING_8
a: ANY
p_buffer, p_utf8: POINTER
do
utf8 := s.to_utf8
a := buffer.to_c
p_buffer := $buffer
a := utf8.to_c
p_utf8 := $a
p_buffer.memory_copy (p_utf8, utf8.count)
end
Yet another approach would be for the Eiffel class that implements the
API to maintain a buffer of memory where the returned result is put.
However then one will run into multprogramming problems with accessing
shared data.
Any feedback on this issue would be welcome!
/Paul
--
Paul Cohen
www.seibostudios.se
mobile: +46 730 787 035
e-mail: [email protected]
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables
unlimited royalty-free distribution of the report engine
for externally facing server and web deployment.
http://p.sf.net/sfu/businessobjects