/// <summary> /// Builds the MAILER property. /// </summary> private void BuildProperties_MAILER( vCardPropertyCollection properties, vCard card) { // The MAILER property indicates the software that // generated the vCard. See section 2.4.3 of the // vCard 2.1 specification. Support is not widespread. if (!string.IsNullOrEmpty(card.Mailer)) { vCardProperty property = new vCardProperty("MAILER", card.Mailer); properties.Add(property); } }
private void BuildProperties_FN( vCardPropertyCollection properties, vCard card) { // The FN property indicates the formatted // name of the person. This can be something // like "John Smith". if (!string.IsNullOrEmpty(card.FormattedName)) { vCardProperty property = new vCardProperty("FN", card.FormattedName); properties.Add(property); } }
public void Constructor() { vCardProperty property = new vCardProperty(); Assert.IsNotNull( property.Subproperties, "The subproperties collection was not created."); Assert.IsEmpty( property.Subproperties, "The subproperties collection should be empty."); Assert.IsNull( property.Value, "The value should be null."); }
private void BuildProperties_LABEL( vCardPropertyCollection properties, vCard card) { foreach (vCardDeliveryLabel label in card.DeliveryLabels) { if (label.Text.Length > 0) { vCardProperty property = new vCardProperty("LABEL", label.Text); if (label.IsDomestic) { property.Subproperties.Add("TYPE", "DOM"); } if (label.IsInternational) { property.Subproperties.Add("TYPE", "INTL"); } if (label.IsParcel) { property.Subproperties.Add("TYPE", "PARCEL"); } if (label.IsPostal) { property.Subproperties.Add("TYPE", "POSTAL"); } if (label.IsHome) { property.Subproperties.Add("TYPE", "HOME"); } if (label.IsWork) { property.Subproperties.Add("TYPE", "WORK"); } // Don't use QUOTED-PRINTABLE. //property.Subproperties.Add("ENCODING", "QUOTED-PRINTABLE"); properties.Add(property); } } }
/// <summary> /// Builds KEY properties. /// </summary> private void BuildProperties_KEY( vCardPropertyCollection properties, vCard card) { // A KEY field contains an embedded security certificate. foreach (vCardCertificate certificate in card.Certificates) { vCardProperty property = new vCardProperty(); property.Name = "KEY"; property.Value = certificate.Data; property.Subproperties.Add("TYPE", certificate.KeyType); properties.Add(property); } }
/// <summary> /// Builds the BDAY property. /// </summary> private void BuildProperties_BDAY( vCardPropertyCollection properties, vCard card) { // The BDAY property indicates the birthdate // of the person. The output format here is based on // Microsoft Outlook, which writes the date as YYYMMDD. // FIXES DateFormat with ToString if (card.BirthDate.HasValue) { vCardProperty property = new vCardProperty("BDAY", card.BirthDate.Value.ToString("yyyy-MM-dd")); properties.Add(property); } }
/// <summary> /// Builds the GEO property. /// </summary> private void BuildProperties_GEO( vCardPropertyCollection properties, vCard card) { // The GEO properties contains the latitude and // longitude of the person or company of the vCard. if (card.Latitude.HasValue && card.Longitude.HasValue) { vCardProperty property = new vCardProperty(); property.Name = "GEO"; property.Value = card.Latitude.ToString() + ";" + card.Longitude.ToString(); properties.Add(property); } }
private void BuildProperties_TITLE( vCardPropertyCollection properties, vCard card) { // The TITLE property specifies the job title of // the person. Example: // // TITLE:Systems Analyst // TITLE:President if (!string.IsNullOrEmpty(card.Title)) { vCardProperty property = new vCardProperty("TITLE", card.Title); properties.Add(property); } }
/// <summary> /// Builds SOURCE properties. /// </summary> private void BuildProperties_SOURCE( vCardPropertyCollection properties, vCard card) { foreach (vCardSource source in card.Sources) { vCardProperty property = new vCardProperty(); property.Name = "SOURCE"; property.Value = source.Uri.ToString(); if (!string.IsNullOrEmpty(source.Context)) { property.Subproperties.Add("CONTEXT", source.Context); } properties.Add(property); } }
public void ReadProperty_String_QuotedPrintable() { const string encodedValue = "LABEL;" + "HOME;" + "ENCODING=QUOTED-PRINTABLE:" + "129 15th Street #3=0D=0A" + "Minneapolis, MN 55403=0D=0A" + "United States of America"; const string decodedValue = "129 15th Street #3\r\n" + "Minneapolis, MN 55403\r\n" + "United States of America"; vCardStandardReader reader = new vCardStandardReader(); // Read the property string. It should // be decoded by the reader. vCardProperty property = reader.ReadProperty(encodedValue); Assert.AreEqual( "LABEL", property.Name, "The name of the property should be LABEL."); Assert.IsTrue( property.Subproperties.Contains("HOME"), "The property should have a subproperty called HOME."); // Now for the big test. The loaded property // value should be decoded. It should not have the // quoted-printable escape sequences. Assert.AreEqual( decodedValue, property.ToString()); }
public void Constructor_Name() { vCardProperty property = new vCardProperty("NAME"); Assert.AreEqual( "NAME", property.Name, "The name is incorrect."); Assert.IsNull( property.Value, "The value should be null."); Assert.IsNotNull( property.Subproperties, "The subproperties collection was not created."); Assert.IsEmpty( property.Subproperties, "The subproperties collection should be empty."); }
private void BuildProperties_IMPP( vCardPropertyCollection properties, vCard card) { // Build IMPP and X-AIM properties foreach (vCardIMPP impp in card.IMs) { if (!string.IsNullOrEmpty(impp.Handle)) { vCardProperty propertyIMPP; vCardProperty propertyXAIM; if (impp.ServiceType == IMServiceType.AIM) { propertyIMPP = new vCardProperty("IMPP", "aim:" + impp.Handle); propertyIMPP.Subproperties.Add("X-SERVICE-TYPE", "AIM"); if (impp.ItemType == ItemType.HOME) { propertyIMPP.Subproperties.Add("TYPE", "HOME"); } if (impp.ItemType == ItemType.WORK) { propertyIMPP.Subproperties.Add("TYPE", "WORK"); } if (impp.IsPreferred) { propertyIMPP.Subproperties.Add("TYPE", "PREF"); } properties.Add(propertyIMPP); propertyXAIM = new vCardProperty("X-AIM", impp.Handle); properties.Add(propertyXAIM); } } } }
public void CanReadXmlvCard() { string xml = @"<?xml version=""1.0"" encoding=""utf-8""?> <vcards xmlns=""urn:ietf:params:xml:ns:vcard-4.0""> <vcard> <fn> <text>John Doe</text> </fn> <n> <surname><text>Doe</text></surname> <given><text>J.</text></given> </n> <email><text>[email protected]</text></email> <name><text>JohnDoe</text></name> <source><uri>http://www.somewhere.com</uri></source> <ex:why xmlns:ex=""http://here.net"">It is red</ex:why> <ex:where xmlns:ex=""http://here.net""> <uri>ldap://somefellow</uri> </ex:where> </vcard> </vcards>"; using (StringReader r = new StringReader(xml)) { vCardXmlReader reader = new vCardXmlReader(); vCard c = reader.Read(r, ParseExtensions); Assert.IsNotNull(c); Assert.AreEqual("John Doe", c.Fn.Default.Value); Assert.AreEqual("*****@*****.**", c.EMail.Default.Value); Assert.AreEqual("JohnDoe", c.Name); Assert.AreEqual("Doe", c.N.FamilyName); Assert.AreEqual("J.", c.N.GivenNames); Assert.AreEqual("http://www.somewhere.com", c.Source.Default.Value); vCardProperty p = c.GetExtendedProperty("why", "http://here.net"); Assert.IsNotNull(p); Assert.AreEqual("It is red", p.ToString()); } }
public void ReadProperty_String_Name_Subproperties_Value() { // This function tests the parser against a property // string with two subproperties. vCardStandardReader reader = new vCardStandardReader(); vCardProperty property = reader.ReadProperty("NAME;SUB1;SUB2:VALUE"); Assert.AreEqual( "NAME", property.Name, "The Name is incorrect."); Assert.AreEqual( 2, property.Subproperties.Count, "The Subproperties collection has an incorrect number of items."); Assert.AreEqual( "SUB1", property.Subproperties[0].Name, "The Subproperty[0] value is incorrect."); Assert.AreEqual( "SUB2", property.Subproperties[1].Name, "The Subproperty[1] value is incorrect."); Assert.AreEqual( "VALUE", property.Value, "The parsed value is incorrect."); }
public void ReadProperty_String_Name_Value() { // This function tests the parsing function // against a basic string like NAME:VALUE. vCardStandardReader reader = new vCardStandardReader(); vCardProperty property = reader.ReadProperty( TestName + ":" + TestValue); Assert.AreEqual( TestName, property.Name); Assert.AreEqual( TestValue, property.Value, "The parsed value is incorrect."); Assert.IsEmpty( property.Subproperties, "The Subproperties collection should be empty."); }
/// <summary> /// Builds the NOTE property. /// </summary> private void BuildProperties_NOTE( vCardPropertyCollection properties, vCard card) { foreach (vCardNote note in card.Notes) { if (!string.IsNullOrEmpty(note.Text)) { vCardProperty property = new vCardProperty(); property.Name = "NOTE"; property.Value = note.Text; if (!string.IsNullOrEmpty(note.Language)) { property.Subproperties.Add("language", note.Language); } // Don't use QUOTED-PRINTABLE since it is deprecated //property.Subproperties.Add("ENCODING", "QUOTED-PRINTABLE"); properties.Add(property); } } }
private void BuildProperties_TITLE( vCardPropertyCollection properties, vCard card) { // The TITLE property specifies the job title of // the person. Example: // // TITLE:Systems Analyst // TITLE:President if (!string.IsNullOrEmpty(card.Title)) { vCardProperty property = new vCardProperty("TITLE", card.Title); properties.Add(property); } }
/// <summary> /// Builds TEL properties. /// </summary> private void BuildProperties_TEL( vCardPropertyCollection properties, vCard card) { // The TEL property indicates a telephone number of // the person (including non-voice numbers like fax // and BBS numbers). // // TEL;VOICE;WORK:1-800-929-5805 foreach (vCardPhone phone in card.Phones) { // A telephone entry has the property name TEL and // can have zero or more subproperties like FAX // or HOME. Examples: // // TEL;HOME:+1-612-555-1212 // TEL;FAX;HOME:+1-612-555-1212 vCardProperty property = new vCardProperty(); property.Name = "TEL"; if (phone.IsBBS) property.Subproperties.Add("BBS"); if (phone.IsCar) property.Subproperties.Add("CAR"); if (phone.IsCellular) property.Subproperties.Add("CELL"); if (phone.IsFax) property.Subproperties.Add("FAX"); if (phone.IsHome) property.Subproperties.Add("HOME"); if (phone.IsISDN) property.Subproperties.Add("ISDN"); if (phone.IsMessagingService) property.Subproperties.Add("MSG"); if (phone.IsModem) property.Subproperties.Add("MODEM"); if (phone.IsPager) property.Subproperties.Add("PAGER"); if (phone.IsPreferred) property.Subproperties.Add("PREF"); if (phone.IsVideo) property.Subproperties.Add("VIDEO"); if (phone.IsVoice) property.Subproperties.Add("VOICE"); if (phone.IsWork) property.Subproperties.Add("WORK"); property.Value = phone.FullNumber; properties.Add(property); } }
/// <summary> /// Builds SOURCE properties. /// </summary> private void BuildProperties_SOURCE( vCardPropertyCollection properties, vCard card) { foreach (vCardSource source in card.Sources) { vCardProperty property = new vCardProperty(); property.Name = "SOURCE"; property.Value = source.Uri.ToString(); if (!string.IsNullOrEmpty(source.Context)) property.Subproperties.Add("CONTEXT", source.Context); properties.Add(property); } }
private void BuildProperties_PHOTO( vCardPropertyCollection properties, vCard card) { foreach (vCardPhoto photo in card.Photos) { if (photo.Url == null) { // This photo does not have a URL associated // with it. Therefore a property can be // generated only if the image data is loaded. // Otherwise there is not enough information. if (photo.IsLoaded) { properties.Add( new vCardProperty("PHOTO", photo.GetBytes())); } } else { // This photo has a URL associated with it. The // PHOTO property can either be linked as an image // or embedded, if desired. bool doEmbedded = photo.Url.IsFile ? this.embedLocalImages : this.embedInternetImages; if (doEmbedded) { // According to the settings of the card writer, // this linked image should be embedded into the // vCard data. Attempt to fetch the data. try { photo.Fetch(); } catch { // An error was encountered. The image can // still be written as a link, however. doEmbedded = false; } } // At this point, doEmbedded is true only if (a) the // writer was configured to embed the image, and (b) // the image was successfully downloaded. if (doEmbedded) { properties.Add( new vCardProperty("PHOTO", photo.GetBytes())); } else { vCardProperty uriPhotoProperty = new vCardProperty("PHOTO"); // Set the VALUE property to indicate that // the data for the photo is a URI. uriPhotoProperty.Subproperties.Add("VALUE", "URI"); uriPhotoProperty.Value = photo.Url.ToString(); properties.Add(uriPhotoProperty); } } } }
private void BuildProperties_FN( vCardPropertyCollection properties, vCard card) { // The FN property indicates the formatted // name of the person. This can be something // like "John Smith". if (!string.IsNullOrEmpty(card.FormattedName)) { vCardProperty property = new vCardProperty("FN", card.FormattedName); properties.Add(property); } }
private void BuildProperties_CLASS( vCardPropertyCollection properties, vCard card) { vCardProperty property = new vCardProperty("CLASS"); switch (card.AccessClassification) { case vCardAccessClassification.Unknown: // No value is written. return; case vCardAccessClassification.Confidential: property.Value = "CONFIDENTIAL"; break; case vCardAccessClassification.Private: property.Value = "PRIVATE"; break; case vCardAccessClassification.Public: property.Value = "PUBLIC"; break; default: throw new NotSupportedException(); } properties.Add(property); }
/// <summary> /// Builds ADR properties. /// </summary> private void BuildProperties_ADR( vCardPropertyCollection properties, vCard card) { foreach (vCardDeliveryAddress address in card.DeliveryAddresses) { // Do not generate a postal address (ADR) property // if the entire address is blank. if ( (!string.IsNullOrEmpty(address.City)) || (!string.IsNullOrEmpty(address.Country)) || (!string.IsNullOrEmpty(address.PostalCode)) || (!string.IsNullOrEmpty(address.Region)) || (!string.IsNullOrEmpty(address.Street))) { // The ADR property contains the following // subvalues in order. All are required: // // - Post office box // - Extended address // - Street address // - Locality (e.g. city) // - Region (e.g. province or state) // - Postal code (e.g. ZIP code) // - Country name vCardValueCollection values = new vCardValueCollection(';'); values.Add(string.Empty); values.Add(string.Empty); values.Add(address.Street); values.Add(address.City); values.Add(address.Region); values.Add(address.PostalCode); values.Add(address.Country); vCardProperty property = new vCardProperty("ADR", values); if (address.IsDomestic) property.Subproperties.Add("DOM"); if (address.IsInternational) property.Subproperties.Add("INTL"); if (address.IsParcel) property.Subproperties.Add("PARCEL"); if (address.IsPostal) property.Subproperties.Add("POSTAL"); if (address.IsHome) property.Subproperties.Add("HOME"); if (address.IsWork) property.Subproperties.Add("WORK"); properties.Add(property); } } }
private void BuildProperties_PHOTO( vCardPropertyCollection properties, vCard card) { foreach (vCardPhoto photo in card.Photos) { if (photo.Url == null) { // This photo does not have a URL associated // with it. Therefore a property can be // generated only if the image data is loaded. // Otherwise there is not enough information. if (photo.IsLoaded) { properties.Add( new vCardProperty("PHOTO", photo.GetBytes())); } } else { // This photo has a URL associated with it. The // PHOTO property can either be linked as an image // or embedded, if desired. bool doEmbedded = photo.Url.IsFile ? this.embedLocalImages : this.embedInternetImages; if (doEmbedded) { // According to the settings of the card writer, // this linked image should be embedded into the // vCard data. Attempt to fetch the data. try { //photo.Fetch(); // PCL } catch { // An error was encountered. The image can // still be written as a link, however. doEmbedded = false; } } // At this point, doEmbedded is true only if (a) the // writer was configured to embed the image, and (b) // the image was successfully downloaded. if (doEmbedded) { properties.Add( new vCardProperty("PHOTO", photo.GetBytes())); } else { vCardProperty uriPhotoProperty = new vCardProperty("PHOTO"); // Set the VALUE property to indicate that // the data for the photo is a URI. uriPhotoProperty.Subproperties.Add("VALUE", "URI"); uriPhotoProperty.Value = photo.Url.ToString(); properties.Add(uriPhotoProperty); } } } }
/// <summary> /// Builds the NOTE property. /// </summary> private void BuildProperties_NOTE( vCardPropertyCollection properties, vCard card) { foreach (vCardNote note in card.Notes) { if (!string.IsNullOrEmpty(note.Text)) { vCardProperty property = new vCardProperty(); property.Name = "NOTE"; property.Value = note.Text; if (!string.IsNullOrEmpty(note.Language)) { property.Subproperties.Add("language", note.Language); } property.Subproperties.Add("ENCODING", "QUOTED-PRINTABLE"); properties.Add(property); } } }
private void BuildProperties_NAME( vCardPropertyCollection properties, vCard card) { if (!string.IsNullOrEmpty(card.DisplayName)) { vCardProperty property = new vCardProperty("NAME", card.DisplayName); properties.Add(property); } }
/// <summary> /// Builds the MAILER property. /// </summary> private void BuildProperties_MAILER( vCardPropertyCollection properties, vCard card) { // The MAILER property indicates the software that // generated the vCard. See section 2.4.3 of the // vCard 2.1 specification. Support is not widespread. if (!string.IsNullOrEmpty(card.Mailer)) { vCardProperty property = new vCardProperty("MAILER", card.Mailer); properties.Add(property); } }
/// <summary> /// Builds KEY properties. /// </summary> private void BuildProperties_KEY( vCardPropertyCollection properties, vCard card) { // A KEY field contains an embedded security certificate. foreach (vCardCertificate certificate in card.Certificates) { vCardProperty property = new vCardProperty(); property.Name = "KEY"; property.Value = certificate.Data; property.Subproperties.Add(certificate.KeyType); properties.Add(property); } }
/// <summary> /// Builds ADR properties. /// </summary> private void BuildProperties_ADR( vCardPropertyCollection properties, vCard card) { foreach (vCardDeliveryAddress address in card.DeliveryAddresses) { // Do not generate a postal address (ADR) property // if the entire address is blank. if ( (!string.IsNullOrEmpty(address.City)) || (!string.IsNullOrEmpty(address.Country)) || (!string.IsNullOrEmpty(address.PostalCode)) || (!string.IsNullOrEmpty(address.Region)) || (!string.IsNullOrEmpty(address.Street))) { // The ADR property contains the following // subvalues in order. All are required: // // - Post office box // - Extended address // - Street address // - Locality (e.g. city) // - Region (e.g. province or state) // - Postal code (e.g. ZIP code) // - Country name vCardValueCollection values = new vCardValueCollection(';'); values.Add(string.Empty); values.Add(string.Empty); values.Add(address.Street); values.Add(address.City); values.Add(address.Region); values.Add(address.PostalCode); values.Add(address.Country); vCardProperty property = new vCardProperty("ADR", values); if (address.IsDomestic) { property.Subproperties.Add("TYPE", "DOM"); } if (address.IsInternational) { property.Subproperties.Add("TYPE", "INTL"); } if (address.IsParcel) { property.Subproperties.Add("TYPE", "PARCEL"); } if (address.IsPostal) { property.Subproperties.Add("TYPE", "POSTAL"); } if (address.IsHome) { property.Subproperties.Add("TYPE", "HOME"); } if (address.IsWork) { property.Subproperties.Add("TYPE", "WORK"); } properties.Add(property); } } }
/// <summary> /// Builds EMAIL properties. /// </summary> private void BuildProperties_EMAIL( vCardPropertyCollection properties, vCard card) { // The EMAIL property contains an electronic // mail address for the purpose. A vCard may contain // as many email addresses as needed. The format also // supports various vendors, such as CompuServe addresses // and Internet SMTP addresses. // // EMAIL;INTERNET:[email protected] foreach (vCardEmailAddress emailAddress in card.EmailAddresses) { vCardProperty property = new vCardProperty(); property.Name = "EMAIL"; property.Value = emailAddress.Address; if (emailAddress.IsPreferred) { property.Subproperties.Add("TYPE", "PREF"); } switch (emailAddress.EmailType) { case vCardEmailAddressType.Internet: property.Subproperties.Add("TYPE", "INTERNET"); break; case vCardEmailAddressType.AOL: property.Subproperties.Add("TYPE", "AOL"); break; case vCardEmailAddressType.AppleLink: property.Subproperties.Add("TYPE", "AppleLink"); break; case vCardEmailAddressType.AttMail: property.Subproperties.Add("TYPE", "ATTMail"); break; case vCardEmailAddressType.CompuServe: property.Subproperties.Add("TYPE", "CIS"); break; case vCardEmailAddressType.eWorld: property.Subproperties.Add("TYPE", "eWorld"); break; case vCardEmailAddressType.IBMMail: property.Subproperties.Add("TYPE", "IBMMail"); break; case vCardEmailAddressType.MCIMail: property.Subproperties.Add("TYPE", "MCIMail"); break; case vCardEmailAddressType.PowerShare: property.Subproperties.Add("TYPE", "POWERSHARE"); break; case vCardEmailAddressType.Prodigy: property.Subproperties.Add("TYPE", "PRODIGY"); break; case vCardEmailAddressType.Telex: property.Subproperties.Add("TYPE", "TLX"); break; case vCardEmailAddressType.X400: property.Subproperties.Add("TYPE", "X400"); break; default: property.Subproperties.Add("TYPE", "INTERNET"); break; } properties.Add(property); } }
private void BuildProperties_URL( vCardPropertyCollection properties, vCard card) { foreach (vCardWebsite webSite in card.Websites) { if (!string.IsNullOrEmpty(webSite.Url)) { vCardProperty property = new vCardProperty("URL", webSite.Url.ToString()); if (webSite.IsWorkSite) property.Subproperties.Add("WORK"); properties.Add(property); } } }
/// <summary> /// Returns property encoded into a standard vCard NAME:VALUE format. /// </summary> public string EncodeProperty(vCardProperty property) { if (property == null) throw new ArgumentNullException("property"); if (string.IsNullOrEmpty(property.Name)) throw new ArgumentException(); StringBuilder builder = new StringBuilder(); builder.Append(property.Name); foreach (vCardSubproperty subproperty in property.Subproperties) { builder.Append(';'); builder.Append(subproperty.Name); if (!string.IsNullOrEmpty(subproperty.Value)) { builder.Append('='); builder.Append(subproperty.Value); } } // The property name and all subproperties have been // written to the string builder (the colon separator // has not been written). The next step is to write // the value. Depending on the type of value and any // characters in the value, it may be necessary to // use an non-default encoding. For example, byte arrays // are written encoded in BASE64. if (property.Value == null) { builder.Append(':'); } else { Type valueType = property.Value.GetType(); if (valueType == typeof(byte[])) { // A byte array should be encoded in BASE64 format. builder.Append(";ENCODING=BASE64:"); builder.Append(EncodeBase64((byte[])property.Value)); } else if (valueType == typeof(vCardValueCollection)) { vCardValueCollection values = (vCardValueCollection)property.Value; builder.Append(':'); for (int index = 0; index < values.Count; index++) { builder.Append(EncodeEscaped(values[index])); if (index < values.Count - 1) { builder.Append(values.Separator); } } } else { // The object will be converted to a string (if it is // not a string already) and encoded if necessary. // The first step is to get the string value. string stringValue = null; if (valueType == typeof(char[])) { stringValue = new string(((char[])property.Value)); } else { stringValue = property.Value.ToString(); } builder.Append(':'); switch (property.Subproperties.GetValue("ENCODING")) { case "QUOTED-PRINTABLE": builder.Append(EncodeQuotedPrintable(stringValue)); break; default: builder.Append(EncodeEscaped(stringValue)); break; } } } return builder.ToString(); }
/// <summary> /// Builds the REV property. /// </summary> private void BuildProperties_REV( vCardPropertyCollection properties, vCard card) { if (card.RevisionDate.HasValue) { vCardProperty property = new vCardProperty("REV", card.RevisionDate.Value.ToString()); properties.Add(property); } }
/// <summary> /// Builds the BDAY property. /// </summary> private void BuildProperties_BDAY( vCardPropertyCollection properties, vCard card) { // The BDAY property indicates the birthdate // of the person. The output format here is based on // Microsoft Outlook, which writes the date as YYYMMDD. if (card.BirthDate.HasValue) { vCardProperty property = new vCardProperty("BDAY", card.BirthDate.Value); properties.Add(property); } }
/// <summary> /// Returns property encoded into a standard vCard NAME:VALUE format. /// </summary> public string EncodeProperty(vCardProperty property) { if (property == null) { throw new ArgumentNullException("property"); } if (string.IsNullOrEmpty(property.Name)) { throw new ArgumentException(); } StringBuilder builder = new StringBuilder(); builder.Append(property.Name); foreach (vCardSubproperty subproperty in property.Subproperties) { builder.Append(';'); builder.Append(subproperty.Name); if (!string.IsNullOrEmpty(subproperty.Value)) { builder.Append('='); builder.Append(subproperty.Value); } } // The property name and all subproperties have been // written to the string builder (the colon separator // has not been written). The next step is to write // the value. Depending on the type of value and any // characters in the value, it may be necessary to // use an non-default encoding. For example, byte arrays // are written encoded in BASE64. if (property.Value == null) { builder.Append(':'); } else { Type valueType = property.Value.GetType(); if (valueType == typeof(byte[])) { // A byte array should be encoded in BASE64 format. builder.Append(";ENCODING=b:"); builder.Append(EncodeBase64((byte[])property.Value)); } else if (valueType == typeof(vCardValueCollection)) { vCardValueCollection values = (vCardValueCollection)property.Value; builder.Append(':'); for (int index = 0; index < values.Count; index++) { builder.Append(EncodeEscaped(values[index])); if (index < values.Count - 1) { builder.Append(values.Separator); } } } else { // The object will be converted to a string (if it is // not a string already) and encoded if necessary. // The first step is to get the string value. string stringValue = null; if (valueType == typeof(char[])) { stringValue = new string(((char[])property.Value)); } else { stringValue = property.Value.ToString(); } builder.Append(':'); switch (property.Subproperties.GetValue("ENCODING")) { case "QUOTED-PRINTABLE": builder.Append(EncodeQuotedPrintable(stringValue)); break; default: builder.Append(EncodeEscaped(stringValue)); break; } } } return(builder.ToString()); }
/// <summary> /// Builds EMAIL properties. /// </summary> private void BuildProperties_EMAIL( vCardPropertyCollection properties, vCard card) { // The EMAIL property contains an electronic // mail address for the purpose. A vCard may contain // as many email addresses as needed. The format also // supports various vendors, such as CompuServe addresses // and Internet SMTP addresses. // // EMAIL;INTERNET:[email protected] foreach (vCardEmailAddress emailAddress in card.EmailAddresses) { vCardProperty property = new vCardProperty(); property.Name = "EMAIL"; property.Value = emailAddress.Address; if (emailAddress.IsPreferred) { property.Subproperties.Add("PREF"); } switch (emailAddress.EmailType) { case vCardEmailAddressType.Internet: property.Subproperties.Add("INTERNET"); break; case vCardEmailAddressType.AOL: property.Subproperties.Add("AOL"); break; case vCardEmailAddressType.AppleLink: property.Subproperties.Add("AppleLink"); break; case vCardEmailAddressType.AttMail: property.Subproperties.Add("ATTMail"); break; case vCardEmailAddressType.CompuServe: property.Subproperties.Add("CIS"); break; case vCardEmailAddressType.eWorld: property.Subproperties.Add("eWorld"); break; case vCardEmailAddressType.IBMMail: property.Subproperties.Add("IBMMail"); break; case vCardEmailAddressType.MCIMail: property.Subproperties.Add("MCIMail"); break; case vCardEmailAddressType.PowerShare: property.Subproperties.Add("POWERSHARE"); break; case vCardEmailAddressType.Prodigy: property.Subproperties.Add("PRODIGY"); break; case vCardEmailAddressType.Telex: property.Subproperties.Add("TLX"); break; case vCardEmailAddressType.X400: property.Subproperties.Add("X400"); break; default: property.Subproperties.Add("INTERNET"); break; } properties.Add(property); } }
/// <summary> /// Updates a vCard object based on the contents of a vCardProperty. /// </summary> /// <param name="card"> /// An initialized vCard object. /// </param> /// <param name="property"> /// An initialized vCardProperty object. /// </param> /// <remarks> /// <para> /// This method examines the contents of a property /// and attempts to update an existing vCard based on /// the property name and value. This function must /// be updated when new vCard properties are implemented. /// </para> /// </remarks> public void ReadInto(vCard card, vCardProperty property) { if (card == null) throw new ArgumentNullException("card"); if (property == null) throw new ArgumentNullException("property"); if (string.IsNullOrEmpty(property.Name)) return; switch (property.Name.ToUpperInvariant()) { case "ADR": ReadInto_ADR(card, property); break; case "BDAY": ReadInto_BDAY(card, property); break; case "CATEGORIES": ReadInto_CATEGORIES(card, property); break; case "CLASS": ReadInto_CLASS(card, property); break; case "EMAIL": ReadInto_EMAIL(card, property); break; case "FN": ReadInto_FN(card, property); break; case "GEO": ReadInto_GEO(card, property); break; case "KEY": ReadInto_KEY(card, property); break; case "LABEL": ReadInto_LABEL(card, property); break; case "MAILER": ReadInto_MAILER(card, property); break; case "N": ReadInto_N(card, property); break; case "NAME": ReadInto_NAME(card, property); break; case "NICKNAME": ReadInto_NICKNAME(card, property); break; case "NOTE": ReadInto_NOTE(card, property); break; case "ORG": ReadInto_ORG(card, property); break; case "PHOTO": ReadInto_PHOTO(card, property); break; case "PRODID": ReadInto_PRODID(card, property); break; case "REV": ReadInto_REV(card, property); break; case "ROLE": ReadInto_ROLE(card, property); break; case "SOURCE": ReadInto_SOURCE(card, property); break; case "TEL": ReadInto_TEL(card, property); break; case "TITLE": ReadInto_TITLE(card, property); break; case "TZ": ReadInto_TZ(card, property); break; case "UID": ReadInto_UID(card, property); break; case "URL": ReadInto_URL(card, property); break; case "X-WAB-GENDER": ReadInto_X_WAB_GENDER(card, property); break; default: // The property name is not recognized and // will be ignored. break; } }
/// <summary> /// Builds the GEO property. /// </summary> private void BuildProperties_GEO( vCardPropertyCollection properties, vCard card) { // The GEO properties contains the latitude and // longitude of the person or company of the vCard. if (card.Latitude.HasValue && card.Longitude.HasValue) { vCardProperty property = new vCardProperty(); property.Name = "GEO"; property.Value = card.Latitude.ToString() + ";" + card.Longitude.ToString(); properties.Add(property); } }
/// <summary> /// Builds TEL properties. /// </summary> private void BuildProperties_TEL( vCardPropertyCollection properties, vCard card) { // The TEL property indicates a telephone number of // the person (including non-voice numbers like fax // and BBS numbers). // // TEL;VOICE;WORK:1-800-929-5805 foreach (vCardPhone phone in card.Phones) { // A telephone entry has the property name TEL and // can have zero or more subproperties like FAX // or HOME. Examples: // // TEL;HOME:+1-612-555-1212 // TEL;FAX;HOME:+1-612-555-1212 vCardProperty property = new vCardProperty(); property.Name = "TEL"; if (phone.IsBBS) { property.Subproperties.Add("TYPE", "BBS"); } if (phone.IsCar) { property.Subproperties.Add("TYPE", "CAR"); } if (phone.IsCellular) { property.Subproperties.Add("TYPE", "CELL"); } if (phone.IsFax) { property.Subproperties.Add("TYPE", "FAX"); } if (phone.IsHome) { property.Subproperties.Add("TYPE", "HOME"); } if (phone.IsISDN) { property.Subproperties.Add("TYPE", "ISDN"); } if (phone.IsMessagingService) { property.Subproperties.Add("TYPE", "MSG"); } if (phone.IsModem) { property.Subproperties.Add("TYPE", "MODEM"); } if (phone.IsPager) { property.Subproperties.Add("TYPE", "PAGER"); } if (phone.IsPreferred) { property.Subproperties.Add("TYPE", "PREF"); } if (phone.IsVideo) { property.Subproperties.Add("TYPE", "VIDEO"); } if (phone.IsVoice) { property.Subproperties.Add("TYPE", "VOICE"); } if (phone.IsWork) { property.Subproperties.Add("TYPE", "WORK"); } property.Value = phone.FullNumber; properties.Add(property); } }
private void BuildProperties_LABEL( vCardPropertyCollection properties, vCard card) { foreach (vCardDeliveryLabel label in card.DeliveryLabels) { if (label.Text.Length > 0) { vCardProperty property = new vCardProperty("LABEL", label.Text); if (label.IsDomestic) property.Subproperties.Add("DOM"); if (label.IsInternational) property.Subproperties.Add("INTL"); if (label.IsParcel) property.Subproperties.Add("PARCEL"); if (label.IsPostal) property.Subproperties.Add("POSTAL"); if (label.IsHome) property.Subproperties.Add("HOME"); if (label.IsWork) property.Subproperties.Add("WORK"); // Give a hint to use QUOTED-PRINTABLE. property.Subproperties.Add("ENCODING", "QUOTED-PRINTABLE"); properties.Add(property); } } }
/// <summary> /// Reads the TITLE property. /// </summary> private void ReadInto_TITLE(vCard card, vCardProperty property) { // The TITLE property defines the job title of the // person. This should not be confused by the name // prefix (e.g. "Mr"), which is called "Title" in // some vCard-compatible software like Outlook. card.Title = property.ToString(); }
private void BuildProperties_N( vCardPropertyCollection properties, vCard card) { // The property has the following components: Family Name, // Given Name, Additional Names, Name Prefix, and Name // Suffix. Example: // // N:Pinch;David // N:Pinch;David;John // // The N property is required (see section 3.1.2 of RFC 2426). vCardValueCollection values = new vCardValueCollection(';'); values.Add(card.FamilyName); values.Add(card.GivenName); values.Add(card.AdditionalNames); values.Add(card.NamePrefix); values.Add(card.NameSuffix); vCardProperty property = new vCardProperty("N", values); properties.Add(property); }
/// <summary> /// Reads a TZ property. /// </summary> private void ReadInto_TZ(vCard card, vCardProperty property) { card.TimeZone = property.ToString(); }
/// <summary> /// Builds the NICKNAME property. /// </summary> private void BuildProperties_NICKNAME( vCardPropertyCollection properties, vCard card) { // The NICKNAME property specifies the familiar name // of the person, such as Jim. This is defined in // section 3.1.3 of RFC 2426. Multiple names can // be listed, separated by commas. if (card.Nicknames.Count > 0) { // A NICKNAME property is a comma-separated // list of values. Create a value list and // add the nicknames collection to it. vCardValueCollection values = new vCardValueCollection(','); values.Add(card.Nicknames); // Create the new properties with each name separated // by a comma. vCardProperty property = new vCardProperty("NICKNAME", values); properties.Add(property); } }
/// <summary> /// Reads the UID property. /// </summary> private void ReadInto_UID(vCard card, vCardProperty property) { card.UniqueId = property.ToString(); }
/// <summary> /// Builds the ORG property. /// </summary> private void BuildProperties_ORG( vCardPropertyCollection properties, vCard card) { // The ORG property specifies the name of the // person's company or organization. Example: // // ORG:FairMetric LLC if (!string.IsNullOrEmpty(card.Organization)) { vCardProperty property = new vCardProperty("ORG", card.Organization); properties.Add(property); } }
/// <summary> /// Reads the URL property. /// </summary> private void ReadInto_URL(vCard card, vCardProperty property) { vCardWebsite webSite = new vCardWebsite(); webSite.Url = property.ToString(); if (property.Subproperties.Contains("HOME")) webSite.IsPersonalSite = true; if (property.Subproperties.Contains("WORK")) webSite.IsWorkSite = true; card.Websites.Add(webSite); }
/// <summary> /// Builds PRODID properties. /// </summary> private void BuildProperties_PRODID( vCardPropertyCollection properties, vCard card) { if (!string.IsNullOrEmpty(card.ProductId)) { vCardProperty property = new vCardProperty(); property.Name = "PRODID"; property.Value = card.ProductId; properties.Add(property); } }
/// <summary> /// Reads the X-WAB-GENDER property. /// </summary> private void ReadInto_X_WAB_GENDER(vCard card, vCardProperty property) { // The X-WAB-GENDER property is a custom property generated by // Microsoft Outlook 2003. It contains the value 1 for females // or 2 for males. It is not known if other PIM clients // recognize this value. int genderId; if (int.TryParse(property.ToString(), out genderId)) { switch (genderId) { case 1: card.Gender = vCardGender.Female; break; case 2: card.Gender = vCardGender.Male; break; } } }
/// <summary> /// Builds the ROLE property. /// </summary> private void BuildProperties_ROLE( vCardPropertyCollection properties, vCard card) { // The ROLE property identifies the role of // the person at his/her organization. if (!string.IsNullOrEmpty(card.Role)) { vCardProperty property = new vCardProperty("ROLE", card.Role); properties.Add(property); } }
/// <summary> /// Reads a property from a text reader. /// </summary> public vCardProperty ReadProperty(TextReader reader) { if (reader == null) throw new ArgumentNullException("reader"); do { // Read the first line of the next property // from the input stream. If a null string // is returned, then the end of the input // stream has been reached. string firstLine = reader.ReadLine(); if (firstLine == null) return null; // See if this line is a blank line. It is // blank if (a) it has no characters, or (b) // it consists of whitespace characters only. firstLine = firstLine.Trim(); if (firstLine.Length == 0) { Warnings.Add(WarningMessage.BlankLine); continue; } // Get the index of the colon (:) in this // property line. All vCard properties are // written in NAME:VALUE format. int colonIndex = firstLine.IndexOf(':'); if (colonIndex == -1) { Warnings.Add(WarningMessage.ColonMissing); continue; } // Get the name portion of the property. This // portion contains the property name as well // as any subproperties. string namePart = firstLine.Substring(0, colonIndex).Trim(); if (string.IsNullOrEmpty(namePart)) { Warnings.Add(WarningMessage.EmptyName); continue; } // Split apart the name portion of the property. // A property can have subproperties, separated // by semicolons. string[] nameParts = namePart.Split(';'); for (int i = 0; i < nameParts.Length; i++) nameParts[i] = nameParts[i].Trim(); // The name of the property is supposed to // be first on the line. An empty name is not // legal syntax. if (nameParts[0].Length == 0) { Warnings.Add(WarningMessage.EmptyName); continue; } // At this point there is sufficient text // to define a vCard property. The only // true minimum requirement is a name. vCardProperty property = new vCardProperty(); property.Name = nameParts[0]; // Next, store any subproperties. Subproperties // are defined like "NAME;SUBNAME=VALUE:VALUE". Note // that subproperties do not necessarily have to have // a subvalue. for (int index = 1; index < nameParts.Length; index++) { // Split the subproperty into its name and // value components. If multiple equal signs // happen to exist, they are interpreted as // part of the value. This may change in a // future version of the parser. string[] subNameValue = nameParts[index].Split(new char[] { '=' }, 2); if (subNameValue.Length == 1) { // The Split function above returned a single // array element. This means no equal (=) sign // was present. The subproperty consists of // a name only. property.Subproperties.Add( nameParts[index].Trim()); } else { property.Subproperties.Add( subNameValue[0].Trim(), subNameValue[1].Trim()); } } // The subproperties have been defined. The next // step is to try to identify the encoding of the // value. The encoding is supposed to be specified // with a subproperty called ENCODING. However, older // versions of the format just wrote the plain // encoding value, e.g. "NAME;BASE64:VALUE" instead // of the normalized "NAME;ENCODING=BASE64:VALUE" form. string encodingName = property.Subproperties.GetValue("ENCODING", new string[] { "B", "BASE64", "QUOTED-PRINTABLE" }); // Convert the encoding name into its corresponding // vCardEncoding enumeration value. vCardEncoding encoding = ParseEncoding(encodingName); // At this point, the first line of the property has been // loaded and the suggested value encoding has been // determined. Get the raw value as encoded in the file. string rawValue = firstLine.Substring(colonIndex + 1); // The vCard specification allows long values // to be folded across multiple lines. An example // is a security key encoded in MIME format. // When folded, each subsequent line begins with // a space or tab character instead of the next property. // // See: RFC 2425, Section 5.8.1 do { int peekChar = reader.Peek(); if ((peekChar == 32) || (peekChar == 9)) { string foldedLine = reader.ReadLine(); rawValue += foldedLine.Substring(1); } else { break; } } while (true); if (encoding == vCardEncoding.QuotedPrintable && rawValue.Length > 0) { while (rawValue[rawValue.Length - 1] == '=') { rawValue += "\r\n" + reader.ReadLine(); } } // The full value has finally been loaded from the // input stream. The next step is to decode it. switch (encoding) { case vCardEncoding.Base64: property.Value = DecodeBase64(rawValue); break; case vCardEncoding.Escaped: property.Value = DecodeEscaped(rawValue); break; case vCardEncoding.QuotedPrintable: property.Value = DecodeQuotedPrintable(rawValue); break; default: property.Value = DecodeEscaped(rawValue); break; } return property; } while (true); }