ExternalStructure examples

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

ExternalStructure examples

Eric Winger-4
Hi!

Does anyone have any good examples of how ExternalStructures are used in
Dolphin? In particular, StructurePointers?

I'm having real problems accessing the string inside of:

StructurePointer newNull: COMTaskMemory elementClass: UnicodeString

I keep getting walkbacks all over the place, no matter how I try to
get/set the value. Maybe a good question is, is value/value: the way to
set the raw value in the structure?


thx

Eric


Reply | Threaded
Open this post in threaded view
|

Re: ExternalStructure examples

Eric Winger-4
Ok, I've been able to kind of use value/value:. But I had to do some
memory allocation first. I say kind of because if I inspect this:


| txt sp |
sp := StructurePointer newNull: COMTaskMemory elementClass: UnicodeString.
txt := 'some text' asUnicodeString.
sp bytes allocate: txt size * 2.
sp value: txt.
sp value

I'll get 'so'.

hmmmmm.

Do others get similar results? I would expect to get 'some text' as a
result.

I have a nagging suspicion still that I'm not understanding how to use
ExternalStructures well enough.

thx for any feedback.

Eric





Eric Winger wrote:

> Hi!
>
> Does anyone have any good examples of how ExternalStructures are used in
> Dolphin? In particular, StructurePointers?
>
> I'm having real problems accessing the string inside of:
>
> StructurePointer newNull: COMTaskMemory elementClass: UnicodeString
>
> I keep getting walkbacks all over the place, no matter how I try to
> get/set the value. Maybe a good question is, is value/value: the way to
> set the raw value in the structure?
>
>
> thx
>
> Eric
>


Reply | Threaded
Open this post in threaded view
|

Re: ExternalStructure examples

Ian Bartholomew-5
Eric,

> I have a nagging suspicion still that I'm not understanding how to use
> ExternalStructures well enough.

And I know less about it than you, but I had a little play and came up with

sp := StructurePointer newNull: ExternalMemory elementClass: UnicodeString.
txt := 'some text' asUnicodeString.
sp bytes allocate: txt size * 2.
sp replaceFrom: 1 to: txt size * 2 with: txt startingAt: 1.
sp value

made slightly more complex because of the UnicodeString (the * 2 bits are
really a kludge).  This appears to work, but!!

The problem with the original is that sending #value:  to a StructurePointer
writes to memory the number of bytes used to hold the ExternalMemory address
and not the number of bytes available at the address that it points to (have
a think about that - I think it's what I meant). It can therefore only save
4 bytes (the byte size of an address) which is the two UnicodeCharacters you
saw.

Without knowing how you should really use the class I can only speculate
that it needs to override #value: (or maybe #copyBytes:) in a similar way to
the way in which it overrides #value.  This is just a guess though.

Ian


Reply | Threaded
Open this post in threaded view
|

Re: ExternalStructure examples

Eric Winger-4
Ian Bartholomew wrote:

> Eric,
>
>
>>I have a nagging suspicion still that I'm not understanding how to use
>>ExternalStructures well enough.
>>
>
> And I know less about it than you, but I had a little play and came up with
>
> sp := StructurePointer newNull: ExternalMemory elementClass: UnicodeString.
> txt := 'some text' asUnicodeString.
> sp bytes allocate: txt size * 2.
> sp replaceFrom: 1 to: txt size * 2 with: txt startingAt: 1.
> sp value
>
> made slightly more complex because of the UnicodeString (the * 2 bits are
> really a kludge).  This appears to work, but!!


Never let it be said that I'd pass up an opportunity to kludge something. :)


>
> The problem with the original is that sending #value:  to a StructurePointer
> writes to memory the number of bytes used to hold the ExternalMemory address
> and not the number of bytes available at the address that it points to (have
> a think about that - I think it's what I meant). It can therefore only save
> 4 bytes (the byte size of an address) which is the two UnicodeCharacters you
> saw.
>
> Without knowing how you should really use the class I can only speculate
> that it needs to override #value: (or maybe #copyBytes:) in a similar way to
> the way in which it overrides #value.  This is just a guess though.
>


Ok, I think I'm beginning to understand what StructurePointer value:
does. And I think its wrong for Strings (or Unicode strings).
value/value: should be symmetric. In SP, they're not.

Let me explain: (and I might not get some of the details right, but I
think the general argument is right)

The correct implementation of value/value: should get/set the value of a
string in the pointer. value does this. But value: replaces the bytes of
the bytes inst var. In my example above, bytes is a subclass of
ExternalAddress.

Look what happens when you do the following:

(StructurePointer newNull: ExternalMemory elementClass: String) value:
'hi' .

(StructurePointer newNull: ExternalMemory elementClass: UnicodeString)
value: 'hi there' asUnicodeString.

The first gets an index error. The second tries to write out of bounds.

What is happening is that value: is trying to write the bytes of the
strings into the bytes inst var. In this case its a 4 byte memory
address of ExternalMemory. It doesn't want a string.  I believe it wants
an address of the string. This isn't right, it should be symmetric.

I made a subclass of StructurePointer -> StringPointer which overrides
value: as you suggested. It has just one method.

value: aString
        bytes free.
        bytes := bytes class fromString: aString.

This just changes the ExternalAddress (pointer) of the object as needed
and frees the previous pointer.

Anyway, I don't know how much value this has on a cosmic or geologic
scale, but I think it might be worth a looksie.

Eric


Reply | Threaded
Open this post in threaded view
|

Re: ExternalStructure examples

Ian Bartholomew-5
Eric,

> Never let it be said that I'd pass up an opportunity to kludge something.
:)

Ah, sorry. No insult intended. A(nother) case where the words didn't quite
end up reading what I meant to say <g>.  I had initially tried to use
#byteSize to get the number of bytes to copy, which seemed more "correct",
but ran into problems as #byteSize includes the trailing 0 ...

x := '123456789' asUnicodeString.
x copyFrom: 1 to: x byteSize

.. fails. *That* why I referred to the "* 2" as a kludge - honestly.

> What is happening is that value: is trying to write the bytes of the
> strings into the bytes inst var. In this case its a 4 byte memory
> address of ExternalMemory. It doesn't want a string.  I believe it wants
> an address of the string. This isn't right, it should be symmetric.

Hmm, I convinced myself that it was writing to the correct memory address
but was only writing the number of bytes that would fit into the space used
by an address.  Never mind though, whatever it's doing I agree that it is
not right.

> This just changes the ExternalAddress (pointer) of the object as needed
> and frees the previous pointer.

That's really just a partial fix though as the underlying reason for
#value: failing, that the implementation of #copyBytes: is wrong, means that
all (?) the other copy semantics for the object will (might?) be wrong as
well.

> Anyway, I don't know how much value this has on a cosmic or geologic
> scale, but I think it might be worth a looksie.

Agreed. It's not a class that is used much but it should still work.

Regards
    Ian