function ParseVCard( cText )
local nVer := 0
local aRet := {}
cText := StrBetween( cText, "BEGIN:VCARD", "END:VCARD" )
cText := StrTran( cText, Chr(10), Chr(13 ) )
if Empty( cText )
MsgInfo( "Not valid VCard Info" )
else
nVer := Val( StrBetween( cText, "VERSION:", Chr(13) ) )
if nVer == 2.1
AAdd( aRet, TagInfo( cText, "TITLE:" ) )
AAdd( aRet, TagInfo( cText, "TEL;WORK;VOICE:" ) )
AAdd( aRet, TagInfo( cText, "TEL;HOME;VOICE:" ) )
AAdd( aRet, TagInfo( cText, "ADR;WORK:;;" ) )
AAdd( aRet, TagInfo( cText, "ADR;HOME:;;" ) )
AAdd( aRet, TagInfo( cText, "EMAIL;PREF;INTERNET:" ) )
else
if nVer > 0
MsgInfo( "Version " + LTrim( Str( nVer ) ) + " not implemented" )
endif
endif
endif
return aRet
//----------------------------------------------------------------------------//
tatic function TagInfo( cStr, cTag )
return StrBetween( cStr, cTag, Chr( 13 ) )
//----------------------------------------------------------------------------//
static function StrBetween( cStr, cAfter, cBefore )
return BeforAtNum( cBefore, AfterAtNum( cAfter, cStr, 1 ), 1 )
//----------------------------------------------------------------------------//
// Purpose: VCard class
// Date: 4/30/2013
#include "fivewin.ch"
function main()
local cVcard, aVcard, oVcard, cFile
cFile:= "James Bott.vcf"
oVcard:= TVcard():new( cFile )
msgInfo( oVcard:cName )
msgInfo( oVcard:cCompany )
return nil
//---------------------------------------------------------------------------//
class Tvcard
data cName
data cTitle
data cCompany
data cWorkPhone
data cWorkFax
data cHomePhone
data cWorkAddress
data cHomeAddress
data cEmail
data cEmail2
Exported:
method new( cVcard )
method end() VIRTUAL
Hidden:
method tagInfo()
method StrBetween()
endclass
//---------------------------------------------------------------------------//
method new( cVcard ) class TVCARD
local nVer := 0
local aRet := {}
local cText := memoRead( cVcard )
cText := ::StrBetween( cText, "BEGIN:VCARD", "END:VCARD" )
cText := StrTran( cText, Chr(10), Chr(13 ) )
if Empty( cText )
MsgInfo( "Not valid VCard Info" )
else
nVer := Val( ::StrBetween( cText, "VERSION:", Chr(13) ) )
if nVer == 2.1
::cName:= ::TagInfo( cText, "FN:" )
::cTitle:= ::TagInfo( cText, "TITLE:" )
::cCompany:= ::TagInfo( cText, "ORG:" )
::cWorkPhone:= ::TagInfo( cText, "TEL;WORK;VOICE:" )
::cWorkFax:= ::TagInfo( cText, "TEL:WORK:FAX:" )
::cHomePhone:= ::TagInfo( cText, "TEL;HOME;VOICE:" )
::cWorkAddress:= ::TagInfo( cText, "ADR;WORK:;;" )
::cHomeAddress:= ::TagInfo( cText, "ADR;HOME:;;" )
::cEmail:= ::TagInfo( cText, "EMAIL;PREF;INTERNET:" )
::cEmail2:= ::TagInfo( cText, "EMAIL:INTERNET:" )
else
if nVer > 0
MsgInfo( "VCard Version " + LTrim( Str( nVer ) ) + " not implemented" )
endif
endif
endif
return self
//---------------------------------------------------------------------------//
method tagInfo( cStr, cTag ) Class TVCARD
return ::StrBetween( cStr, cTag, Chr( 13 ) )
//----------------------------------------------------------------------------//
method StrBetween( cStr, cAfter, cBefore ) Class TVCARD
return BeforAtNum( cBefore, AfterAtNum( cAfter, cStr, 1 ), 1 )
//----------------------------------------------------------------------------//
// end of file
maybe we can use an array for the attributes.
/*
*
* vcard.prg
* G.N.Rao
* Apr 30-2013 06:27 PM
*
*/
#include "FiveWin.Ch"
#include "hbcompat.ch"
#include "ord.ch"
#include "xbrowse.ch"
//----------------------------------------------------------------------------//
REQUEST DBFCDX
//----------------------------------------------------------------------------//
function Main()
local cCard, aInfo
local oCard
local cFile
do while ! Empty( cFile := cGetFile( "VCard (*.vcf) |*.vcf|", "Select a VCard File", ;
nil, cFilePath( ExeName() ) ) )
oCard := TVCard():New( cFile )
oCard:Display()
enddo
return (0)
//----------------------------------------------------------------------------//
init procedure PrgInit
SET DATE GERMAN
SET CENTURY ON
SET TIME FORMAT TO "HH:MM:SS"
SET EPOCH TO YEAR(DATE())-50
SET DELETED ON
SET EXCLUSIVE OFF
RDDSETDEFAULT( "DBFCDX" )
XbrNumFormat( 'E', .t. )
SetKinetic( .f. )
SetGetColorFocus()
return
//----------------------------------------------------------------------------//
CLASS TVCard
DATA nVersion AS NUMERIC
DATA lValid AS LOGICAL
//
DATA cFile
DATA cName, cNameFmt, cAdrHome, cAdrWork, cAdrHomeFmt, cAdrWorkFmt, ;
cTitle, cKind, cGender, cOrg, cRole, cNickName, cNote, ;
cPhoneHome, cPhoneWork, cFaxHome, cFaxWork, cPhoneCell, ;
cEmail, cPhotoRef, cPhotoBuf ;
AS CHARACTER
DATA dDOB AS DATE INIT CTOD( '' )
//
//
METHOD New( cFile ) CONSTRUCTOR
METHOD ReadFile( cFile ) INLINE ::ReadCardText( MemoRead( cFile ) )
METHOD ReadCardText( cText )
METHOD Display()
//
METHOD SaveToDBF() VIRTUAL
METHOD ReadFromDBF() VIRTUAL
METHOD SaveAsText() VIRTUAL
METHOD RestoreFromText( cText ) VIRTUAL
METHOD WriteVCard() VIRTUAL
ENDCLASS
//----------------------------------------------------------------------------//
METHOD New( cFile ) CLASS TVCard
if ! Empty( cFile )
if Len( cFile ) < 256 .and. Lower( cFileExt( cFile ) ) == "vcf"
::cFile := cFileNoPath( cFile )
::ReadFile( cFile )
else
::ReadCardText( cFile )
endif
endif
return Self
//----------------------------------------------------------------------------//
METHOD ReadCardText( cText ) CLASS TVCard
local aLines, aLine
local c, cVal, n, nAt
local lAssigned, cAttr
cText := StrBetween( cText, "BEGIN:VCARD", "END:VCARD" )
cText := StrTran( cText, CRLF + ' ', '' )
cText := StrTran( cText, CRLF, Chr(10) )
cText := StrTran( cText, Chr(10) + ' ', '' )
cText := RemAll( cText, 10 )
aLines := HB_ATokens( cText, Chr(10) )
for n := 1 to Len( aLines )
c := aLines[ n ]
aLines[ n ] := { Upper( BeforAtNum( ':', c, 1 ) ), AfterAtNum( ':', c, 1 ), "" }
if aLines[ n, 1 ] = "PHOTO" .and. ;
"ENCODING" $ aLines[ n, 1 ] .and. ;
"BASE64" $ aLines[ n, 1 ]
aLines[ n, 2 ] := DecodeBase64( aLines[ n, 2 ] )
endif
next n
if aLines[ 1, 1 ] = "VERSION"
::nVersion := Val( aLines[ 1, 2 ] )
endif
if ::nVersion == 2.1 .or. ::nVersion == 3 .or. ::nVersion == 4
::lValid := .t.
endif
if ! ::lValid
return Self
endif
ADel( aLines, 1, .t. )
for n := 1 to Len( aLines )
if !( ';' $ aLines[ n, 1 ] )
aLines[ n, 1 ] += ';'
endif
c := aLines[ n, 1 ]
if ( nAt := At( '.', c ) ) > 0 .and. nAt < At( ';', c )
aLines[ n, 3 ] := Trim( BeforAtNum( c, '.', 1 ) ) // Group
aLines[ n, 1 ] := LTrim( AfterAtNum( c, '.', 1 ) )
endif
next
for each aLine in aLines
c := aLine[ 1 ]
cVal := aLine[ 2 ]
lAssigned := .f.
for each cAttr in { "TITLE", "GENDER", "KIND", "ORG", "ROLE", "NICKNAME", "NOTE" }
if c = cAttr + ';'
OSend( Self, "_c" + cAttr, cVal )
lAssigned := .t.
exit
endif
next
if lAssigned
loop
endif
//
do case
case c = 'N;' ; ::cName := cVal
case c = 'FN;' ; ::cNameFmt := cVal
case c = 'ADR;'
if "WORK" $ c
::cAdrWork := cVal
endif
if "HOME" $ c .or. !( "WORK" $ c )
::cAdrHome := cVal
endif
case c = 'LABEL;'
cVal := StrTran( cVal, "=0A=0D", CRLF )
cVal := StrTran( cVal, "=0D=0A", CRLF )
cVal := StrTran( cVal, "=20", " " )
cVal := FW_ValToExp( cVal )
if "WORK" $ c
::cAdrWorkFmt := cVal
endif
if "HOME" $ c .or. !( "WORK" $ c )
::cAdrHomeFmt := cVal
endif
case c = 'TEL;'
if "CELL" $ c
::cPhoneCell := cVal
else
if "WORK" $ c
if "FAX" $ c
::cFaxWork := cVal
else
::cPhoneWork := cVal
endif
endif
if "HOME" $ c .or. !( "WORK" $ c )
if "FAX" $ c
::cFaxHome := cVal
else
::cPhoneHome := cVal
endif
endif
endif
case c = 'EMAIL;'
::cEmail := cVal
case c = 'PHOTO;'
if IsBinaryData( cVal )
::cPhotoBuf := cVal
else
::cPhotoRef := cVal
endif
case c = 'BDAY;'
c := cVal
::dDOB := STOD( Left( StrTran( StrTran( c, '-', '' ), '/', '' ), 8 ) )
endcase
next
return Self
//----------------------------------------------------------------------------//
METHOD Display() CLASS TVCard
local oDlg, oFont, oImage
local nRow, cAdrHomeFmt := '', cAdrWorkFmt := ''
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-14
DEFINE DIALOG oDlg SIZE 800,500 PIXEL FONT oFont ;
TITLE ::cFile + " (Version : " + LTrim( Str( ::nVersion ) ) + " )"
if ! Empty( ::cAdrHomeFmt )
cAdrHomeFmt := &( ::cAdrHomeFmt )
endif
if ! Empty( ::cAdrWorkFmt )
cAdrWorkFmt := &( ::cAdrWorkFmt )
endif**
nRow := 10
@ nRow,10 SAY "NameFmt : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cNameFmt SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
/*
nRow += 12
@ nRow,10 SAY "Name : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cName SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
*/
nRow += 12
@ nRow,10 SAY "Gender : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cGender SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "Title : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cTitle SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "Role : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cRole SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "Orgnisn : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cOrg SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "DateOfBirth : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::dDOB SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "PHONES (Work) : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cPhoneWork SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "(Home) : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cPhoneHome SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "FAX (Work) : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cFaxWork SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "(Home) : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cFaxHome SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "CellPhone : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cPhoneCell SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "Email : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cEmail SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
/*
nRow += 12
@ nRow,10 SAY "ADDR (Work) : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cAdrWork SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 12
@ nRow,10 SAY "(Home) : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY ::cAdrHome SIZE 200,10 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
*/
nRow += 12
@ nRow,10 SAY "MailWork : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY cAdrWorkFmt SIZE 200,30 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 32
@ nRow,10 SAY "MailHome : " SIZE 50,10 PIXEL OF oDlg RIGHT
@ nRow,61 SAY cAdrHomeFmt SIZE 200,30 PIXEL OF oDlg COLOR CLR_BLACK,CLR_WHITE BORDER
nRow += 30
if ! Empty( ::cPhotoBuf )
@ 10,290 IMAGE oImage SIZE 100,100 PIXEL OF oDlg
WITH OBJECT oImage
:LoadFromMemory( ::cPhotoBuf )
:Refresh()
END
elseif ! Empty( ::cPhotoRef )
@ 10,290 SAY ::cPhotoRef SIZE 100,100 PIXEL OF oDlg COLOR CLR_HRED,CLR_WHITE BORDER
endif
@ nRow-14,350 BUTTON "Close" SIZE 40,14 PIXEL OF oDlg ACTION oDlg:End()
ACTIVATE DIALOG oDlg CENTERED
RELEASE FONT oFont
// QuickDisplay
XBrowse( Self )
return nil
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
static function StrBetween( cStr, cAfter, cBefore, nOccur )
return BeforAtNum( cBefore, AfterAtNum( cAfter, cStr, IfNil( nOccur, 1 ) ), 1 )
//----------------------------------------------------------------------------//
static function GetXmlTag( cText, cTag, nOccur )
local cRet := nil
local c, n1, n2
n1 := At( '<' + cTag + '>', cText )
n2 := At( '<' + cTag + '/>', cText )
if n2 > 0 .and. n2 < n1
cRet := ""
cText := SubStr( cText, n2 + Len( '<' + cTag + '/>' ) + 1 )
elseif n1 > 0
c := SubStr( cText, n1 + Len( '<' + cTag + '>' ) + 1 )
n2 := At( '</' + cTag + '>', c )
if n2 > 0
cRet := Left( c, n2 - 1 )
cText := SubStr( c, n2 + Len( '<' + cTag + '/>' ) + 1 )
endif
endif
return cRet // nil -> tag not found, '' -> empty value
//----------------------------------------------------------------------------//
function DecodeBase64( cIn )
local cOut := ""
do while ! Empty( cIn )
cOut += b64_sub( Left( cIn, 4 ) )
cIn := SubStr( cIn, 5 )
enddo
return cOut
//----------------------------------------------------------------------------//
static function b64_sub( c4 )
static cRef := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
local a,b,c,d
local x,y,z
local cRet
c4 := Left( c4 + "==", 4 )
a := At( SubStr( c4, 1, 1 ), cRef ) - 1
b := At( SubStr( c4, 2, 1 ), cRef ) - 1
c := At( SubStr( c4, 3, 1 ), cRef ) - 1
d := At( SubStr( c4, 4, 1 ), cRef ) - 1
x := a * 4
x += Int( b / 16 )
if c == -1
return Chr( x )
endif
b := b % 16
y := b * 16
y += Int( c / 4 )
if d == -1
return Chr( x ) + Chr( y )
endif
c := c % 4
z := c * 64
z += d
return Chr( x ) + Chr( y ) + Chr( z )
//----------------------------------------------------------------------------//
BEGIN:VCARD
VERSION:2.1
N:Gump;Forrest
FN:Forrest Gump
ORG:Bubba Gump Shrimp Co.
TITLE:Shrimp Man
GENDER:M
PHOTO;TYPE=JPEG;ENCODING=BASE64:
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
4K0bWnxxm+fY/9k=
TEL;WORK;VOICE:(111) 555-1212
TEL;HOME;VOICE:(404) 555-1212
ADR;WORK:;;100 Waters Edge;Baytown;LA;30314;United States of America
LABEL;WORK;ENCODING=QUOTED-PRINTABLE:100 Waters Edge=0D=0ABaytown, LA 30314=0D=0AUnited States of
America
ADR;HOME:;;42 Plantation St.;Baytown;LA;30314;United States of America
LABEL;HOME;ENCODING=QUOTED-PRINTABLE:42 Plantation St.=0D=0ABaytown, LA 30314=0D=0AUnited States of
America
BDAY;:1972-10-15
EMAIL;PREF;INTERNET:forrestgump@example.com
REV:20080424T195243Z
END:VCARD
I do wonder why you use static functions instead of protected methods? I have found static functions to be a problem when trying to subclass in other FW classes.
Also, why the regular function instead of a protected method?
And, I haven't tested this yet, but it looks like your class cannot detect the preferred email address. Is this correct?
These functions/static functions are not part of the class. For my personal use they are separate library functions, to be used as library functions from any other applications. I included them here (with some changes in names and code) to make the sample complete. In some cases we can remove "static" restriction.
for each cAttr in { "TITLE", "GENDER", "KIND", "ORG", "ROLE", "NICKNAME", "NOTE" }
if c = cAttr + ';'
OSend( Self, "_c" + cAttr, cVal ) // ???
lAssigned := .t.
exit
endif
next
Return to FiveWin for Harbour/xHarbour
Users browsing this forum: jair and 44 guests