Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
USE anyTable
SCATTER NAME oRec MEMO
cRec = serializeobject(oRec)
* do anything with the character data cRec...
* ...say store it in a text file,
* ...or send it through an email
* ...or send it through TCP/IP
* ...or pass it across a COM boundary
* ...or, well, you get the picture!
oNewRec = deserializeobject(cRec)
* now examine oNewRec in the Debug Watch Window to see that it resembles oRec!
PROCEDURE SerializeObject
LPARAMETERS toObj
* Written by William GC Steinford
* Input: toObj is a subclass of Empty (or a SCATTER NAME object)
* Output: a string representing toObj
LOCAL lnMem, laMem[1], lcOut, lcProp, lvData, lnI
lnMem = AMEMBERS(laMem,toObj,0)
SET TEXTMERGE TO MEMVAR lcOut ON
\\<? version="1.0" encoding="UTF-8" ?>
\<object class="empty">
FOR lnI = 1 TO lnMem
lcProp = laMem[lnI]
\ <property name="<<laMem[lnI]>>"
lvData = EVALUATE('toObj.'+lcProp)
* from lexRegistry.AnyTypeToC
do case
case varType(lvData)='T'
\\ type="DATETIME">
if empty(lvData)
\\{/:}
ELSE
lcData = "{^" + Transform(Year( lvData)) + '/' ;
+ Transform(Month( lvData)) + '/' ;
+ Transform(Day( lvData)) + ' ' ;
+ Transform(hour( lvData)) + ':' ;
+ Transform(Minute(lvData)) + ':' ;
+ Transform(Sec( lvData)) ;
+ '}'
\\<<lcData>>
endif
case varType(lvData)='D'
\\ type="DATE">
if EMPTY(lvData)
\\{}
else
lcData = '{^ '+ alltrim(Str(Year(lvData))) + '/' ;
+ alltrim(Str(Month(lvData))) + '/' ;
+ alltrim(Str(Day(lvData))) + '}'
\\<<lcData>>
endif
case varType(lvData)='L'
\\ type="LOGICAL"><<iif( vData, '.T.', '.F.' )>>
case varType(lvData)='N'
\\ type="NUMERIC"><<Transform(lvData)>>
case varType(lvData)='C'
\\ type="CHARACTER">
* UrlEncode dangerous characters:
lcData = StrTran(lvData,'%', '%25')
lcData = StrTran(lcData,'"', '%22')
lcData = StrTran(lcData,['], '%27')
lcData = StrTran(lcData,'[', '%5B')
lcData = StrTran(lcData,']', '%5D')
lcData = StrTran(lcData,'<', '%3C')
lcData = StrTran(lcData,'>', '%3E')
lcData = StrTran(lcData,chr(13),'%0D')
lcData = StrTran(lcData,chr(10),'%0A')
\\<<lcData>>
case varType(lvData)='O'
* Skip sub objects.
* We could recursively call SerializeObject to package this member.
endcase
\\</property>
ENDFOR
\</object>
SET TEXTMERGE TO
RETURN lcOut
PROCEDURE DeSerializeObject
LPARAMETERS tcObj
* Written by William GC Steinford
* Input: tcObj is a string representing a subclass of Empty (or a SCATTER NAME object)
* Output: an actual object representing tcObj
* Example tcObj Value:
* <? version="1.0" encoding="UTF-8" ?>
* <object class="empty">
* <property name="TEXT" type="CHARACTER">There </property>
* <property name="TEXT2" type="CHARACTER"></property>
* </object>
*
LOCAL lnProp, laProp[1], lcObj, lnStrt, lnStop, loOut, lnI
lnStrt = ATC('<property', tcObj )
lnStop = RATC('</object>', tcObj )
lcObj = SUBSTR( tcObj, lnStrt, lnStop-lnStrt )
lnProp = ALINES(laProp, STRTRAN(lcObj,'</property>',CHR(13)) )
loOut = CREATEOBJECT('Empty')
FOR lnI = 1 TO lnProp
lvVal = .NULL.
lcName = .NULL.
TRY
lcType = UPPER( SUBSTR(laProp[lnI], ATC('type="',laProp[lnI])+6) )
lcName = SUBSTR(laProp[lnI], ATC('name="',laProp[lnI])+6)
IF NOT '"'$lcName
lcName = .NULL.
THROW "bad name"
ENDIF
lcName = LEFT(lcName,AT('"',lcName)-1)
lcVal = SUBSTR(laProp[lnI], ATC('>', laProp[lnI])+1)
DO CASE
CASE lcType='DATETIME' AND TYPE(lcVal)='T'
lvVal = EVALUATE(lcVal)
CASE lcType='C' AND TYPE('['+lcVal+']')='C'
lvVal = EVALUATE('['+lcVal+']')
CASE TYPE(lcVal)=LEFT(lcType,1)
lvVal = EVALUATE(lcVal)
ENDCASE
CATCH TO oExc
* Ignore errors... lvVal=.NULL. will signify errors.
ENDTRY
IF NOT ISNULL(lcName)
TRY
ADDPROPERTY(loOut, lcName, lvVal)
CATCH TO oExc
* Ignore errors
ENDTRY
ENDIF
ENDFOR
RETURN loOut