forked from pEp.foundation/libAccountSettings
Compare commits
69 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
b9c4bfc54d | |
![]() |
c63b71ce79 | |
![]() |
bcdda9f55a | |
|
7e8a7dd836 | |
|
67461fdb03 | |
![]() |
c51a99d185 | |
![]() |
8145cd6220 | |
|
652239d964 | |
|
e75d9130e6 | |
|
205d60e292 | |
|
291bf2bf70 | |
|
603e6a463d | |
|
28299af7c8 | |
![]() |
069d7ecb59 | |
![]() |
a2a4f2e8e6 | |
|
0c6b2b257c | |
|
b652c2fabd | |
![]() |
5523e22f12 | |
![]() |
eb46711fab | |
|
7793794fa5 | |
|
11ece8e115 | |
|
69b80d5c4d | |
|
4b787c2d91 | |
|
5e8204d10e | |
|
d58871da43 | |
|
6a7d389c01 | |
|
bd1adcead4 | |
|
6eb1dd65dc | |
|
d1a339817d | |
|
4fcc43f620 | |
![]() |
990738bd6d | |
![]() |
36d9467f6a | |
![]() |
36fe4372bd | |
![]() |
da8b67d939 | |
|
0014edb61c | |
|
88d94c7ce4 | |
|
8ebaad87e5 | |
|
bf58884058 | |
|
3a4e3776f3 | |
|
659dbb5600 | |
|
dd15362ca4 | |
|
dcc049c624 | |
|
3facba78d8 | |
|
5497b9fd47 | |
![]() |
72a053a455 | |
![]() |
5f1296aac4 | |
|
bb641d072e | |
|
ba485c7052 | |
|
fee8a42469 | |
|
9e3e4ebc52 | |
|
e69982522a | |
|
5b159af529 | |
|
46e3af89f1 | |
|
f1fa27e1d8 | |
|
6f8eb6436f | |
|
eb7512f9cf | |
|
898336eca2 | |
|
141baa40aa | |
|
06e7d8297f | |
|
953e73e3f2 | |
|
6a8dda19c7 | |
|
45cb8a717d | |
|
22871a52d7 | |
|
0f4f1b6ef5 | |
|
5478cd6b8a | |
|
240a955332 | |
|
b4b7facf30 | |
|
49425bb6f4 | |
|
bb1ba802d8 |
|
@ -0,0 +1,70 @@
|
|||
# Xcode
|
||||
|
||||
## Build generated
|
||||
build/
|
||||
DerivedData/
|
||||
|
||||
## Various settings
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata/
|
||||
|
||||
## Other
|
||||
*.moved-aside
|
||||
*.xccheckout
|
||||
*.xcscmblueprint
|
||||
|
||||
## Obj-C/Swift specific
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.dSYM.zip
|
||||
*.dSYM
|
||||
|
||||
## Playgrounds
|
||||
timeline.xctimeline
|
||||
playground.xcworkspace
|
||||
|
||||
## Swift Package Manager
|
||||
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
|
||||
# Packages/
|
||||
# Package.pins
|
||||
# Package.resolved
|
||||
.build/
|
||||
|
||||
## Xcode Patch ###
|
||||
**/xcshareddata/WorkspaceSettings.xcsettings
|
||||
|
||||
# macOS
|
||||
|
||||
## General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
## Icon must end with two \r
|
||||
Icon
|
||||
|
||||
## Thumbnails
|
||||
._*
|
||||
|
||||
## Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
## Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
|
@ -0,0 +1,23 @@
|
|||
<clientConfig version="1.1">
|
||||
<emailProvider id="e-foundation">
|
||||
<domain>e.email</domain>
|
||||
<domain>ecloud.global</domain>
|
||||
|
||||
<displayName>e Foundation</displayName>
|
||||
<displayShortName>e Foundation</displayShortName>
|
||||
<incomingServer type="imap">
|
||||
<hostname>mail.ecloud.global</hostname>
|
||||
<port>993</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</incomingServer>
|
||||
<outgoingServer type="smtp">
|
||||
<hostname>mail.ecloud.global</hostname>
|
||||
<port>587</port>
|
||||
<socketType>STARTTLS</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</outgoingServer>
|
||||
</emailProvider>
|
||||
</clientConfig>
|
|
@ -0,0 +1,61 @@
|
|||
<clientConfig version="1.1">
|
||||
<emailProvider id="M-net">
|
||||
<domain>16000-kbits.de</domain>
|
||||
<domain>7fun.de</domain>
|
||||
<domain>a-city.de</domain>
|
||||
<domain>alpenbazi.de</domain>
|
||||
<domain>amberg-mail.de</domain>
|
||||
<domain>augustakom.net</domain>
|
||||
<domain>bayern-mail.de</domain>
|
||||
<domain>club-goes-uefacup.de</domain>
|
||||
<domain>dachau-mail.de</domain>
|
||||
<domain>erding-mail.de</domain>
|
||||
<domain>es-laendle.de</domain>
|
||||
<domain>familien-postfach.de</domain>
|
||||
<domain>fcn-cluberer.de</domain>
|
||||
<domain>frankenbeutel-mail.de</domain>
|
||||
<domain>franken-ist-cool.de</domain>
|
||||
<domain>franken-online.de</domain>
|
||||
<domain>ich-liebe-franken.de</domain>
|
||||
<domain>ich-mag-net.de</domain>
|
||||
<domain>ingolstadt-mail.de</domain>
|
||||
<domain>loewen-mail.de</domain>
|
||||
<domain>maxi-allgaeu.de</domain>
|
||||
<domain>maxi-bayern.de</domain>
|
||||
<domain>maxi-dsl.de</domain>
|
||||
<domain>maxi-schwaben.de</domain>
|
||||
<domain>mnet-mail.de</domain>
|
||||
<domain>mnet-online.de</domain>
|
||||
<domain>muenchen-ist-toll.de</domain>
|
||||
<domain>muenchen-mail.de</domain>
|
||||
<domain>muenchen-surf.de</domain>
|
||||
<domain>myway.de</domain>
|
||||
<domain>nefkom.info</domain>
|
||||
<domain>nefkom.net</domain>
|
||||
<domain>neumarkt-mail.de</domain>
|
||||
<domain>post-ist-da.de</domain>
|
||||
<domain>regensburg-mail.de</domain>
|
||||
<domain>rotgruenweiss.de</domain>
|
||||
<domain>starnberg-mail.de</domain>
|
||||
<domain>unser-postfach.de</domain>
|
||||
<domain>weissblautsv.de</domain>
|
||||
<domain>wir-datschiburger.de</domain>
|
||||
|
||||
<displayName>M-net Telekommunikations GmbH</displayName>
|
||||
<displayShortName>M-net</displayShortName>
|
||||
<incomingServer type="imap">
|
||||
<hostname>imap.mnet-online.de</hostname>
|
||||
<port>993</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</incomingServer>
|
||||
<outgoingServer type="smtp">
|
||||
<hostname>mail.mnet-online.de</hostname>
|
||||
<port>587</port>
|
||||
<socketType>STARTTLS</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</outgoingServer>
|
||||
</emailProvider>
|
||||
</clientConfig>
|
|
@ -0,0 +1,22 @@
|
|||
<clientConfig version="1.1">
|
||||
<emailProvider id="Mailfence">
|
||||
<domain>mailfence.com</domain>
|
||||
|
||||
<displayName>Mailfence</displayName>
|
||||
<displayShortName>Mailfence</displayShortName>
|
||||
<incomingServer type="imap">
|
||||
<hostname>imap.mailfence.com</hostname>
|
||||
<port>993</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</incomingServer>
|
||||
<outgoingServer type="smtp">
|
||||
<hostname>smtp.mailfence.com</hostname>
|
||||
<port>465</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</outgoingServer>
|
||||
</emailProvider>
|
||||
</clientConfig>
|
|
@ -0,0 +1,21 @@
|
|||
<clientConfig version="1.1">
|
||||
<emailProvider id="pep-security.net">
|
||||
<domain>pep-security.net</domain>
|
||||
<displayName>pEp Security S.A.</displayName>
|
||||
<displayShortName>pEp Security S.A.</displayShortName>
|
||||
<incomingServer type="imap">
|
||||
<hostname>mail.pep-security.net</hostname>
|
||||
<port>993</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</incomingServer>
|
||||
<outgoingServer type="smtp">
|
||||
<hostname>mail.pep-security.net</hostname>
|
||||
<port>587</port>
|
||||
<socketType>STARTTLS</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</outgoingServer>
|
||||
</emailProvider>
|
||||
</clientConfig>
|
|
@ -0,0 +1,21 @@
|
|||
<clientConfig version="1.1">
|
||||
<emailProvider id="pep.digital">
|
||||
<domain>pep.digital</domain>
|
||||
<displayName>p≡p Security S.A.</displayName>
|
||||
<displayShortName>p≡p Security S.A.</displayShortName>
|
||||
<incomingServer type="imap">
|
||||
<hostname>mail.peptest.ch</hostname>
|
||||
<port>993</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</incomingServer>
|
||||
<outgoingServer type="smtp">
|
||||
<hostname>mail.peptest.ch</hostname>
|
||||
<port>465</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</outgoingServer>
|
||||
</emailProvider>
|
||||
</clientConfig>
|
|
@ -0,0 +1,21 @@
|
|||
<clientConfig version="1.1">
|
||||
<emailProvider id="pep.security">
|
||||
<domain>pep.security</domain>
|
||||
<displayName>p≡p Security S.A.</displayName>
|
||||
<displayShortName>p≡p Security S.A.</displayShortName>
|
||||
<incomingServer type="imap">
|
||||
<hostname>mail.pep.security</hostname>
|
||||
<port>993</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</incomingServer>
|
||||
<outgoingServer type="smtp">
|
||||
<hostname>mail.pep.security</hostname>
|
||||
<port>465</port>
|
||||
<socketType>SSL</socketType>
|
||||
<username>%EMAILADDRESS%</username>
|
||||
<authentication>password-cleartext</authentication>
|
||||
</outgoingServer>
|
||||
</emailProvider>
|
||||
</clientConfig>
|
|
@ -52,6 +52,15 @@ const struct AccountSettings* get_account_settings(const char* accountName, cons
|
|||
AS_STATUS AS_get_status(const struct AccountSettings* account_settings);
|
||||
|
||||
|
||||
/** get the privder id string of the account_settings
|
||||
*
|
||||
* @param account_settings the account settings your want to get provider id
|
||||
* @return the provider id, if any. Might be NULL or empty string.
|
||||
The pointer points to internal r/o data in accountSettings, do not delete it!
|
||||
*/
|
||||
const char* AS_get_provider_id(const struct AccountSettings* account_settings);
|
||||
|
||||
|
||||
/** get the server settings for "incoming" messages (e.g. IMAP or POP3)
|
||||
* @param accountSettings guess what
|
||||
* @return the server for incoming messages associated with the accountSettings.
|
||||
|
|
|
@ -31,12 +31,19 @@ typedef enum _AS_STATUS
|
|||
typedef enum _AS_FLAGS
|
||||
{
|
||||
AS_FLAG_USE_LOCAL_ISP_DB = 0x0010, ///< use local ISP database
|
||||
AS_FLAG_USE_HEURISTICS = 0x0020, ///< use heuristics from account's domain name
|
||||
AS_FLAG_USE_ANY_LOCAL = 0x00FF, ///< use all local (without communication to 3rd parties) methods in ascending order
|
||||
AS_FLAG_USE_DNS_AUTOCONFIG = 0x0100, ///< fetch account config from "autodiscover/autoconfig" servers
|
||||
AS_FLAG_USE_DNS_SRV = 0x0110, ///< use DNS SRV records for the mail domain
|
||||
AS_FLAG_USE_ONLINE_ISP_DB = 0x0800, ///< ask https://live.mozillamessaging.com/autoconfig/v1.1/$DOMAINNAME
|
||||
AS_FLAG_USE_ANY = 0xFFFF ///< try first local, than network methods
|
||||
// FIXME: local-only heuristics? Is that possible/sensible?
|
||||
// AS_FLAG_USE_HEURISTICS = 0x0020, ///< use heuristics from account's domain name
|
||||
AS_FLAG_USE_ANY_LOCAL = 0x000F, ///< use all local (without communication to 3rd parties) methods in ascending order
|
||||
|
||||
AS_FLAG_USE_MOZ_AUTOCONFIG = 0x0100, ///< fetch account config via Mozilla's "autoconfig" method
|
||||
AS_FLAG_USE_MS_AUTODISCOVER = 0x0200, ///< fetch account config via Microsoft's "autodiscover" method
|
||||
AS_FLAG_USE_DNS_SRV = 0x0400, ///< use DNS SRV records for the mail domain
|
||||
AS_FLAG_USE_ONLINE_ISP_DB = 0x0800, ///< ask https://live.mozillamessaging.com/autoconfig/v1.1/$DOMAINNAME
|
||||
AS_FLAG_USE_ANY_ONLINE = 0x0F00, ///< try all (almost) reliable online configuration methods in ascending order
|
||||
|
||||
AS_FLAG_USE_GUESSING = 0x1000, ///< guess server names and try to detect its login methods. MAY BE DANGEROUS!
|
||||
|
||||
AS_FLAG_USE_ANY = 0xFFFF ///< try first local, than network methods
|
||||
} AS_FLAGS;
|
||||
|
||||
|
||||
|
@ -44,6 +51,7 @@ typedef enum _AS_FLAGS
|
|||
typedef enum _AS_ACCESS
|
||||
{
|
||||
/// protocols
|
||||
AS_PROTO_EXCHANGE = 0x00008, ///< both (?) - selected with very low precedence
|
||||
AS_PROTO_POP3 = 0x00011, ///< incoming
|
||||
AS_PROTO_IMAP = 0x00012, ///< incoming
|
||||
AS_PROTO_SMTP = 0x00021, ///< outgoing
|
||||
|
|
|
@ -10,18 +10,18 @@ test: accountSettings_test
|
|||
isp_db: isp_db.cc
|
||||
|
||||
isp_db.cc: xml2cxx
|
||||
./xml2cxx ../../autoconfig/* > $@
|
||||
./xml2cxx ../../autoconfig/* ../example/* > $@
|
||||
|
||||
xml2cxx: xml2cxx.o tinyxml2.o account_settings_internal.o stringpool.o
|
||||
${CXX} -o $@ $^
|
||||
|
||||
accountSettings_test: accountSettings_test.o libAccountSettings.a
|
||||
${CXX} -o $@ $^ -lldns
|
||||
${CXX} -o $@ $^ -lldns -lcrypto -lssl
|
||||
|
||||
libAccountSettings.a: account_settings_internal.o implementation.o \
|
||||
isp_db.o \
|
||||
isp_db.o http_client.o \
|
||||
from_srv.o
|
||||
ar rcs $@ $^
|
||||
${AR} rcs $@ $^
|
||||
|
||||
%.o : %.cc %.hh
|
||||
${CXX} -o $@ -c $<
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// unit test program for libAccountSettings
|
||||
|
||||
#include "../include/account_settings_c.h"
|
||||
#include "account_settings_internal.hh"
|
||||
#include "from_srv.hh"
|
||||
#include "http_client.hh"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
@ -19,25 +21,26 @@ struct TestHost
|
|||
{
|
||||
std::string name;
|
||||
int port;
|
||||
unsigned access;
|
||||
};
|
||||
|
||||
// stored in ISP DB
|
||||
const std::vector< KeyValue< TestHost> > incomingServer =
|
||||
{
|
||||
{ "lib_as@peptest.ch", {"peptest.ch", 993} },
|
||||
{ "example@gmx.de" , {"imap.gmx.net", 993} },
|
||||
{ "example@yandex.ua", {"imap.yandex.com", 993} },
|
||||
{ "lib_as@peptest.ch", {"peptest.ch" , 993, AS_PROTO_IMAP | AS_SOCK_SSL | AS_AUTH_PW_CLEARTEXT} },
|
||||
{ "example@gmx.de" , {"imap.gmx.net" , 993, AS_PROTO_IMAP | AS_SOCK_SSL | AS_AUTH_PW_CLEARTEXT} },
|
||||
{ "example@yandex.ua", {"imap.yandex.com", 993, AS_PROTO_IMAP | AS_SOCK_SSL | AS_AUTH_PW_CLEARTEXT} },
|
||||
{ "example@yahoo.com", {"imap.mail.yahoo.com", 993, AS_PROTO_IMAP | AS_SOCK_SSL | AS_AUTH_OAUTH2} },
|
||||
};
|
||||
|
||||
// stored in ISP DB
|
||||
const std::vector< KeyValue< TestHost> > outgoingServer =
|
||||
{
|
||||
{ "lib_as@peptest.ch", {"peptest.ch", 587} },
|
||||
{ "example@gmx.de" , {"mail.gmx.net", 465} },
|
||||
{ "example@yandex.ua", {"smtp.yandex.com", 465} },
|
||||
{ "lib_as@peptest.ch", {"peptest.ch" , 587, AS_PROTO_SMTP | AS_SOCK_STARTTLS | AS_AUTH_PW_CLEARTEXT} },
|
||||
{ "example@gmx.de" , {"mail.gmx.net" , 465, AS_PROTO_SMTP | AS_SOCK_SSL | AS_AUTH_PW_CLEARTEXT} },
|
||||
{ "example@yandex.ua", {"smtp.yandex.com", 465, AS_PROTO_SMTP | AS_SOCK_SSL | AS_AUTH_PW_CLEARTEXT} },
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
template<class TestData, class Function >
|
||||
bool testServers( const TestData& testData, Function testFunc )
|
||||
|
@ -66,6 +69,14 @@ bool testServers( const TestData& testData, Function testFunc )
|
|||
okay = false;
|
||||
}
|
||||
|
||||
const AS_ACCESS acc = AS_get_access_method(srv);
|
||||
if( acc != AS_ACCESS(t.value.access) )
|
||||
{
|
||||
std::cerr << "Got access method " << std::hex << acc << ", expected " << t.value.access << " for account " << t.key << std::dec << "!\n";
|
||||
okay = false;
|
||||
}
|
||||
|
||||
|
||||
free_account_settings(as);
|
||||
}
|
||||
|
||||
|
@ -82,22 +93,49 @@ bool testSRV()
|
|||
}
|
||||
|
||||
|
||||
bool testHttp()
|
||||
{
|
||||
using account_settings::http_get_file;
|
||||
|
||||
bool okay = true;
|
||||
|
||||
okay &= (http_get_file("autoconfig.peptest.ch", 80, "/mail/config-v1.1.xml", false).size() > 0);
|
||||
|
||||
bool invalid_host = false;
|
||||
try
|
||||
{
|
||||
http_get_file("invalid-host.pep.lol", 80, "/dontmatter", false);
|
||||
}catch(...)
|
||||
{
|
||||
invalid_host = true;
|
||||
}
|
||||
okay &= invalid_host;
|
||||
|
||||
return okay;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
try{
|
||||
if(argc>1)
|
||||
{
|
||||
for(int a=1; a<argc; ++a)
|
||||
{
|
||||
printf("#%d : ", a);
|
||||
std::cout << a << ": " << std::endl;
|
||||
auto as = std::unique_ptr<AccountSettings>{ new AccountSettings };
|
||||
get_settings_from_srv( as.get(), "foo@bar.com", argv[a], "dummy");
|
||||
printf("\n");
|
||||
if( AS_get_status( as.get() ) == AS_OK )
|
||||
{
|
||||
std::cout << *as.get() << std::endl;
|
||||
}else{
|
||||
std::cout << "No SRV record for \"" << argv[a] << "\". :-(" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool all_okay = true;
|
||||
all_okay &= testServers( incomingServer, &AS_get_incoming );
|
||||
all_okay &= testServers( outgoingServer, &AS_get_outgoing );
|
||||
|
||||
all_okay &= testHttp();
|
||||
all_okay &= testSRV();
|
||||
|
||||
std::cout << "***\t" << (all_okay ? "All tests are okay." : "ERROS happened") << std::endl;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <set>
|
||||
#include <ostream>
|
||||
|
||||
// public names, must be accessible from C, so no namespace here:
|
||||
struct AS_Server
|
||||
{
|
||||
std::string name;
|
||||
|
@ -30,6 +31,7 @@ std::ostream& operator<<(std::ostream& o, const AS_Server& srv);
|
|||
std::ostream& operator<<(std::ostream& o, const AccountSettings& as);
|
||||
|
||||
|
||||
namespace account_settings {
|
||||
// for static ISP DB:
|
||||
struct AS_Server_DB
|
||||
{
|
||||
|
@ -47,4 +49,6 @@ struct AccountSettings_DB
|
|||
AS_Server_DB outgoing;
|
||||
};
|
||||
|
||||
} // end of namespace account_settings
|
||||
|
||||
#endif // ACCOUNT_SETTINGS_INTERNAL_HH
|
||||
|
|
|
@ -131,10 +131,15 @@ SRV get_srv_server(const std::string& domain, const std::string& service)
|
|||
ldns_buffer* buf_host = ldns_buffer_new(128);
|
||||
ldns_rdf2buffer_str_dname( buf_host, rdf_host);
|
||||
|
||||
const std::string host = ldns_rdf_get_type(rdf_host)==LDNS_RDF_TYPE_DNAME ? std::string( (const char*)buf_host->_data, buf_host->_limit) : "{°?°}";
|
||||
std::string host = ldns_rdf_get_type(rdf_host)==LDNS_RDF_TYPE_DNAME ? std::string( (const char*)buf_host->_data, buf_host->_position) : "{°?°}";
|
||||
ldns_buffer_free(buf_host);
|
||||
buf_host=nullptr;
|
||||
|
||||
while( (host.size() > 0) && (host.back() == '.') )
|
||||
{
|
||||
host.pop_back();
|
||||
}
|
||||
|
||||
// printf("***\tPrio: %u, Weight: %u, Port: %u, Host: \"%s\".\n", priority, weight, port, host.c_str());
|
||||
|
||||
return SRV{ priority, weight, port, host };
|
||||
|
@ -149,14 +154,35 @@ AccountSettings* get_settings_from_srv(AccountSettings* as, const std::string& a
|
|||
{
|
||||
throw std::runtime_error("get_settings_from_srv shall not be called with NULL pointer!");
|
||||
}
|
||||
|
||||
bool imap_okay = false;
|
||||
bool smtp_okay = false;
|
||||
|
||||
// fprintf(stderr, "== IMAPS ==\n");
|
||||
try{
|
||||
const SRV imap_srv = get_srv_server( domain, "_imaps._tcp" );
|
||||
if(imap_srv.is_valid())
|
||||
{
|
||||
as->incoming.name = imap_srv.hostname;
|
||||
as->incoming.port = imap_srv.port;
|
||||
as->incoming.access = AS_ACCESS(AS_PROTO_IMAP | AS_SOCK_SSL);
|
||||
imap_okay = true;
|
||||
}
|
||||
}catch( const DNS_error& )
|
||||
{
|
||||
// ignore unsuccessful DNS queries
|
||||
}
|
||||
|
||||
// fprintf(stderr, "== IMAP ==\n");
|
||||
if( !imap_okay ) // let's try with plain IMAP nexr (with possibly STARTTLS later)
|
||||
try{
|
||||
const SRV imap_srv = get_srv_server( domain, "_imap._tcp" );
|
||||
if(imap_srv.is_valid())
|
||||
{
|
||||
as->incoming.name = imap_srv.hostname;
|
||||
as->incoming.port = imap_srv.port;
|
||||
as->incoming.access = AS_PROTO_IMAP;
|
||||
imap_okay = true;
|
||||
}
|
||||
}catch( const DNS_error& )
|
||||
{
|
||||
|
@ -170,11 +196,18 @@ AccountSettings* get_settings_from_srv(AccountSettings* as, const std::string& a
|
|||
{
|
||||
as->outgoing.name = smtp_srv.hostname;
|
||||
as->outgoing.port = smtp_srv.port;
|
||||
as->outgoing.access = AS_PROTO_SMTP;
|
||||
smtp_okay = true;
|
||||
}
|
||||
}catch( const DNS_error& )
|
||||
{
|
||||
// ignore unsuccessful DNS queries
|
||||
}
|
||||
|
||||
if(imap_okay && smtp_okay)
|
||||
{
|
||||
as->status = AS_OK;
|
||||
}
|
||||
|
||||
return as;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
#include "http_client.hh"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
|
||||
namespace account_settings
|
||||
{
|
||||
|
||||
using boost::asio::ip::tcp;
|
||||
namespace ssl = boost::asio::ssl;
|
||||
|
||||
// returns the content of the given http://host:port/path as string
|
||||
// might throw HttpError
|
||||
// implementation based on https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp03/http/client/sync_client.cpp
|
||||
// (Boost license 1.0)
|
||||
std::string http_get_file(const std::string& host, int port, const std::string& path, bool tls)
|
||||
{
|
||||
boost::asio::io_context io_context;
|
||||
|
||||
// Get a list of endpoints corresponding to the server name.
|
||||
tcp::resolver resolver(io_context);
|
||||
tcp::resolver::results_type endpoints = resolver.resolve(host, std::to_string(port));
|
||||
|
||||
tcp::socket* socket = nullptr;
|
||||
if(tls)
|
||||
{
|
||||
ssl::context ctx(ssl::context::sslv23);
|
||||
|
||||
}else{
|
||||
// Try each endpoint until we successfully establish a connection.
|
||||
socket = new tcp::socket(io_context);
|
||||
boost::asio::connect(*socket, endpoints);
|
||||
}
|
||||
// Form the request. We specify the "Connection: close" header so that the
|
||||
// server will close the socket after transmitting the response. This will
|
||||
// allow us to treat all data up until the EOF as the content.
|
||||
boost::asio::streambuf request;
|
||||
std::ostream request_stream(&request);
|
||||
request_stream << "GET " << path << " HTTP/1.0\r\n"
|
||||
<< "Host: " << host << "\r\n"
|
||||
<< "Accept: */*\r\n"
|
||||
<< "Connection: close\r\n\r\n";
|
||||
|
||||
// Send the request.
|
||||
boost::asio::write(*socket, request);
|
||||
|
||||
// Read the response status line. The response streambuf will automatically
|
||||
// grow to accommodate the entire line. The growth may be limited by passing
|
||||
// a maximum size to the streambuf constructor.
|
||||
boost::asio::streambuf response;
|
||||
boost::asio::read_until(*socket, response, "\r\n");
|
||||
|
||||
// Check that response is OK.
|
||||
std::istream response_stream(&response);
|
||||
std::string http_version;
|
||||
response_stream >> http_version;
|
||||
unsigned int status_code;
|
||||
response_stream >> status_code;
|
||||
std::string status_message;
|
||||
std::getline(response_stream, status_message);
|
||||
if (!response_stream || http_version.substr(0, 5) != "HTTP/")
|
||||
{
|
||||
throw HttpError(host, port, path, -1, http_version);
|
||||
}
|
||||
|
||||
if (status_code != 200)
|
||||
{
|
||||
throw HttpError(host, port, path, status_code, status_message);
|
||||
}
|
||||
|
||||
// Read the response headers, which are terminated by a blank line.
|
||||
boost::asio::read_until(*socket, response, "\r\n\r\n");
|
||||
/*
|
||||
// Process the response headers.
|
||||
std::string header;
|
||||
while (std::getline(response_stream, header) && header != "\r")
|
||||
std::cout << header << "\n";
|
||||
std::cout << "\n";
|
||||
|
||||
// Write whatever content we already have to output.
|
||||
if (response.size() > 0)
|
||||
std::cout << &response;
|
||||
*/
|
||||
// Read until EOF, writing data to output as we go.
|
||||
std::string content;
|
||||
|
||||
boost::system::error_code error;
|
||||
while (boost::asio::read(*socket, response,
|
||||
boost::asio::transfer_at_least(1), error))
|
||||
{
|
||||
auto bufs = response.data();
|
||||
auto begin = boost::asio::buffers_begin(bufs);
|
||||
content.append(begin, begin + bufs.size());
|
||||
}
|
||||
|
||||
if (error != boost::asio::error::eof)
|
||||
throw boost::system::system_error(error);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
} // end of namespace account_settings
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef ACCOUNT_SETTINGS_HTTP_CLIENT_HH
|
||||
#define ACCOUNT_SETTINGS_HTTP_CLIENT_HH
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace account_settings
|
||||
{
|
||||
|
||||
class HttpError : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
HttpError(const std::string& _host, int _port, const std::string& _path,
|
||||
int _error_code, const std::string& _error_message)
|
||||
: std::runtime_error{ "HTTP Error for http://" + _host + ":" + std::to_string(_port) + _path
|
||||
+ " : Status=" + std::to_string(_error_code) + (_error_message.empty() ? "" : (": " + _error_message) )}
|
||||
, host{_host}
|
||||
, port{_port}
|
||||
, path{_path}
|
||||
, error_code{_error_code}
|
||||
, error_message{_error_message}
|
||||
{}
|
||||
|
||||
// are public by intention
|
||||
const std::string host;
|
||||
const int port;
|
||||
const std::string path;
|
||||
const int error_code;
|
||||
const std::string error_message;
|
||||
};
|
||||
|
||||
|
||||
// returns the content of the given http://host:port/path as string
|
||||
// might throw HttpError
|
||||
std::string http_get_file(const std::string& host, int port, const std::string& path, bool tls);
|
||||
|
||||
} // end of namespace account_settings
|
||||
|
||||
#endif // ACCOUNT_SETTINGS_HTTP_CLIENT_HH
|
|
@ -108,6 +108,12 @@ AS_STATUS AS_get_status(const struct AccountSettings* account_settings)
|
|||
}
|
||||
|
||||
|
||||
const char* AS_get_provider_id(const struct AccountSettings* account_settings)
|
||||
{
|
||||
return account_settings ? account_settings->id.c_str() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
const AS_Server* AS_get_incoming(const AccountSettings* as)
|
||||
{
|
||||
return &as->incoming;
|
||||
|
|
3535
src/isp_db.cc
3535
src/isp_db.cc
File diff suppressed because it is too large
Load Diff
562
src/tinyxml2.cc
562
src/tinyxml2.cc
File diff suppressed because it is too large
Load Diff
337
src/tinyxml2.hh
337
src/tinyxml2.hh
|
@ -47,15 +47,15 @@ distribution.
|
|||
*/
|
||||
/*
|
||||
gcc:
|
||||
g++ -Wall -DDEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
|
||||
g++ -Wall -DTINYXML2_DEBUG tinyxml2.cpp xmltest.cpp -o gccxmltest.exe
|
||||
|
||||
Formatting, Artistic Style:
|
||||
AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h
|
||||
*/
|
||||
|
||||
#if defined( _DEBUG ) || defined( DEBUG ) || defined (__DEBUG__)
|
||||
# ifndef DEBUG
|
||||
# define DEBUG
|
||||
#if defined( _DEBUG ) || defined (__DEBUG__)
|
||||
# ifndef TINYXML2_DEBUG
|
||||
# define TINYXML2_DEBUG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
@ -79,7 +79,7 @@ distribution.
|
|||
#endif
|
||||
|
||||
|
||||
#if defined(DEBUG)
|
||||
#if defined(TINYXML2_DEBUG)
|
||||
# if defined(_MSC_VER)
|
||||
# // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like
|
||||
# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); }
|
||||
|
@ -98,9 +98,20 @@ distribution.
|
|||
/* Versioning, past 1.0.14:
|
||||
http://semver.org/
|
||||
*/
|
||||
static const int TIXML2_MAJOR_VERSION = 4;
|
||||
static const int TIXML2_MINOR_VERSION = 0;
|
||||
static const int TIXML2_PATCH_VERSION = 1;
|
||||
static const int TIXML2_MAJOR_VERSION = 7;
|
||||
static const int TIXML2_MINOR_VERSION = 1;
|
||||
static const int TIXML2_PATCH_VERSION = 0;
|
||||
|
||||
#define TINYXML2_MAJOR_VERSION 7
|
||||
#define TINYXML2_MINOR_VERSION 1
|
||||
#define TINYXML2_PATCH_VERSION 0
|
||||
|
||||
// A fixed element depth limit is problematic. There needs to be a
|
||||
// limit to avoid a stack overflow. However, that limit varies per
|
||||
// system, and the capacity of the stack. On the other hand, it's a trivial
|
||||
// attack that can result from ill, malicious, or even correctly formed XML,
|
||||
// so there needs to be a limit in place.
|
||||
static const int TINYXML2_MAX_ELEMENT_DEPTH = 100;
|
||||
|
||||
namespace tinyxml2
|
||||
{
|
||||
|
@ -118,8 +129,10 @@ class XMLPrinter;
|
|||
pointers into the XML file itself, and will apply normalization
|
||||
and entity translation if actually read. Can also store (and memory
|
||||
manage) a traditional char[]
|
||||
|
||||
Isn't clear why TINYXML2_LIB is needed; but seems to fix #719
|
||||
*/
|
||||
class StrPair
|
||||
class TINYXML2_LIB StrPair
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
|
@ -179,7 +192,7 @@ private:
|
|||
char* _end;
|
||||
|
||||
StrPair( const StrPair& other ); // not supported
|
||||
void operator=( StrPair& other ); // not supported, use TransferTo()
|
||||
void operator=( const StrPair& other ); // not supported, use TransferTo()
|
||||
};
|
||||
|
||||
|
||||
|
@ -192,10 +205,11 @@ template <class T, int INITIAL_SIZE>
|
|||
class DynArray
|
||||
{
|
||||
public:
|
||||
DynArray() {
|
||||
_mem = _pool;
|
||||
_allocated = INITIAL_SIZE;
|
||||
_size = 0;
|
||||
DynArray() :
|
||||
_mem( _pool ),
|
||||
_allocated( INITIAL_SIZE ),
|
||||
_size( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
~DynArray() {
|
||||
|
@ -264,12 +278,19 @@ public:
|
|||
return _allocated;
|
||||
}
|
||||
|
||||
void SwapRemove(int i) {
|
||||
TIXMLASSERT(i >= 0 && i < _size);
|
||||
TIXMLASSERT(_size > 0);
|
||||
_mem[i] = _mem[_size - 1];
|
||||
--_size;
|
||||
}
|
||||
|
||||
const T* Mem() const {
|
||||
TIXMLASSERT( _mem );
|
||||
return _mem;
|
||||
}
|
||||
|
||||
T* Mem() {
|
||||
T* Mem() {
|
||||
TIXMLASSERT( _mem );
|
||||
return _mem;
|
||||
}
|
||||
|
@ -282,8 +303,9 @@ private:
|
|||
TIXMLASSERT( cap > 0 );
|
||||
if ( cap > _allocated ) {
|
||||
TIXMLASSERT( cap <= INT_MAX / 2 );
|
||||
int newAllocated = cap * 2;
|
||||
const int newAllocated = cap * 2;
|
||||
T* newMem = new T[newAllocated];
|
||||
TIXMLASSERT( newAllocated >= _size );
|
||||
memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs
|
||||
if ( _mem != _pool ) {
|
||||
delete [] _mem;
|
||||
|
@ -314,7 +336,6 @@ public:
|
|||
virtual void* Alloc() = 0;
|
||||
virtual void Free( void* ) = 0;
|
||||
virtual void SetTracked() = 0;
|
||||
virtual void Clear() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -325,16 +346,16 @@ template< int ITEM_SIZE >
|
|||
class MemPoolT : public MemPool
|
||||
{
|
||||
public:
|
||||
MemPoolT() : _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
|
||||
MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {}
|
||||
~MemPoolT() {
|
||||
Clear();
|
||||
MemPoolT< ITEM_SIZE >::Clear();
|
||||
}
|
||||
|
||||
|
||||
void Clear() {
|
||||
// Delete the blocks.
|
||||
while( !_blockPtrs.Empty()) {
|
||||
Block* b = _blockPtrs.Pop();
|
||||
delete b;
|
||||
Block* lastBlock = _blockPtrs.Pop();
|
||||
delete lastBlock;
|
||||
}
|
||||
_root = 0;
|
||||
_currentAllocs = 0;
|
||||
|
@ -375,14 +396,14 @@ public:
|
|||
++_nUntracked;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
virtual void Free( void* mem ) {
|
||||
if ( !mem ) {
|
||||
return;
|
||||
}
|
||||
--_currentAllocs;
|
||||
Item* item = static_cast<Item*>( mem );
|
||||
#ifdef DEBUG
|
||||
#ifdef TINYXML2_DEBUG
|
||||
memset( item, 0xfe, sizeof( *item ) );
|
||||
#endif
|
||||
item->next = _root;
|
||||
|
@ -505,10 +526,8 @@ enum XMLError {
|
|||
XML_ERROR_FILE_NOT_FOUND,
|
||||
XML_ERROR_FILE_COULD_NOT_BE_OPENED,
|
||||
XML_ERROR_FILE_READ_ERROR,
|
||||
XML_ERROR_ELEMENT_MISMATCH,
|
||||
XML_ERROR_PARSING_ELEMENT,
|
||||
XML_ERROR_PARSING_ATTRIBUTE,
|
||||
XML_ERROR_IDENTIFYING_TAG,
|
||||
XML_ERROR_PARSING_TEXT,
|
||||
XML_ERROR_PARSING_CDATA,
|
||||
XML_ERROR_PARSING_COMMENT,
|
||||
|
@ -519,6 +538,7 @@ enum XMLError {
|
|||
XML_ERROR_PARSING,
|
||||
XML_CAN_NOT_CONVERT_TEXT,
|
||||
XML_NO_TEXT_NODE,
|
||||
XML_ELEMENT_DEPTH_EXCEEDED,
|
||||
|
||||
XML_ERROR_COUNT
|
||||
};
|
||||
|
@ -551,7 +571,7 @@ public:
|
|||
static bool IsWhiteSpace( char p ) {
|
||||
return !IsUTF8Continuation(p) && isspace( static_cast<unsigned char>(p) );
|
||||
}
|
||||
|
||||
|
||||
inline static bool IsNameStartChar( unsigned char ch ) {
|
||||
if ( ch >= 128 ) {
|
||||
// This is a heuristic guess in attempt to not implement Unicode-aware isalpha()
|
||||
|
@ -562,7 +582,7 @@ public:
|
|||
}
|
||||
return ch == ':' || ch == '_';
|
||||
}
|
||||
|
||||
|
||||
inline static bool IsNameChar( unsigned char ch ) {
|
||||
return IsNameStartChar( ch )
|
||||
|| isdigit( ch )
|
||||
|
@ -579,7 +599,7 @@ public:
|
|||
TIXMLASSERT( nChar >= 0 );
|
||||
return strncmp( p, q, nChar ) == 0;
|
||||
}
|
||||
|
||||
|
||||
inline static bool IsUTF8Continuation( char p ) {
|
||||
return ( p & 0x80 ) != 0;
|
||||
}
|
||||
|
@ -597,6 +617,7 @@ public:
|
|||
static void ToStr( float v, char* buffer, int bufferSize );
|
||||
static void ToStr( double v, char* buffer, int bufferSize );
|
||||
static void ToStr(int64_t v, char* buffer, int bufferSize);
|
||||
static void ToStr(uint64_t v, char* buffer, int bufferSize);
|
||||
|
||||
// converts strings to primitive types
|
||||
static bool ToInt( const char* str, int* value );
|
||||
|
@ -605,7 +626,7 @@ public:
|
|||
static bool ToFloat( const char* str, float* value );
|
||||
static bool ToDouble( const char* str, double* value );
|
||||
static bool ToInt64(const char* str, int64_t* value);
|
||||
|
||||
static bool ToUnsigned64(const char* str, uint64_t* value);
|
||||
// Changes what is serialized for a boolean value.
|
||||
// Default to "true" and "false". Shouldn't be changed
|
||||
// unless you have a special testing or compatibility need.
|
||||
|
@ -857,6 +878,21 @@ public:
|
|||
*/
|
||||
virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0;
|
||||
|
||||
/**
|
||||
Make a copy of this node and all its children.
|
||||
|
||||
If the 'target' is null, then the nodes will
|
||||
be allocated in the current document. If 'target'
|
||||
is specified, the memory will be allocated is the
|
||||
specified XMLDocument.
|
||||
|
||||
NOTE: This is probably not the correct tool to
|
||||
copy a document, since XMLDocuments can have multiple
|
||||
top level XMLNodes. You probably want to use
|
||||
XMLDocument::DeepCopy()
|
||||
*/
|
||||
XMLNode* DeepClone( XMLDocument* target ) const;
|
||||
|
||||
/**
|
||||
Test if 2 nodes are the same, but don't test children.
|
||||
The 2 nodes do not need to be in the same Document.
|
||||
|
@ -889,8 +925,8 @@ public:
|
|||
*/
|
||||
virtual bool Accept( XMLVisitor* visitor ) const = 0;
|
||||
|
||||
/**
|
||||
Set user data into the XMLNode. TinyXML-2 in
|
||||
/**
|
||||
Set user data into the XMLNode. TinyXML-2 in
|
||||
no way processes or interprets user data.
|
||||
It is initially 0.
|
||||
*/
|
||||
|
@ -904,10 +940,10 @@ public:
|
|||
void* GetUserData() const { return _userData; }
|
||||
|
||||
protected:
|
||||
XMLNode( XMLDocument* );
|
||||
explicit XMLNode( XMLDocument* );
|
||||
virtual ~XMLNode();
|
||||
|
||||
virtual char* ParseDeep( char*, StrPair*, int* );
|
||||
virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
|
||||
|
||||
XMLDocument* _document;
|
||||
XMLNode* _parent;
|
||||
|
@ -972,10 +1008,10 @@ public:
|
|||
virtual bool ShallowEqual( const XMLNode* compare ) const;
|
||||
|
||||
protected:
|
||||
XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
|
||||
explicit XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {}
|
||||
virtual ~XMLText() {}
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr );
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
|
||||
|
||||
private:
|
||||
bool _isCData;
|
||||
|
@ -1003,10 +1039,10 @@ public:
|
|||
virtual bool ShallowEqual( const XMLNode* compare ) const;
|
||||
|
||||
protected:
|
||||
XMLComment( XMLDocument* doc );
|
||||
explicit XMLComment( XMLDocument* doc );
|
||||
virtual ~XMLComment();
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr);
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr);
|
||||
|
||||
private:
|
||||
XMLComment( const XMLComment& ); // not supported
|
||||
|
@ -1042,10 +1078,10 @@ public:
|
|||
virtual bool ShallowEqual( const XMLNode* compare ) const;
|
||||
|
||||
protected:
|
||||
XMLDeclaration( XMLDocument* doc );
|
||||
explicit XMLDeclaration( XMLDocument* doc );
|
||||
virtual ~XMLDeclaration();
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr );
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
|
||||
|
||||
private:
|
||||
XMLDeclaration( const XMLDeclaration& ); // not supported
|
||||
|
@ -1077,10 +1113,10 @@ public:
|
|||
virtual bool ShallowEqual( const XMLNode* compare ) const;
|
||||
|
||||
protected:
|
||||
XMLUnknown( XMLDocument* doc );
|
||||
explicit XMLUnknown( XMLDocument* doc );
|
||||
virtual ~XMLUnknown();
|
||||
|
||||
char* ParseDeep( char*, StrPair* endTag, int* curLineNumPtr );
|
||||
char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr );
|
||||
|
||||
private:
|
||||
XMLUnknown( const XMLUnknown& ); // not supported
|
||||
|
@ -1129,6 +1165,12 @@ public:
|
|||
return i;
|
||||
}
|
||||
|
||||
uint64_t Unsigned64Value() const {
|
||||
uint64_t i = 0;
|
||||
QueryUnsigned64Value(&i);
|
||||
return i;
|
||||
}
|
||||
|
||||
/// Query as an unsigned integer. See IntValue()
|
||||
unsigned UnsignedValue() const {
|
||||
unsigned i=0;
|
||||
|
@ -1163,6 +1205,8 @@ public:
|
|||
XMLError QueryUnsignedValue( unsigned int* value ) const;
|
||||
/// See QueryIntValue
|
||||
XMLError QueryInt64Value(int64_t* value) const;
|
||||
/// See QueryIntValue
|
||||
XMLError QueryUnsigned64Value(uint64_t* value) const;
|
||||
/// See QueryIntValue
|
||||
XMLError QueryBoolValue( bool* value ) const;
|
||||
/// See QueryIntValue
|
||||
|
@ -1178,7 +1222,9 @@ public:
|
|||
void SetAttribute( unsigned value );
|
||||
/// Set the attribute to value.
|
||||
void SetAttribute(int64_t value);
|
||||
/// Set the attribute to value.
|
||||
/// Set the attribute to value.
|
||||
void SetAttribute(uint64_t value);
|
||||
/// Set the attribute to value.
|
||||
void SetAttribute( bool value );
|
||||
/// Set the attribute to value.
|
||||
void SetAttribute( double value );
|
||||
|
@ -1188,7 +1234,7 @@ public:
|
|||
private:
|
||||
enum { BUF_SIZE = 200 };
|
||||
|
||||
XMLAttribute() : _parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
|
||||
XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {}
|
||||
virtual ~XMLAttribute() {}
|
||||
|
||||
XMLAttribute( const XMLAttribute& ); // not supported
|
||||
|
@ -1266,6 +1312,8 @@ public:
|
|||
unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const;
|
||||
/// See IntAttribute()
|
||||
int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const;
|
||||
/// See IntAttribute()
|
||||
uint64_t Unsigned64Attribute(const char* name, uint64_t defaultValue = 0) const;
|
||||
/// See IntAttribute()
|
||||
bool BoolAttribute(const char* name, bool defaultValue = false) const;
|
||||
/// See IntAttribute()
|
||||
|
@ -1312,6 +1360,15 @@ public:
|
|||
return a->QueryInt64Value(value);
|
||||
}
|
||||
|
||||
/// See QueryIntAttribute()
|
||||
XMLError QueryUnsigned64Attribute(const char* name, uint64_t* value) const {
|
||||
const XMLAttribute* a = FindAttribute(name);
|
||||
if(!a) {
|
||||
return XML_NO_ATTRIBUTE;
|
||||
}
|
||||
return a->QueryUnsigned64Value(value);
|
||||
}
|
||||
|
||||
/// See QueryIntAttribute()
|
||||
XMLError QueryBoolAttribute( const char* name, bool* value ) const {
|
||||
const XMLAttribute* a = FindAttribute( name );
|
||||
|
@ -1337,14 +1394,25 @@ public:
|
|||
return a->QueryFloatValue( value );
|
||||
}
|
||||
|
||||
|
||||
/// See QueryIntAttribute()
|
||||
XMLError QueryStringAttribute(const char* name, const char** value) const {
|
||||
const XMLAttribute* a = FindAttribute(name);
|
||||
if (!a) {
|
||||
return XML_NO_ATTRIBUTE;
|
||||
}
|
||||
*value = a->Value();
|
||||
return XML_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Given an attribute name, QueryAttribute() returns
|
||||
XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion
|
||||
can't be performed, or XML_NO_ATTRIBUTE if the attribute
|
||||
doesn't exist. It is overloaded for the primitive types,
|
||||
and is a generally more convenient replacement of
|
||||
QueryIntAttribute() and related functions.
|
||||
|
||||
|
||||
If successful, the result of the conversion
|
||||
will be written to 'value'. If not successful, nothing will
|
||||
be written to 'value'. This allows you to provide default
|
||||
|
@ -1355,27 +1423,31 @@ public:
|
|||
QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10
|
||||
@endverbatim
|
||||
*/
|
||||
int QueryAttribute( const char* name, int* value ) const {
|
||||
XMLError QueryAttribute( const char* name, int* value ) const {
|
||||
return QueryIntAttribute( name, value );
|
||||
}
|
||||
|
||||
int QueryAttribute( const char* name, unsigned int* value ) const {
|
||||
XMLError QueryAttribute( const char* name, unsigned int* value ) const {
|
||||
return QueryUnsignedAttribute( name, value );
|
||||
}
|
||||
|
||||
int QueryAttribute(const char* name, int64_t* value) const {
|
||||
XMLError QueryAttribute(const char* name, int64_t* value) const {
|
||||
return QueryInt64Attribute(name, value);
|
||||
}
|
||||
|
||||
int QueryAttribute( const char* name, bool* value ) const {
|
||||
XMLError QueryAttribute(const char* name, uint64_t* value) const {
|
||||
return QueryUnsigned64Attribute(name, value);
|
||||
}
|
||||
|
||||
XMLError QueryAttribute( const char* name, bool* value ) const {
|
||||
return QueryBoolAttribute( name, value );
|
||||
}
|
||||
|
||||
int QueryAttribute( const char* name, double* value ) const {
|
||||
XMLError QueryAttribute( const char* name, double* value ) const {
|
||||
return QueryDoubleAttribute( name, value );
|
||||
}
|
||||
|
||||
int QueryAttribute( const char* name, float* value ) const {
|
||||
XMLError QueryAttribute( const char* name, float* value ) const {
|
||||
return QueryFloatAttribute( name, value );
|
||||
}
|
||||