00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "ldif.h"
00023 #include "record.h"
00024 #include "r_contact.h"
00025 #include "base64.h"
00026 #include <stdexcept>
00027 #include <iostream>
00028 #include <iomanip>
00029 #include <string.h>
00030 #include "ios_state.h"
00031
00032 #define __DEBUG_MODE__
00033 #include "debug.h"
00034
00035 namespace Barry {
00036
00037 const ContactLdif::NameToFunc ContactLdif::FieldMap[] = {
00038 { "Email", "Email address",
00039 &ContactLdif::Email, &ContactLdif::SetEmail },
00040 { "Phone", "Phone number",
00041 &ContactLdif::Phone, &ContactLdif::SetPhone },
00042 { "Fax", "Fax number",
00043 &ContactLdif::Fax, &ContactLdif::SetFax },
00044 { "WorkPhone", "Work phone number",
00045 &ContactLdif::WorkPhone, &ContactLdif::SetWorkPhone },
00046 { "HomePhone", "Home phone number",
00047 &ContactLdif::HomePhone, &ContactLdif::SetHomePhone },
00048 { "MobilePhone", "Mobile phone number",
00049 &ContactLdif::MobilePhone, &ContactLdif::SetMobilePhone },
00050 { "Pager", "Pager number",
00051 &ContactLdif::Pager, &ContactLdif::SetPager },
00052 { "PIN", "PIN",
00053 &ContactLdif::PIN, &ContactLdif::SetPIN },
00054 { "FirstName", "First name",
00055 &ContactLdif::FirstName, &ContactLdif::SetFirstName },
00056 { "LastName", "Last name",
00057 &ContactLdif::LastName, &ContactLdif::SetLastName },
00058 { "Company", "Company name",
00059 &ContactLdif::Company, &ContactLdif::SetCompany },
00060 { "DefaultCommunicationsMethod", "Default communications method",
00061 &ContactLdif::DefaultCommunicationsMethod, &ContactLdif::SetDefaultCommunicationsMethod },
00062 { "WorkAddress1", "Work Address, line 1",
00063 &ContactLdif::WorkAddress1, &ContactLdif::SetWorkAddress1 },
00064 { "WorkAddress2", "Work Address, line 2",
00065 &ContactLdif::WorkAddress2, &ContactLdif::SetWorkAddress2 },
00066 { "WorkAddress3", "Work Address, line 3",
00067 &ContactLdif::WorkAddress3, &ContactLdif::SetWorkAddress3 },
00068 { "WorkCity", "WorkCity",
00069 &ContactLdif::WorkCity, &ContactLdif::SetWorkCity },
00070 { "WorkProvince", "WorkProvince / State",
00071 &ContactLdif::WorkProvince, &ContactLdif::SetWorkProvince },
00072 { "WorkPostalCode", "Work Postal / ZIP code",
00073 &ContactLdif::WorkPostalCode, &ContactLdif::SetWorkPostalCode },
00074 { "WorkCountry", "WorkCountry",
00075 &ContactLdif::WorkCountry, &ContactLdif::SetWorkCountry },
00076 { "JobTitle", "Job Title",
00077 &ContactLdif::JobTitle, &ContactLdif::SetJobTitle },
00078 { "PublicKey", "Public key",
00079 &ContactLdif::PublicKey, &ContactLdif::SetPublicKey },
00080 { "Notes", "Notes",
00081 &ContactLdif::Notes, &ContactLdif::SetNotes },
00082 { "Image", "Contact photo",
00083 &ContactLdif::Image, &ContactLdif::SetImage },
00084 { "WorkPostalAddress", "Mailing Work address (includes address lines, city, province, country, and postal code)",
00085 &ContactLdif::WorkPostalAddress, &ContactLdif::SetWorkPostalAddress },
00086 { "HomePostalAddress", "Mailing home address (includes address lines, city, province, country, and postal code)",
00087 &ContactLdif::HomePostalAddress, &ContactLdif::SetHomePostalAddress },
00088 { "FullName", "First + Last names",
00089 &ContactLdif::FullName, &ContactLdif::SetFullName },
00090 { "FQDN", "Fully qualified domain name",
00091 &ContactLdif::FQDN, &ContactLdif::SetFQDN },
00092 { 0, 0, 0 }
00093 };
00094
00095
00096 bool ContactLdif::LdifAttribute::operator<(const LdifAttribute &other) const
00097 {
00098
00099 if( name == "dn" ) {
00100 if( other.name == "dn" )
00101 return false;
00102 return true;
00103 }
00104 else if( other.name == "dn" )
00105 return false;
00106
00107 return (order < other.order && name != other.name) ||
00108 (order == other.order && name < other.name);
00109 }
00110
00111 bool ContactLdif::LdifAttribute::operator==(const LdifAttribute &other) const
00112 {
00113 return name == other.name;
00114 }
00115
00116
00117
00118
00119
00120 ContactLdif::ContactLdif(const std::string &baseDN)
00121 : m_baseDN(baseDN)
00122 {
00123
00124 Map("mail", &ContactLdif::Email, &ContactLdif::SetEmail);
00125 Map("facsimileTelephoneNumber", &ContactLdif::Fax, &ContactLdif::SetFax);
00126 Map("telephoneNumber", &ContactLdif::WorkPhone, &ContactLdif::SetWorkPhone);
00127 Map("homePhone", &ContactLdif::HomePhone, &ContactLdif::SetHomePhone);
00128 Map("mobile", &ContactLdif::MobilePhone, &ContactLdif::SetMobilePhone);
00129 Map("pager", &ContactLdif::Pager, &ContactLdif::SetPager);
00130 Map("l", &ContactLdif::WorkCity, &ContactLdif::SetWorkCity);
00131 Map("st", &ContactLdif::WorkProvince, &ContactLdif::SetWorkProvince);
00132 Map("postalCode", &ContactLdif::WorkPostalCode, &ContactLdif::SetWorkPostalCode);
00133 Map("o", &ContactLdif::Company, &ContactLdif::SetCompany);
00134 Map("c", &ContactLdif::WorkCountry, &ContactLdif::SetWorkCountry);
00135 SetObjectClass("c", "country");
00136
00137 Map("title", &ContactLdif::JobTitle, &ContactLdif::SetJobTitle);
00138 Map("dn", &ContactLdif::FQDN, &ContactLdif::SetFQDN);
00139 Map("displayName", &ContactLdif::FullName, &ContactLdif::SetFullName);
00140 Map("cn", &ContactLdif::FullName, &ContactLdif::SetFullName);
00141 Map("sn", &ContactLdif::LastName, &ContactLdif::SetLastName);
00142 Map("givenName", &ContactLdif::FirstName, &ContactLdif::SetFirstName);
00143 Map("street", &ContactLdif::WorkAddress1, &ContactLdif::SetWorkAddress1);
00144 Map("postalAddress", &ContactLdif::WorkPostalAddress, &ContactLdif::SetWorkPostalAddress);
00145 Map("homePostalAddress", &ContactLdif::HomePostalAddress, &ContactLdif::SetHomePostalAddress);
00146 Map("note", &ContactLdif::Notes, &ContactLdif::SetNotes);
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 Hook("cn", &m_cn);
00158 Hook("displayName", &m_displayName);
00159 Hook("sn", &m_sn);
00160 Hook("givenName", &m_givenName);
00161
00162
00163 SetDNAttr("cn");
00164 }
00165
00166 ContactLdif::~ContactLdif()
00167 {
00168 }
00169
00170 void ContactLdif::DoWrite(Barry::Contact &con,
00171 const std::string &attr,
00172 const std::string &data)
00173 {
00174
00175 if( attr.size() == 0 || data.size() == 0 )
00176 return;
00177
00178
00179 HookMapType::iterator hook = m_hookMap.find(attr);
00180 if( hook != m_hookMap.end() ) {
00181 *(hook->second) = data;
00182 }
00183
00184
00185 AccessMapType::iterator acc = m_map.find(attr);
00186 if( acc != m_map.end() ) {
00187 (this->*(acc->second.write))(con, data);
00188 }
00189 }
00190
00191 void ContactLdif::Hook(const std::string &ldifname, std::string *var)
00192 {
00193 m_hookMap[ldifname] = var;
00194 }
00195
00196 const ContactLdif::NameToFunc*
00197 ContactLdif::GetField(const std::string &fieldname) const
00198 {
00199 for( const NameToFunc *n = FieldMap; n->name; n++ ) {
00200 if( fieldname == n->name )
00201 return n;
00202 }
00203 return 0;
00204 }
00205
00206 std::string ContactLdif::GetFieldReadName(GetFunctionType read) const
00207 {
00208 for( const NameToFunc *n = FieldMap; n->name; n++ ) {
00209 if( read == n->read )
00210 return n->name;
00211 }
00212 return "<unknown>";
00213 }
00214
00215 std::string ContactLdif::GetFieldWriteName(SetFunctionType write) const
00216 {
00217 for( const NameToFunc *n = FieldMap; n->name; n++ ) {
00218 if( write == n->write )
00219 return n->name;
00220 }
00221 return "<unknown>";
00222 }
00223
00224 bool ContactLdif::Map(const LdifAttribute &ldifname,
00225 const std::string &readField,
00226 const std::string &writeField)
00227 {
00228 const NameToFunc *read = GetField(readField);
00229 const NameToFunc *write = GetField(writeField);
00230 if( !read || !write )
00231 return false;
00232 Map(ldifname, read->read, write->write);
00233 return true;
00234 }
00235
00236 void ContactLdif::Map(const LdifAttribute &ldifname,
00237 GetFunctionType read,
00238 SetFunctionType write)
00239 {
00240 m_map[ldifname] = AccessPair(read, write);
00241 }
00242
00243 void ContactLdif::Unmap(const LdifAttribute &ldifname)
00244 {
00245 m_map.erase(ldifname);
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255 bool ContactLdif::SetDNAttr(const LdifAttribute &name)
00256 {
00257
00258 AccessMapType::iterator i = m_map.find(name);
00259 if( i == m_map.end() )
00260 return false;
00261
00262 m_dnAttr = name;
00263 return true;
00264 }
00265
00266 bool ContactLdif::SetObjectClass(const LdifAttribute &name,
00267 const std::string &objectClass)
00268 {
00269 AccessMapType::iterator i = m_map.find(name);
00270 if( i == m_map.end() )
00271 return false;
00272
00273 LdifAttribute key = i->first;
00274 AccessPair pair = i->second;
00275 m_map.erase(key);
00276 key.objectClass = objectClass;
00277 m_map[key] = pair;
00278 return true;
00279 }
00280
00281 bool ContactLdif::SetObjectOrder(const LdifAttribute &name, int order)
00282 {
00283 AccessMapType::iterator i = m_map.find(name);
00284 if( i == m_map.end() )
00285 return false;
00286
00287 LdifAttribute key = i->first;
00288 AccessPair pair = i->second;
00289 m_map.erase(key);
00290 key.order = order;
00291 m_map[key] = pair;
00292 return true;
00293 }
00294
00295
00296 std::string ContactLdif::Email(const Barry::Contact &con) const
00297 {
00298 return con.GetEmail(m_emailIndex++);
00299 }
00300
00301 std::string ContactLdif::Phone(const Barry::Contact &con) const
00302 {
00303 return con.Phone;
00304 }
00305
00306 std::string ContactLdif::Fax(const Barry::Contact &con) const
00307 {
00308 return con.Fax;
00309 }
00310
00311 std::string ContactLdif::WorkPhone(const Barry::Contact &con) const
00312 {
00313 return con.WorkPhone;
00314 }
00315
00316 std::string ContactLdif::HomePhone(const Barry::Contact &con) const
00317 {
00318 return con.HomePhone;
00319 }
00320
00321 std::string ContactLdif::MobilePhone(const Barry::Contact &con) const
00322 {
00323 return con.MobilePhone;
00324 }
00325
00326 std::string ContactLdif::Pager(const Barry::Contact &con) const
00327 {
00328 return con.Pager;
00329 }
00330
00331 std::string ContactLdif::PIN(const Barry::Contact &con) const
00332 {
00333 return con.PIN;
00334 }
00335
00336 std::string ContactLdif::FirstName(const Barry::Contact &con) const
00337 {
00338 return con.FirstName;
00339 }
00340
00341 std::string ContactLdif::LastName(const Barry::Contact &con) const
00342 {
00343 return con.LastName;
00344 }
00345
00346 std::string ContactLdif::Company(const Barry::Contact &con) const
00347 {
00348 return con.Company;
00349 }
00350
00351 std::string ContactLdif::DefaultCommunicationsMethod(const Barry::Contact &con) const
00352 {
00353 return con.DefaultCommunicationsMethod;
00354 }
00355
00356 std::string ContactLdif::WorkAddress1(const Barry::Contact &con) const
00357 {
00358 return con.WorkAddress.Address1;
00359 }
00360
00361 std::string ContactLdif::WorkAddress2(const Barry::Contact &con) const
00362 {
00363 return con.WorkAddress.Address2;
00364 }
00365
00366 std::string ContactLdif::WorkAddress3(const Barry::Contact &con) const
00367 {
00368 return con.WorkAddress.Address3;
00369 }
00370
00371 std::string ContactLdif::WorkCity(const Barry::Contact &con) const
00372 {
00373 return con.WorkAddress.City;
00374 }
00375
00376 std::string ContactLdif::WorkProvince(const Barry::Contact &con) const
00377 {
00378 return con.WorkAddress.Province;
00379 }
00380
00381 std::string ContactLdif::WorkPostalCode(const Barry::Contact &con) const
00382 {
00383 return con.WorkAddress.PostalCode;
00384 }
00385
00386 std::string ContactLdif::WorkCountry(const Barry::Contact &con) const
00387 {
00388 return con.WorkAddress.Country;
00389 }
00390
00391 std::string ContactLdif::JobTitle(const Barry::Contact &con) const
00392 {
00393 return con.JobTitle;
00394 }
00395
00396 std::string ContactLdif::PublicKey(const Barry::Contact &con) const
00397 {
00398 return con.PublicKey;
00399 }
00400
00401 std::string ContactLdif::Notes(const Barry::Contact &con) const
00402 {
00403 return con.Notes;
00404 }
00405
00406 std::string ContactLdif::Image(const Barry::Contact &con) const
00407 {
00408 return con.Image;
00409 }
00410
00411 std::string ContactLdif::WorkPostalAddress(const Barry::Contact &con) const
00412 {
00413 return con.WorkAddress.GetLabel();
00414 }
00415
00416 std::string ContactLdif::HomePostalAddress(const Barry::Contact &con) const
00417 {
00418 return con.HomeAddress.GetLabel();
00419 }
00420
00421 std::string ContactLdif::FullName(const Barry::Contact &con) const
00422 {
00423 return con.GetFullName();
00424 }
00425
00426 std::string ContactLdif::FQDN(const Barry::Contact &con) const
00427 {
00428 std::string FQDN = m_dnAttr.name;
00429 FQDN += "=";
00430
00431 AccessMapType::const_iterator i = m_map.find(m_dnAttr);
00432 if( i != m_map.end() ) {
00433 FQDN += (this->*(i->second.read))(con);
00434 }
00435 else {
00436 FQDN += "unknown";
00437 }
00438
00439 FQDN += ",";
00440 FQDN += m_baseDN;
00441 return FQDN;
00442 }
00443
00444 bool ContactLdif::IsArrayFunc(GetFunctionType getf) const
00445 {
00446
00447 if( getf == &ContactLdif::Email )
00448 return true;
00449 return false;
00450 }
00451
00452 void ContactLdif::ClearArrayState() const
00453 {
00454 m_emailIndex = 0;
00455 }
00456
00457 void ContactLdif::SetEmail(Barry::Contact &con, const std::string &val) const
00458 {
00459 con.EmailAddresses.push_back(val);
00460 }
00461
00462 void ContactLdif::SetPhone(Barry::Contact &con, const std::string &val) const
00463 {
00464 con.Phone = val;
00465 }
00466
00467 void ContactLdif::SetFax(Barry::Contact &con, const std::string &val) const
00468 {
00469 con.Fax = val;
00470 }
00471
00472 void ContactLdif::SetWorkPhone(Barry::Contact &con, const std::string &val) const
00473 {
00474 con.WorkPhone = val;
00475 }
00476
00477 void ContactLdif::SetHomePhone(Barry::Contact &con, const std::string &val) const
00478 {
00479 con.HomePhone = val;
00480 }
00481
00482 void ContactLdif::SetMobilePhone(Barry::Contact &con, const std::string &val) const
00483 {
00484 con.MobilePhone = val;
00485 }
00486
00487 void ContactLdif::SetPager(Barry::Contact &con, const std::string &val) const
00488 {
00489 con.Pager = val;
00490 }
00491
00492 void ContactLdif::SetPIN(Barry::Contact &con, const std::string &val) const
00493 {
00494 con.PIN = val;
00495 }
00496
00497 void ContactLdif::SetFirstName(Barry::Contact &con, const std::string &val) const
00498 {
00499 con.FirstName = val;
00500 }
00501
00502 void ContactLdif::SetLastName(Barry::Contact &con, const std::string &val) const
00503 {
00504 con.LastName = val;
00505 }
00506
00507 void ContactLdif::SetCompany(Barry::Contact &con, const std::string &val) const
00508 {
00509 con.Company = val;
00510 }
00511
00512 void ContactLdif::SetDefaultCommunicationsMethod(Barry::Contact &con, const std::string &val) const
00513 {
00514 con.DefaultCommunicationsMethod = val;
00515 }
00516
00517 void ContactLdif::SetWorkAddress1(Barry::Contact &con, const std::string &val) const
00518 {
00519 con.WorkAddress.Address1 = val;
00520 }
00521
00522 void ContactLdif::SetWorkAddress2(Barry::Contact &con, const std::string &val) const
00523 {
00524 con.WorkAddress.Address2 = val;
00525 }
00526
00527 void ContactLdif::SetWorkAddress3(Barry::Contact &con, const std::string &val) const
00528 {
00529 con.WorkAddress.Address3 = val;
00530 }
00531
00532 void ContactLdif::SetWorkCity(Barry::Contact &con, const std::string &val) const
00533 {
00534 con.WorkAddress.City = val;
00535 }
00536
00537 void ContactLdif::SetWorkProvince(Barry::Contact &con, const std::string &val) const
00538 {
00539 con.WorkAddress.Province = val;
00540 }
00541
00542 void ContactLdif::SetWorkPostalCode(Barry::Contact &con, const std::string &val) const
00543 {
00544 con.WorkAddress.PostalCode = val;
00545 }
00546
00547 void ContactLdif::SetWorkCountry(Barry::Contact &con, const std::string &val) const
00548 {
00549 con.WorkAddress.Country = val;
00550 }
00551
00552 void ContactLdif::SetJobTitle(Barry::Contact &con, const std::string &val) const
00553 {
00554 con.JobTitle = val;
00555 }
00556
00557 void ContactLdif::SetPublicKey(Barry::Contact &con, const std::string &val) const
00558 {
00559 con.PublicKey = val;
00560 }
00561
00562 void ContactLdif::SetNotes(Barry::Contact &con, const std::string &val) const
00563 {
00564 con.Notes = val;
00565 }
00566
00567 void ContactLdif::SetImage(Barry::Contact &con, const std::string &val) const
00568 {
00569 con.Image = val;
00570 }
00571
00572 void ContactLdif::SetWorkPostalAddress(Barry::Contact &con, const std::string &val) const
00573 {
00574
00575
00576
00577 }
00578
00579 void ContactLdif::SetHomePostalAddress(Barry::Contact &con, const std::string &val) const
00580 {
00581
00582
00583
00584 }
00585
00586 void ContactLdif::SetFullName(Barry::Contact &con, const std::string &val) const
00587 {
00588 std::string first, last;
00589 Contact::SplitName(val, first, last);
00590 con.FirstName = first;
00591 con.LastName = last;
00592 }
00593
00594 void ContactLdif::SetFQDN(Barry::Contact &con, const std::string &val) const
00595 {
00596 throw std::runtime_error("not implemented");
00597 }
00598
00599
00600 void ContactLdif::ClearHeuristics()
00601 {
00602 m_cn.clear();
00603 m_displayName.clear();
00604 m_sn.clear();
00605 m_givenName.clear();
00606 }
00607
00608 bool ContactLdif::RunHeuristics(Barry::Contact &con)
00609 {
00610
00611 con.LastName.clear();
00612 con.FirstName.clear();
00613
00614
00615 if( m_sn.size() ) {
00616 con.LastName = m_sn;
00617 }
00618 if( m_givenName.size() ) {
00619 con.FirstName = m_givenName;
00620 }
00621
00622 if( !con.LastName.size() || !con.FirstName.size() ) {
00623 std::string first, last;
00624
00625
00626 if( m_cn.size() ) {
00627 Contact::SplitName(m_cn, first, last);
00628 if( !con.LastName.size() && last.size() )
00629 con.LastName = last;
00630 if( !con.FirstName.size() && first.size() )
00631 con.FirstName = first;
00632 }
00633
00634
00635 if( m_displayName.size() ) {
00636 Contact::SplitName(m_displayName, first, last);
00637 if( !con.LastName.size() && last.size() )
00638 con.LastName = last;
00639 if( !con.FirstName.size() && first.size() )
00640 con.FirstName = first;
00641 }
00642 }
00643
00644 return con.LastName.size() && con.FirstName.size();
00645 }
00646
00647
00648
00649
00650
00651
00652
00653 void ContactLdif::DumpLdif(std::ostream &os,
00654 const Barry::Contact &con) const
00655 {
00656 ios_format_state state(os);
00657
00658
00659 ClearArrayState();
00660
00661
00662 os.setf(std::ios::left);
00663 os.fill(' ');
00664
00665 if( FirstName(con).size() == 0 && LastName(con).size() == 0 )
00666 return;
00667
00668 os << "# Contact 0x" << std::hex << con.GetID() << ", "
00669 << FullName(con) << "\n";
00670
00671
00672 for( AccessMapType::const_iterator b = m_map.begin();
00673 b != m_map.end();
00674 ++b )
00675 {
00676
00677 std::string field;
00678
00679 do {
00680 field = (this->*(b->second.read))(con);
00681 if( field.size() ) {
00682 os << b->first.name << MakeLdifData(field) << "\n";
00683 if( b->first.objectClass.size() )
00684 os << "objectClass: " << b->first.objectClass << "\n";
00685 }
00686 } while( IsArrayFunc(b->second.read) && field.size() );
00687 }
00688
00689 os << "objectClass: inetOrgPerson\n";
00690
00691
00692 os << "\n";
00693 }
00694
00695 bool ContactLdif::ReadLdif(std::istream &is, Barry::Contact &con)
00696 {
00697 std::string line;
00698
00699
00700 con.Clear();
00701 ClearHeuristics();
00702
00703
00704 bool found = false;
00705 while( std::getline(is, line) ) {
00706 if( strncmp(line.c_str(), "dn: ", 4) == 0 ) {
00707 found = true;
00708 break;
00709 }
00710 }
00711 if( !found )
00712 return false;
00713
00714
00715 std::string coded, decode, attr, data;
00716 bool b64field = false;
00717
00718
00719 while( getline(is, line) && line.size() ) {
00720
00721 if( b64field ) {
00722
00723 if( line[0] == ' ' ) {
00724 coded += "\n";
00725 coded += line;
00726 continue;
00727 }
00728 else {
00729
00730
00731
00732
00733 base64_decode(coded, decode);
00734 DoWrite(con, attr, decode);
00735 coded.clear();
00736 b64field = false;
00737 }
00738
00739 }
00740
00741
00742
00743 std::string::size_type delim = line.find(':'), dstart;
00744 if( delim == std::string::npos )
00745 continue;
00746
00747 attr.assign(line, 0, delim);
00748 dstart = delim + 1;
00749 while( line[dstart] == ' ' || line[dstart] == ':' )
00750 dstart++;
00751 data = line.substr(dstart);
00752
00753
00754 if( line[delim + 1] == ':' ) {
00755 coded = data;
00756 b64field = true;
00757 continue;
00758 }
00759
00760 DoWrite(con, attr, data);
00761 }
00762
00763 if( b64field ) {
00764
00765 base64_decode(coded, decode);
00766 DoWrite(con, attr, decode);
00767 coded.clear();
00768 b64field = false;
00769 }
00770
00771 return RunHeuristics(con);
00772 }
00773
00774 void ContactLdif::DumpMap(std::ostream &os) const
00775 {
00776 ios_format_state state(os);
00777
00778 os.setf(std::ios::left);
00779 os.fill(' ');
00780
00781 os << "ContactLdif Mapping:\n";
00782
00783
00784 for( AccessMapType::const_iterator b = m_map.begin();
00785 b != m_map.end();
00786 ++b )
00787 {
00788 os << " " << std::left << std::setw(20) << b->first.name
00789 << "-> " << GetFieldReadName(b->second.read)
00790 << " / " << GetFieldWriteName(b->second.write) << "\n";
00791
00792
00793
00794 if( b->first.objectClass.size() ) {
00795 os << " " << std::setw(20) << " "
00796 << "objectClass: " << b->first.objectClass << "\n";
00797 }
00798 }
00799
00800 os << " >>> DN attribute: " << m_dnAttr.name << "\n";
00801 }
00802
00803 std::string ContactLdif::MakeLdifData(const std::string &str)
00804 {
00805 std::string data = ":";
00806
00807 if( NeedsEncoding(str) ) {
00808 std::string b64;
00809 base64_encode(str, b64);
00810
00811 data += ": ";
00812 data += b64;
00813 }
00814 else {
00815 data += " ";
00816 data += str;
00817 }
00818
00819 return data;
00820 }
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 bool ContactLdif::NeedsEncoding(const std::string &str)
00832 {
00833 for( std::string::size_type i = 0; i < str.size(); i++ ) {
00834 unsigned char c = str[i];
00835
00836 switch( c )
00837 {
00838 case 0x00:
00839 case 0x0a:
00840 case 0x0d:
00841 return true;
00842
00843 case 0x20:
00844 case 0x3a:
00845 case 0x3c:
00846 if( i == 0 )
00847 return true;
00848 }
00849
00850 if( c > 0x7f )
00851 return true;
00852 }
00853 return false;
00854 }
00855
00856 }
00857