How to use DefineProperties in a custom Class Object for dynamic Arrays - Delphi -
i'm trying create own class object , use store various data types application, works fine when using published properties, can stream these disk , no problems. need stream dynamic arrays of integer types well.
type tarrayofinteger = array of integer; tsetting = class(tcomponent) private fintval: integer; fintarr: tarrayofinteger; procedure readintarr(reader: treader); procedure writeintarr(writer: twriter); protected procedure defineproperties(filer: tfiler); override; published property intval: integer read fintval write fintval; property intarr: tarrayofinteger read fintarr write fintarr; end; { tsetting } procedure tsetting.defineproperties(filer: tfiler); begin inherited; filer.defineproperty('intarr', readintarr, writeintarr, true); end; procedure tsetting.readintarr(reader: treader); var i: integer; lvval:integer; begin i:=low(fintarr); reader.readlistbegin; {j := reader.readinteger(); setlength(fintarr, j); := 0 j - 1 begin fintarr[i] := reader.readinteger(); end;} while not reader.endoflist begin fintarr[i]:=reader.readinteger; inc(i); end; reader.readlistend; end; procedure tsetting.writeintarr(writer: twriter); var i: integer; begin writer.writelistbegin; //writer.writeinteger(integer(length(fintarr))); := low(fintarr) high(fintarr) begin writer.writeinteger(fintarr[i]); end; writer.writelistend; end; function classtostr(pvclass:tcomponent):ansistring; var instream, outstream: tmemorystream; begin instream := tmemorystream.create; outstream := tmemorystream.create; try instream.writecomponentres(pvclass.classname, pvclass); //instream.writecomponent(pvclass); instream.position := 0; objectresourcetotext(instream, outstream); // objectbinarytotext(instream,outstream); outstream.position := 0; setlength(result,outstream.size+1); fillchar(result[1],outstream.size+1,0); outstream.readbuffer(result[1],outstream.size); freeandnil(instream); freeandnil(outstream); end; end; function strtoclass(pvstr:ansistring;pvcomponent:tcomponent):tcomponent; var instream, outstream: tmemorystream; begin instream := tmemorystream.create; outstream := tmemorystream.create; try if (pvstr<>'') instream.writebuffer(pvstr[1],length(pvstr)); instream.position:=0; objecttexttoresource(instream, outstream); // objecttexttobinary(instream,outstream); outstream.position:=0; result:=outstream.readcomponentres(pvcomponent); //*****exception fired***** //result:=outstream.readcomponent(pvcomponent); freeandnil(instream); freeandnil(outstream); end; end; ============= //test procedure tform1.btn5click(sender: tobject); var lvobj,lv1: tsetting; lvstr:string; lvarr:tarrayofinteger; begin lvobj := tsetting.create(nil); try lvobj.intval := 12345; setlength(lvarr, 3); lvarr[0] := 222; lvarr[1] := 333; lvarr[2] := 444; lvobj.intarr:=lvarr; lvstr:=classtostr(lvobj); registerclass(tsetting); lvobj.intval:=1; lv1:=tsetting( strtoclass(lvstr,lvobj)); if (lv1.intval>0) mmo1.text:=lvstr; freeandnil(lvobj); end; // writecomponentresfile(extractfilepath(paramstr(0))+ 'd.res',self); end; //first chance exception @ $77925b68. exception class ereaderror message 'property not exist'. process project1.exe (23512) //first chance exception @ $77925b68. exception class ereaderror message 'error reading tsetting.: property not exist'. process project1.exe (23512) result:=outstream.readcomponentres(pvcomponent); //*****exception fired*****
you not allocating array when reading it. so:
procedure tsetting.readintarr(reader: treader); begin fintarr := nil; reader.readlistbegin; while not reader.endoflist begin setlength(fintarr, length(fintarr) + 1); fintarr[high(fintarr)] := reader.readinteger; end; reader.readlistend; end; the other change need make move intarr public property. cannot have published, , define property same name in defineproperties.
i dubious of use of ansistring. have expected utf-8 encoded bytes in case of non-ascii characters. perhaps should using string stream appropriate encoding specified.
personally rather sceptical of using form streaming in way. prefer use standard format such json.
Comments
Post a Comment