[fpc-devel] Reading empty collection from stream

Marc Weustink marc.weustink at cuperus.nl
Mon Sep 11 14:39:38 CEST 2006


Marc Weustink wrote:
> Michael Van Canneyt wrote:
>>
>>
>> On Thu, 7 Sep 2006, Marc Weustink wrote:
>>
>>> Vincent Snijders wrote:
>>>> Hi,
>>>>
>>>> I am investigating Lazarus issue 7305. The TSynEdit class has a 
>>>> KeyStrokes property of the type TSynEditKeyStrokes, which is a 
>>>> TCollection descendant. The TSynEdit constructor fills the 
>>>> collection with some default items. If I remove the items and stream 
>>>> the TSynEdit, the following line is shown in the lfm:
>>>>     Keystrokes = <>
>>>>
>>>> If I read this lfm, I don't get a empty KeyStrokes collection, but 
>>>> one filled with the default value.
>>>>
>>>> I suspect the following lines in TReader.ReadCollection cause this 
>>>> behaviour:
>>>>     if not EndOfList then
>>>>       Collection.Clear;
>>>>
>>>> Is this a bug or by design? How do I load an empty collection from a 
>>>> stream, if the collection has a default value?
>>
>> You can't.
>>
>>> Delphi has the same construction, which is IMO a design flaw.
>>> IMO when a collection is "default" is shouldn't be streamed, so there 
>>> would be nothing written.
>>
>> There is no way to know whether the collection is default or not, 
>> since that would imply keeping a copy of the collection as it was just 
>> after creation.
>>
>>> I don't know why it is there, since when a "default" collection is 
>>> written, all elements are written. So it never will be <>.
>>>
>>>> Note, if I remove the 'Keystrokes = <>' line from the lfm, I will 
>>>> get the default collection too, so I wonder why there are two ways 
>>>> to get the default collection.
>>>
>>> I propose to remove the "if not EndOfList then Collection.Clear;" line.
>>
>> You may not,
> 
> I always can propose ;-)
> 
>> because then inherited form streaming will be broken: a collection of 
>> "<>" means: don't touch, keep the collection of
>> the parent form.
> 
> There you have a point. Didn't think of that.
> 
> And indeed, a collection itself doesn't know if it is default or not. 
> The owning class usually knows this.
> To solve this problem, I think the owning class needs to know when it is 
> loading or not, so that it can add the defaults when it is not loaded, 
> but created.
> I think the cleanest way is to introduce a Loading virtual method as 
> counterpart of the Loaded method. This way the owning class can decide 
> that when loading, the collection should be cleared.
> AFAIK, there is no other way a component knows on creation if it gets 
> loaded in the future or not.

Just thought of another option:

in the owning class, in defineProperties, define a property 
'CollectionIsEmpty' and write it only when the collection is empty. THen 
wen read from stream, clear the collection.

Marc




More information about the fpc-devel mailing list